[libcxx-commits] [libcxx] [libc++] Forward more algorithms to the classic algorithms (PR #114674)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Tue Nov 5 05:17:33 PST 2024


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/114674

>From a7afbfe8cd985b46f2adc28b02c26372528f2248 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 2 Nov 2024 15:48:10 +0100
Subject: [PATCH] [libc++] Forward more algorithms to the classic algorithms

---
 libcxx/include/__algorithm/adjacent_find.h    | 12 ++++++---
 libcxx/include/__algorithm/all_of.h           | 18 ++++++++++---
 libcxx/include/__algorithm/any_of.h           | 18 ++++++++++---
 libcxx/include/__algorithm/copy_if.h          | 26 +++++++++++++++----
 libcxx/include/__algorithm/count_if.h         | 21 +++++++++++----
 .../include/__algorithm/iterator_operations.h |  3 +++
 .../__algorithm/ranges_adjacent_find.h        | 21 +++------------
 libcxx/include/__algorithm/ranges_all_of.h    | 14 +++-------
 libcxx/include/__algorithm/ranges_any_of.h    | 15 +++--------
 libcxx/include/__algorithm/ranges_copy_if.h   | 19 ++++----------
 libcxx/include/__algorithm/ranges_copy_n.h    |  1 +
 libcxx/include/__algorithm/ranges_count_if.h  | 18 +++----------
 libcxx/include/__algorithm/ranges_fill_n.h    |  8 +++---
 libcxx/include/__algorithm/unique.h           |  4 ++-
 14 files changed, 101 insertions(+), 97 deletions(-)

diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h
index f0708ebe251493..76728900bd4d97 100644
--- a/libcxx/include/__algorithm/adjacent_find.h
+++ b/libcxx/include/__algorithm/adjacent_find.h
@@ -13,7 +13,9 @@
 #include <__algorithm/comp.h>
 #include <__algorithm/iterator_operations.h>
 #include <__config>
+#include <__functional/identity.h>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/invoke.h>
 #include <__utility/move.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -25,14 +27,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 +45,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..4b6eb945172864 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,21 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <class _Iter, class _Sent, class _Proj, class _Pred>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 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..ffea621fc06183 100644
--- a/libcxx/include/__algorithm/copy_if.h
+++ b/libcxx/include/__algorithm/copy_if.h
@@ -10,25 +10,41 @@
 #define _LIBCPP___ALGORITHM_COPY_IF_H
 
 #include <__config>
+#include <__functional/identity.h>
+#include <__type_traits/invoke.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _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 _LIBCPP_CONSTEXPR_SINCE_CXX14 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::make_pair(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
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___ALGORITHM_COPY_IF_H
diff --git a/libcxx/include/__algorithm/count_if.h b/libcxx/include/__algorithm/count_if.h
index e70238896095ce..26f945e6bd98c7 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 _LIBCPP_CONSTEXPR_SINCE_CXX14 __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..1276f13680a9f5 100644
--- a/libcxx/include/__algorithm/ranges_fill_n.h
+++ b/libcxx/include/__algorithm/ranges_fill_n.h
@@ -9,9 +9,11 @@
 #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>
+#include <__utility/move.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -29,11 +31,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..307c424a7c2fb5 100644
--- a/libcxx/include/__algorithm/unique.h
+++ b/libcxx/include/__algorithm/unique.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>
 #include <__utility/pair.h>
@@ -31,7 +32,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _AlgPolicy, class _Iter, class _Sent, class _BinaryPredicate>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter>
 __unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) {
-  __first = std::__adjacent_find(__first, __last, __pred);
+  __identity __proj;
+  __first = std::__adjacent_find(__first, __last, __pred, __proj);
   if (__first != __last) {
     // ...  a  a  ?  ...
     //      f     i



More information about the libcxx-commits mailing list