Skip to content

[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

Merged
merged 1 commit into from
Nov 6, 2024

Conversation

philnik777
Copy link
Contributor

This partially addresses #105687.

@philnik777 philnik777 requested a review from a team as a code owner November 2, 2024 14:49
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Nov 2, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 2, 2024

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

This 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:

  • (modified) libcxx/include/__algorithm/adjacent_find.h (+7-4)
  • (modified) libcxx/include/__algorithm/all_of.h (+14-4)
  • (modified) libcxx/include/__algorithm/any_of.h (+13-4)
  • (modified) libcxx/include/__algorithm/copy_if.h (+15-5)
  • (modified) libcxx/include/__algorithm/count_if.h (+16-5)
  • (modified) libcxx/include/__algorithm/iterator_operations.h (+3)
  • (modified) libcxx/include/__algorithm/ranges_adjacent_find.h (+3-18)
  • (modified) libcxx/include/__algorithm/ranges_all_of.h (+3-11)
  • (modified) libcxx/include/__algorithm/ranges_any_of.h (+3-12)
  • (modified) libcxx/include/__algorithm/ranges_copy_if.h (+5-14)
  • (modified) libcxx/include/__algorithm/ranges_copy_n.h (+1)
  • (modified) libcxx/include/__algorithm/ranges_count_if.h (+4-14)
  • (modified) libcxx/include/__algorithm/ranges_fill_n.h (+2-5)
  • (modified) libcxx/include/__algorithm/unique.h (+2-1)
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]

@philnik777 philnik777 force-pushed the ranges_forward_to_classic branch from 096a32c to 2bd6ec1 Compare November 4, 2024 13:45
Copy link
Member

@ldionne ldionne left a 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.

Comment on lines +219 to +220
template <class _AlgPolicy, class _Iter>
using __policy_iter_diff_t = typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>;
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

@ldionne ldionne left a 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).

@philnik777 philnik777 force-pushed the ranges_forward_to_classic branch 3 times, most recently from 6ff3602 to 6c4ecf2 Compare November 4, 2024 21:16
@philnik777 philnik777 force-pushed the ranges_forward_to_classic branch from 6c4ecf2 to a7afbfe Compare November 5, 2024 13:17
@philnik777 philnik777 merged commit eab7be5 into llvm:main Nov 6, 2024
62 checks passed
@philnik777 philnik777 deleted the ranges_forward_to_classic branch March 29, 2025 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants