[libcxx-commits] [libcxx] [libc++] avoid using `ranges::advance` and `ranges::next` in all algorithms (PR #179095)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Feb 1 02:15:41 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Hui (huixie90)

<details>
<summary>Changes</summary>



---

Patch is 23.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/179095.diff


18 Files Affected:

- (modified) libcxx/include/__algorithm/copy_backward.h (+1-1) 
- (modified) libcxx/include/__algorithm/equal_range.h (+2-2) 
- (modified) libcxx/include/__algorithm/find_end.h (+5-5) 
- (modified) libcxx/include/__algorithm/is_permutation.h (+2-2) 
- (modified) libcxx/include/__algorithm/iterator_operations.h (+26-4) 
- (modified) libcxx/include/__algorithm/move_backward.h (+1-1) 
- (modified) libcxx/include/__algorithm/next_permutation.h (+1-1) 
- (modified) libcxx/include/__algorithm/partial_sort.h (+2-2) 
- (modified) libcxx/include/__algorithm/partial_sort_copy.h (+1-1) 
- (modified) libcxx/include/__algorithm/partition.h (+1-1) 
- (modified) libcxx/include/__algorithm/prev_permutation.h (+1-1) 
- (modified) libcxx/include/__algorithm/rotate.h (+7-7) 
- (modified) libcxx/include/__algorithm/set_intersection.h (+4-4) 
- (modified) libcxx/include/__algorithm/shift_left.h (+1-1) 
- (modified) libcxx/include/__algorithm/shuffle.h (+1-1) 
- (modified) libcxx/include/__algorithm/upper_bound.h (+1-1) 
- (modified) libcxx/include/__iterator/advance.h (+23-4) 
- (added) libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp (+35) 


``````````diff
diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h
index 8758d2c9e7b5d..bc2445074fb8b 100644
--- a/libcxx/include/__algorithm/copy_backward.h
+++ b/libcxx/include/__algorithm/copy_backward.h
@@ -161,7 +161,7 @@ struct __copy_backward_impl {
   template <class _InIter, class _Sent, class _OutIter>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
   operator()(_InIter __first, _Sent __last, _OutIter __result) const {
-    auto __last_iter          = _IterOps<_AlgPolicy>::next(__first, __last);
+    auto __last_iter          = _IterOps<_AlgPolicy>::__next_sentinel(__first, __last);
     auto __original_last_iter = __last_iter;
 
     while (__first != __last_iter) {
diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h
index ff6f4f2225c7a..eba132ca9c81e 100644
--- a/libcxx/include/__algorithm/equal_range.h
+++ b/libcxx/include/__algorithm/equal_range.h
@@ -36,10 +36,10 @@ template <class _AlgPolicy, class _Compare, class _Iter, class _Sent, class _Tp,
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter>
 __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) {
   auto __len  = _IterOps<_AlgPolicy>::distance(__first, __last);
-  _Iter __end = _IterOps<_AlgPolicy>::next(__first, __last);
+  _Iter __end = _IterOps<_AlgPolicy>::__next_sentinel(__first, __last);
   while (__len != 0) {
     auto __half_len = std::__half_positive(__len);
-    _Iter __mid     = _IterOps<_AlgPolicy>::next(__first, __half_len);
+    _Iter __mid     = _IterOps<_AlgPolicy>::__next_n(__first, __half_len);
     if (std::__invoke(__comp, std::__invoke(__proj, *__mid), __value)) {
       __first = ++__mid;
       __len -= __half_len + 1;
diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h
index 84b43e31a3a59..af67b7c6969fc 100644
--- a/libcxx/include/__algorithm/find_end.h
+++ b/libcxx/include/__algorithm/find_end.h
@@ -43,7 +43,7 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
     forward_iterator_tag,
     forward_iterator_tag) {
   // modeled after search algorithm
-  _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer
+  _Iter1 __match_first = _IterOps<_AlgPolicy>::__next_sentinel(__first1, __last1); // __last1 is the "default" answer
   _Iter1 __match_last  = __match_first;
   if (__first2 == __last2)
     return pair<_Iter1, _Iter1>(__match_last, __match_last);
@@ -94,8 +94,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter1> __find_
     _Proj2& __proj2,
     bidirectional_iterator_tag,
     bidirectional_iterator_tag) {
-  auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
-  auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
+  auto __last1 = _IterOps<_AlgPolicy>::__next_sentinel(__first1, __sent1);
+  auto __last2 = _IterOps<_AlgPolicy>::__next_sentinel(__first2, __sent2);
   // modeled after search algorithm (in reverse)
   if (__first2 == __last2)
     return std::make_pair(__last1, __last1); // Everything matches an empty sequence
@@ -147,8 +147,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_
     random_access_iterator_tag,
     random_access_iterator_tag) {
   typedef typename iterator_traits<_Iter1>::difference_type _D1;
-  auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
-  auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
+  auto __last1 = _IterOps<_AlgPolicy>::__next_sentinel(__first1, __sent1);
+  auto __last2 = _IterOps<_AlgPolicy>::__next_sentinel(__first2, __sent2);
   // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern
   auto __len2 = __last2 - __first2;
   if (__len2 == 0)
diff --git a/libcxx/include/__algorithm/is_permutation.h b/libcxx/include/__algorithm/is_permutation.h
index 86f469c2799c5..4668a9d31b1a3 100644
--- a/libcxx/include/__algorithm/is_permutation.h
+++ b/libcxx/include/__algorithm/is_permutation.h
@@ -100,7 +100,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl(
 
       // Count number of *__i in [__i, l1) (we can start with 1)
       _D1 __c1 = 1;
-      for (auto __j = _IterOps<_AlgPolicy>::next(__i); __j != __last1; ++__j) {
+      for (auto __j = _IterOps<_AlgPolicy>::__next_n(__i); __j != __last1; ++__j) {
         if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj1, *__j)))
           ++__c1;
       }
@@ -130,7 +130,7 @@ template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _Fo
   _D1 __l1  = _IterOps<_AlgPolicy>::distance(__first1, __last1);
   if (__l1 == _D1(1))
     return false;
-  auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1);
+  auto __last2 = _IterOps<_AlgPolicy>::__next_n(__first2, __l1);
 
   return std::__is_permutation_impl<_AlgPolicy>(
       std::move(__first1),
diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
index 1aa2f8d1604f1..6c8bf2b1bd88d 100644
--- a/libcxx/include/__algorithm/iterator_operations.h
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -14,6 +14,7 @@
 #include <__assert>
 #include <__config>
 #include <__iterator/advance.h>
+#include <__iterator/concepts.h>
 #include <__iterator/distance.h>
 #include <__iterator/incrementable_traits.h>
 #include <__iterator/iter_move.h>
@@ -56,11 +57,32 @@ struct _IterOps<_RangeAlgPolicy> {
   template <class _Iter>
   using __difference_type _LIBCPP_NODEBUG = iter_difference_t<_Iter>;
 
-  static constexpr auto advance      = ranges::advance;
+  template <input_or_output_iterator _Iter>
+  _LIBCPP_HIDE_FROM_ABI static constexpr void advance(_Iter& __iter, iter_difference_t<_Iter> __n) {
+    ranges::__advance::__advance_n(__iter, __n);
+  }
+
+  template <input_or_output_iterator _Iter>
+  _LIBCPP_HIDE_FROM_ABI static constexpr _Iter __next_n(_Iter __iter) {
+    ++__iter;
+    return __iter;
+  }
+
+  template <input_or_output_iterator _Iter>
+  _LIBCPP_HIDE_FROM_ABI static constexpr _Iter __next_n(_Iter __iter, iter_difference_t<_Iter> __n) {
+    ranges::__advance::__advance_n(__iter, __n);
+    return __iter;
+  }
+
+  template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+  _LIBCPP_HIDE_FROM_ABI static constexpr _Ip __next_sentinel(_Ip __x, _Sp __bound_sentinel) {
+    ranges::__advance::__advance_sentinel(__x, __bound_sentinel);
+    return __x;
+  }
+
   static constexpr auto distance     = ranges::distance;
   static constexpr auto __iter_move  = ranges::iter_move;
   static constexpr auto iter_swap    = ranges::iter_swap;
-  static constexpr auto next         = ranges::next;
   static constexpr auto prev         = ranges::prev;
   static constexpr auto __advance_to = ranges::advance;
 };
@@ -140,13 +162,13 @@ struct _IterOps<_ClassicAlgPolicy> {
 
   // next
   template <class _Iterator>
-  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iterator next(_Iterator, _Iterator __last) {
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iterator __next_sentinel(_Iterator, _Iterator __last) {
     return __last;
   }
 
   template <class _Iter>
   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter>
-  next(_Iter&& __it, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
+  __next_n(_Iter&& __it, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
     return std::next(std::forward<_Iter>(__it), __n);
   }
 
diff --git a/libcxx/include/__algorithm/move_backward.h b/libcxx/include/__algorithm/move_backward.h
index 43b72057a5eca..e9a4db4a293a2 100644
--- a/libcxx/include/__algorithm/move_backward.h
+++ b/libcxx/include/__algorithm/move_backward.h
@@ -42,7 +42,7 @@ struct __move_backward_impl {
   template <class _InIter, class _Sent, class _OutIter>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
   operator()(_InIter __first, _Sent __last, _OutIter __result) const {
-    auto __last_iter          = _IterOps<_AlgPolicy>::next(__first, __last);
+    auto __last_iter          = _IterOps<_AlgPolicy>::__next_sentinel(__first, __last);
     auto __original_last_iter = __last_iter;
 
     while (__first != __last_iter) {
diff --git a/libcxx/include/__algorithm/next_permutation.h b/libcxx/include/__algorithm/next_permutation.h
index 011ee028cc2f5..cc18f2a295010 100644
--- a/libcxx/include/__algorithm/next_permutation.h
+++ b/libcxx/include/__algorithm/next_permutation.h
@@ -32,7 +32,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator,
 __next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) {
   using _Result = pair<_BidirectionalIterator, bool>;
 
-  _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
+  _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::__next_sentinel(__first, __last);
   _BidirectionalIterator __i         = __last_iter;
   if (__first == __last || __first == --__i)
     return _Result(std::move(__last_iter), false);
diff --git a/libcxx/include/__algorithm/partial_sort.h b/libcxx/include/__algorithm/partial_sort.h
index 4b39ae0cf2dfc..b00988a2887ea 100644
--- a/libcxx/include/__algorithm/partial_sort.h
+++ b/libcxx/include/__algorithm/partial_sort.h
@@ -35,7 +35,7 @@ template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator __partial_sort_impl(
     _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) {
   if (__first == __middle) {
-    return _IterOps<_AlgPolicy>::next(__middle, __last);
+    return _IterOps<_AlgPolicy>::__next_sentinel(__middle, __last);
   }
 
   std::__make_heap<_AlgPolicy>(__first, __middle, __comp);
@@ -57,7 +57,7 @@ template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
 __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare& __comp) {
   if (__first == __middle)
-    return _IterOps<_AlgPolicy>::next(__middle, __last);
+    return _IterOps<_AlgPolicy>::__next_sentinel(__middle, __last);
 
   std::__debug_randomize_range<_AlgPolicy>(__first, __last);
 
diff --git a/libcxx/include/__algorithm/partial_sort_copy.h b/libcxx/include/__algorithm/partial_sort_copy.h
index 2230dfc9cc4ad..1e4e0728df494 100644
--- a/libcxx/include/__algorithm/partial_sort_copy.h
+++ b/libcxx/include/__algorithm/partial_sort_copy.h
@@ -66,7 +66,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _Random
   }
 
   return pair<_InputIterator, _RandomAccessIterator>(
-      _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r));
+      _IterOps<_AlgPolicy>::__next_sentinel(std::move(__first), std::move(__last)), std::move(__r));
 }
 
 template <class _InputIterator, class _RandomAccessIterator, class _Compare>
diff --git a/libcxx/include/__algorithm/partition.h b/libcxx/include/__algorithm/partition.h
index 669aac3b27555..32af0c3bc6a7d 100644
--- a/libcxx/include/__algorithm/partition.h
+++ b/libcxx/include/__algorithm/partition.h
@@ -49,7 +49,7 @@ __partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred,
 template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator>
 __partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) {
-  _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel);
+  _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::__next_sentinel(__first, __sentinel);
   _BidirectionalIterator __last          = __original_last;
 
   while (true) {
diff --git a/libcxx/include/__algorithm/prev_permutation.h b/libcxx/include/__algorithm/prev_permutation.h
index 8d15b6806401d..2d2602ff9cd86 100644
--- a/libcxx/include/__algorithm/prev_permutation.h
+++ b/libcxx/include/__algorithm/prev_permutation.h
@@ -32,7 +32,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator,
 __prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) {
   using _Result = pair<_BidirectionalIterator, bool>;
 
-  _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
+  _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::__next_sentinel(__first, __last);
   _BidirectionalIterator __i         = __last_iter;
   if (__first == __last || __first == --__i)
     return _Result(std::move(__last_iter), false);
diff --git a/libcxx/include/__algorithm/rotate.h b/libcxx/include/__algorithm/rotate.h
index b6d9eb3b2dd00..6f59034dcd02e 100644
--- a/libcxx/include/__algorithm/rotate.h
+++ b/libcxx/include/__algorithm/rotate.h
@@ -39,7 +39,7 @@ __rotate_left(_ForwardIterator __first, _ForwardIterator __last) {
   using _Ops = _IterOps<_AlgPolicy>;
 
   value_type __tmp       = _Ops::__iter_move(__first);
-  _ForwardIterator __lm1 = std::__move<_AlgPolicy>(_Ops::next(__first), __last, __first).second;
+  _ForwardIterator __lm1 = std::__move<_AlgPolicy>(_Ops::__next_n(__first), __last, __first).second;
   *__lm1                 = std::move(__tmp);
   return __lm1;
 }
@@ -119,7 +119,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
 __rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, std::forward_iterator_tag) {
   typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
   if (is_trivially_move_assignable<value_type>::value) {
-    if (_IterOps<_AlgPolicy>::next(__first) == __middle)
+    if (_IterOps<_AlgPolicy>::__next_n(__first) == __middle)
       return std::__rotate_left<_AlgPolicy>(__first, __last);
   }
   return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
@@ -133,9 +133,9 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterato
     bidirectional_iterator_tag) {
   typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
   if (is_trivially_move_assignable<value_type>::value) {
-    if (_IterOps<_AlgPolicy>::next(__first) == __middle)
+    if (_IterOps<_AlgPolicy>::__next_n(__first) == __middle)
       return std::__rotate_left<_AlgPolicy>(__first, __last);
-    if (_IterOps<_AlgPolicy>::next(__middle) == __last)
+    if (_IterOps<_AlgPolicy>::__next_n(__middle) == __last)
       return std::__rotate_right<_AlgPolicy>(__first, __last);
   }
   return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
@@ -149,9 +149,9 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator
     random_access_iterator_tag) {
   typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
   if (is_trivially_move_assignable<value_type>::value) {
-    if (_IterOps<_AlgPolicy>::next(__first) == __middle)
+    if (_IterOps<_AlgPolicy>::__next_n(__first) == __middle)
       return std::__rotate_left<_AlgPolicy>(__first, __last);
-    if (_IterOps<_AlgPolicy>::next(__middle) == __last)
+    if (_IterOps<_AlgPolicy>::__next_n(__middle) == __last)
       return std::__rotate_right<_AlgPolicy>(__first, __last);
     return std::__rotate_random_access<_AlgPolicy>(__first, __middle, __last);
   }
@@ -162,7 +162,7 @@ template <class _AlgPolicy, class _Iterator, class _Sentinel>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iterator, _Iterator>
 __rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) {
   using _Ret            = pair<_Iterator, _Iterator>;
-  _Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last);
+  _Iterator __last_iter = _IterOps<_AlgPolicy>::__next_sentinel(__middle, __last);
 
   if (__first == __middle)
     return _Ret(__last_iter, __last_iter);
diff --git a/libcxx/include/__algorithm/set_intersection.h b/libcxx/include/__algorithm/set_intersection.h
index 6246e24b9ca4e..945e8eefca8f7 100644
--- a/libcxx/include/__algorithm/set_intersection.h
+++ b/libcxx/include/__algorithm/set_intersection.h
@@ -117,8 +117,8 @@ __set_intersection(
         __first2 == __first2_next, __first1, __first2, __result, __prev_may_be_equal);
   }
   return __set_intersection_result<_InForwardIter1, _InForwardIter2, _OutIter>(
-      _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)),
-      _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)),
+      _IterOps<_AlgPolicy>::__next_sentinel(std::move(__first1), std::move(__last1)),
+      _IterOps<_AlgPolicy>::__next_sentinel(std::move(__first2), std::move(__last2)),
       std::move(__result));
 }
 
@@ -155,8 +155,8 @@ __set_intersection(
   }
 
   return __set_intersection_result<_InInputIter1, _InInputIter2, _OutIter>(
-      _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)),
-      _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)),
+      _IterOps<_AlgPolicy>::__next_sentinel(std::move(__first1), std::move(__last1)),
+      _IterOps<_AlgPolicy>::__next_sentinel(std::move(__first2), std::move(__last2)),
       std::move(__result));
 }
 
