-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] Forward more algorithms to the classic algorithms #114674
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesThis partially addresses #105687. Patch is 20.56 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/114674.diff 14 Files Affected:
diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h
index f0708ebe251493..e65abe36094692 100644
--- a/libcxx/include/__algorithm/adjacent_find.h
+++ b/libcxx/include/__algorithm/adjacent_find.h
@@ -13,6 +13,7 @@
#include <__algorithm/comp.h>
#include <__algorithm/iterator_operations.h>
#include <__config>
+#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
@@ -25,14 +26,15 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Iter, class _Sent, class _BinaryPredicate>
+template <class _Iter, class _Sent, class _Pred, class _Proj>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter
-__adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) {
+__adjacent_find(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
if (__first == __last)
return __first;
+
_Iter __i = __first;
while (++__i != __last) {
- if (__pred(*__first, *__i))
+ if (std::__invoke(__pred, std::__invoke(__proj, *__first), std::__invoke(__proj, *__i)))
return __first;
__first = __i;
}
@@ -42,7 +44,8 @@ __adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) {
template <class _ForwardIterator, class _BinaryPredicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
- return std::__adjacent_find(std::move(__first), std::move(__last), __pred);
+ __identity __proj;
+ return std::__adjacent_find(std::move(__first), std::move(__last), __pred, __proj);
}
template <class _ForwardIterator>
diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h
index 1fcb74ffc0fdc0..6acc117fc47bc5 100644
--- a/libcxx/include/__algorithm/all_of.h
+++ b/libcxx/include/__algorithm/all_of.h
@@ -11,6 +11,8 @@
#define _LIBCPP___ALGORITHM_ALL_OF_H
#include <__config>
+#include <__functional/identity.h>
+#include <__type_traits/invoke.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -18,13 +20,21 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Iter, class _Sent, class _Proj, class _Pred>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
+__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
+ return false;
+ }
+ return true;
+}
+
template <class _InputIterator, class _Predicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
- for (; __first != __last; ++__first)
- if (!__pred(*__first))
- return false;
- return true;
+ __identity __proj;
+ return std::__all_of(__first, __last, __pred, __proj);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/any_of.h b/libcxx/include/__algorithm/any_of.h
index acb546bb22dcca..1f193ea9b1535a 100644
--- a/libcxx/include/__algorithm/any_of.h
+++ b/libcxx/include/__algorithm/any_of.h
@@ -11,6 +11,8 @@
#define _LIBCPP___ALGORITHM_ANY_OF_H
#include <__config>
+#include <__functional/identity.h>
+#include <__type_traits/invoke.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -18,13 +20,20 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Iter, class _Sent, class _Proj, class _Pred>
+_LIBCPP_HIDE_FROM_ABI constexpr static bool __any_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ for (; __first != __last; ++__first) {
+ if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
+ return true;
+ }
+ return false;
+}
+
template <class _InputIterator, class _Predicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
- for (; __first != __last; ++__first)
- if (__pred(*__first))
- return true;
- return false;
+ __identity __proj;
+ return std::__any_of(__first, __last, __pred, __proj);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/copy_if.h b/libcxx/include/__algorithm/copy_if.h
index 228e4d22323e3c..7b895b54051826 100644
--- a/libcxx/include/__algorithm/copy_if.h
+++ b/libcxx/include/__algorithm/copy_if.h
@@ -10,6 +10,9 @@
#define _LIBCPP___ALGORITHM_COPY_IF_H
#include <__config>
+#include <__functional/identity.h>
+#include <__type_traits/invoke.h>
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -17,16 +20,23 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _InputIterator, class _OutputIterator, class _Predicate>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
-copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) {
+template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
+_LIBCPP_HIDE_FROM_ABI static constexpr pair<_InIter, _OutIter>
+__copy_if(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
for (; __first != __last; ++__first) {
- if (__pred(*__first)) {
+ if (std::__invoke(__pred, std::__invoke(__proj, *__first))) {
*__result = *__first;
++__result;
}
}
- return __result;
+ return {std::move(__first), std::move(__result)};
+}
+
+template <class _InputIterator, class _OutputIterator, class _Predicate>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) {
+ __identity __proj;
+ return std::__copy_if(__first, __last, __result, __pred, __proj).second;
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/count_if.h b/libcxx/include/__algorithm/count_if.h
index e70238896095ce..7fac9ff12deadb 100644
--- a/libcxx/include/__algorithm/count_if.h
+++ b/libcxx/include/__algorithm/count_if.h
@@ -10,8 +10,11 @@
#ifndef _LIBCPP___ALGORITHM_COUNT_IF_H
#define _LIBCPP___ALGORITHM_COUNT_IF_H
+#include <__algorithm/iterator_operations.h>
#include <__config>
+#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
+#include <__type_traits/invoke.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -19,15 +22,23 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _AlgPolicy, class _Iter, class _Sent, class _Proj, class _Pred>
+_LIBCPP_HIDE_FROM_ABI constexpr __policy_iter_diff_t<_AlgPolicy, _Iter>
+__count_if(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+ __policy_iter_diff_t<_AlgPolicy, _Iter> __counter(0);
+ for (; __first != __last; ++__first) {
+ if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
+ ++__counter;
+ }
+ return __counter;
+}
+
template <class _InputIterator, class _Predicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
typename iterator_traits<_InputIterator>::difference_type
count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
- typename iterator_traits<_InputIterator>::difference_type __r(0);
- for (; __first != __last; ++__first)
- if (__pred(*__first))
- ++__r;
- return __r;
+ __identity __proj;
+ return std::__count_if<_ClassicAlgPolicy>(__first, __last, __pred, __proj);
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
index 8ced989233bc48..6cdb0aec9b2db8 100644
--- a/libcxx/include/__algorithm/iterator_operations.h
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -216,6 +216,9 @@ struct _IterOps<_ClassicAlgPolicy> {
}
};
+template <class _AlgPolicy, class _Iter>
+using __policy_iter_diff_t = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>;
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/__algorithm/ranges_adjacent_find.h b/libcxx/include/__algorithm/ranges_adjacent_find.h
index 0f2cb66699374e..731142b29e6c0a 100644
--- a/libcxx/include/__algorithm/ranges_adjacent_find.h
+++ b/libcxx/include/__algorithm/ranges_adjacent_find.h
@@ -9,9 +9,9 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H
#define _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H
+#include <__algorithm/adjacent_find.h>
#include <__config>
#include <__functional/identity.h>
-#include <__functional/invoke.h>
#include <__functional/ranges_operations.h>
#include <__iterator/concepts.h>
#include <__iterator/projected.h>
@@ -33,28 +33,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
struct __adjacent_find {
- template <class _Iter, class _Sent, class _Proj, class _Pred>
- _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
- __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
- if (__first == __last)
- return __first;
-
- auto __i = __first;
- while (++__i != __last) {
- if (std::invoke(__pred, std::invoke(__proj, *__first), std::invoke(__proj, *__i)))
- return __first;
- __first = __i;
- }
- return __i;
- }
-
template <forward_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_binary_predicate<projected<_Iter, _Proj>, projected<_Iter, _Proj>> _Pred = ranges::equal_to>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter
operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
- return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj);
+ return std::__adjacent_find(std::move(__first), std::move(__last), __pred, __proj);
}
template <forward_range _Range,
@@ -63,7 +48,7 @@ struct __adjacent_find {
_Pred = ranges::equal_to>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
- return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ return std::__adjacent_find(ranges::begin(__range), ranges::end(__range), __pred, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_all_of.h b/libcxx/include/__algorithm/ranges_all_of.h
index fea089493811a9..c3d6dc08d3c5f1 100644
--- a/libcxx/include/__algorithm/ranges_all_of.h
+++ b/libcxx/include/__algorithm/ranges_all_of.h
@@ -9,6 +9,7 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
#define _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
+#include <__algorithm/all_of.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/invoke.h>
@@ -31,22 +32,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
struct __all_of {
- template <class _Iter, class _Sent, class _Proj, class _Pred>
- _LIBCPP_HIDE_FROM_ABI constexpr static bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
- for (; __first != __last; ++__first) {
- if (!std::invoke(__pred, std::invoke(__proj, *__first)))
- return false;
- }
- return true;
- }
-
template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
- return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj);
+ return std::__all_of(std::move(__first), std::move(__last), __pred, __proj);
}
template <input_range _Range,
@@ -54,7 +46,7 @@ struct __all_of {
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
- return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ return std::__all_of(ranges::begin(__range), ranges::end(__range), __pred, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_any_of.h b/libcxx/include/__algorithm/ranges_any_of.h
index 34d23b4b7455a9..7f0fd290f87d55 100644
--- a/libcxx/include/__algorithm/ranges_any_of.h
+++ b/libcxx/include/__algorithm/ranges_any_of.h
@@ -9,9 +9,9 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
#define _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
+#include <__algorithm/any_of.h>
#include <__config>
#include <__functional/identity.h>
-#include <__functional/invoke.h>
#include <__iterator/concepts.h>
#include <__iterator/projected.h>
#include <__ranges/access.h>
@@ -31,22 +31,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
struct __any_of {
- template <class _Iter, class _Sent, class _Proj, class _Pred>
- _LIBCPP_HIDE_FROM_ABI constexpr static bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
- for (; __first != __last; ++__first) {
- if (std::invoke(__pred, std::invoke(__proj, *__first)))
- return true;
- }
- return false;
- }
-
template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
class _Proj = identity,
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
- return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj);
+ return std::__any_of(std::move(__first), std::move(__last), __pred, __proj);
}
template <input_range _Range,
@@ -54,7 +45,7 @@ struct __any_of {
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
- return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
+ return std::__any_of(ranges::begin(__range), ranges::end(__range), __pred, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_copy_if.h b/libcxx/include/__algorithm/ranges_copy_if.h
index 1a08985fe35caa..acf74b669d481c 100644
--- a/libcxx/include/__algorithm/ranges_copy_if.h
+++ b/libcxx/include/__algorithm/ranges_copy_if.h
@@ -9,6 +9,7 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
#define _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
+#include <__algorithm/copy_if.h>
#include <__algorithm/in_out_result.h>
#include <__config>
#include <__functional/identity.h>
@@ -37,18 +38,6 @@ template <class _Ip, class _Op>
using copy_if_result = in_out_result<_Ip, _Op>;
struct __copy_if {
- template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
- _LIBCPP_HIDE_FROM_ABI static constexpr copy_if_result<_InIter, _OutIter>
- __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
- for (; __first != __last; ++__first) {
- if (std::invoke(__pred, std::invoke(__proj, *__first))) {
- *__result = *__first;
- ++__result;
- }
- }
- return {std::move(__first), std::move(__result)};
- }
-
template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
weakly_incrementable _OutIter,
@@ -57,7 +46,8 @@ struct __copy_if {
requires indirectly_copyable<_Iter, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<_Iter, _OutIter>
operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
- return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
+ auto __res = std::__copy_if(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
+ return {std::move(__res.first), std::move(__res.second)};
}
template <input_range _Range,
@@ -67,7 +57,8 @@ struct __copy_if {
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
- return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
+ auto __res = std::__copy_if(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
+ return {std::move(__res.first), std::move(__res.second)};
}
};
diff --git a/libcxx/include/__algorithm/ranges_copy_n.h b/libcxx/include/__algorithm/ranges_copy_n.h
index 4407e07f5ca62e..79ce1580490d43 100644
--- a/libcxx/include/__algorithm/ranges_copy_n.h
+++ b/libcxx/include/__algorithm/ranges_copy_n.h
@@ -37,6 +37,7 @@ namespace ranges {
template <class _Ip, class _Op>
using copy_n_result = in_out_result<_Ip, _Op>;
+// TODO: Merge this with copy_n
struct __copy_n {
template <class _InIter, class _DiffType, class _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
diff --git a/libcxx/include/__algorithm/ranges_count_if.h b/libcxx/include/__algorithm/ranges_count_if.h
index 2663180242c1cd..6adeb78582bf3c 100644
--- a/libcxx/include/__algorithm/ranges_count_if.h
+++ b/libcxx/include/__algorithm/ranges_count_if.h
@@ -9,9 +9,10 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
#define _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
+#include <__algorithm/count_if.h>
+#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__functional/identity.h>
-#include <__functional/invoke.h>
#include <__functional/ranges_operations.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -33,17 +34,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
-template <class _Iter, class _Sent, class _Proj, class _Pred>
-_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
-__count_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
- iter_difference_t<_Iter> __counter(0);
- for (; __first != __last; ++__first) {
- if (std::invoke(__pred, std::invoke(__proj, *__first)))
- ++__counter;
- }
- return __counter;
-}
-
struct __count_if {
template <input_iterator _Iter,
sentinel_for<_Iter> _Sent,
@@ -51,7 +41,7 @@ struct __count_if {
indirect_unary_predicate<projected<_Iter, _Proj>> _Predicate>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
- return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
+ return std::__count_if<_RangeAlgPolicy>(std::move(__first), std::move(__last), __pred, __proj);
}
template <input_range _Range,
@@ -59,7 +49,7 @@ struct __count_if {
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Predicate>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
- return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
+ return std::__count_if<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __pred, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_fill_n.h b/libcxx/include/__algorithm/ranges_fill_n.h
index 7a33268e1dd323..d95e4bd3f19808 100644
--- a/libcxx/include/__algorithm/ranges_fill_n.h
+++ b/libcxx/include/__algorithm/ranges_fill_n.h
@@ -9,6 +9,7 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_FILL_N_H
#define _LIBCPP___ALGORITHM_RANGES_FILL_N_H
+#include <__algorithm/fill_n.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
@@ -29,11 +30,7 @@ struct __fill_n {
template <class _Type, output_iterator<const _Type&> _Iter>
_LIBCPP_HIDE_FROM_ABI constexpr _Iter
operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const {
- for (; __n != 0; --__n) {
- *__first = __value;
- ++__first;
- }
- return __first;
+ return std::__fill_n(std::move(__first), __n, __value);
}
};
diff --git a/libcxx/include/__algorithm/unique.h b/libcxx/include/__algorithm/unique.h
index 1f0c4ffa82dd16..c1f2ef5f802387 100644
--- a/libcxx/include/__al...
[truncated]
|
096a32c
to
2bd6ec1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really nice, thanks for going over those! Some comments but generally looks fine.
template <class _AlgPolicy, class _Iter> | ||
using __policy_iter_diff_t = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would find it clearer to instead do this at the beginning of algorithms that need it:
using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>;
And then to use _Difference
throughout. __policy_iter_diff_t
introduces yet another short-name that I'd rather not have to remember. Not a blocking comment since this is somewhat subjective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that you also have to mention typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>
in the declaration, which is really not easy to read IMO. FWIW I think we may want to rethink the iterator_operations.h
, since it's become a quite ugly catch-all of different operations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo CI passing and the comment about __policy_diff_t
(which is non-blocking, but please consider).
6ff3602
to
6c4ecf2
Compare
6c4ecf2
to
a7afbfe
Compare
This partially addresses #105687.