diff --git a/libcxx/include/__algorithm/shift_left.h b/libcxx/include/__algorithm/shift_left.h
index 42d6c2321ff7d..25397263731e5 100644
--- a/libcxx/include/__algorithm/shift_left.h
+++ b/libcxx/include/__algorithm/shift_left.h
@@ -35,7 +35,7 @@ __shift_left(_Iter __first, _Sent __last, typename _IterOps<_AlgPolicy>::templat
   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n >= 0, "n must be greater than or equal to 0");
 
   if (__n == 0) {
-    _Iter __end = _IterOps<_AlgPolicy>::next(__first, __last);
+    _Iter __end = _IterOps<_AlgPolicy>::__next_sentinel(__first, __last);
     return {std::move(__first), std::move(__end)};
   }
 
diff --git a/libcxx/include/__algorithm/shuffle.h b/libcxx/include/__algorithm/shuffle.h
index 7177fbb469ba7..9a5b0b7e8654c 100644
--- a/libcxx/include/__algorithm/shuffle.h
+++ b/libcxx/include/__algorithm/shuffle.h
@@ -138,7 +138,7 @@ __shuffle(_RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRand
   typedef uniform_int_distribution<ptrdiff_t> _Dp;
   typedef typename _Dp::param_type _Pp;
 
-  auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel);
+  auto __original_last = _IterOps<_AlgPolicy>::__next_sentinel(__first, __last_sentinel);
   auto __last          = __original_last;
   difference_type __d  = __last - __first;
   if (__d > 1) {
diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h
index d77286c9e5af5..4691ade856879 100644
--- a/libcxx/include/__algorithm/upper_bound.h
+++ b/libcxx/include/__algorithm/upper_bound.h
@@ -38,7 +38,7 @@ __upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp
   auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
   while (__len != 0) {
     auto __half_len = std::__half_positive(__len);
-    auto __mid      = _IterOps<_AlgPolicy>::next(__first, __half_len);
+    auto __mid      = _IterOps<_AlgPolicy>::__next_n(__first, __half_len);
     if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid)))
       __len = __half_len;
     else {
diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h
index c7d3c1f0e8f05..3a5988ca16643 100644
--- a/libcxx/include/__iterator/advance.h
+++ b/libcxx/include/__iterator/advance.h
@@ -74,6 +74,9 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void advance(_InputIter& __i
 
 // [range.iter.op.advance]
 
+template <class _AlgPolicy>
+struct _IterOps;
+
 namespace ranges {
 struct __advance {
 private:
@@ -93,10 +96,12 @@ struct __advance {
     }
   }
 
-public:
+  template <class _AlgPolicy>
+  friend struct std::_IterOps;
+
   // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative.
   template <input_or_output_iterator _Ip>
-  _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const {
+  _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_n(_Ip& __i, iter_difference...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/179095


More information about the libcxx-commits mailing list