[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 8 00:31:14 PST 2026


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

>From 9db99c3bcf45083ed7ba29849011e14fdd44c892 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 1 Feb 2026 10:13:38 +0000
Subject: [PATCH 1/3] [libc++] avoid using `ranges::advance` and `ranges::next`
 in all algorithms

---
 libcxx/include/__algorithm/copy_backward.h    |  2 +-
 libcxx/include/__algorithm/equal_range.h      |  4 +--
 libcxx/include/__algorithm/find_end.h         | 10 +++---
 libcxx/include/__algorithm/is_permutation.h   |  4 +--
 .../include/__algorithm/iterator_operations.h | 30 +++++++++++++---
 libcxx/include/__algorithm/move_backward.h    |  2 +-
 libcxx/include/__algorithm/next_permutation.h |  2 +-
 libcxx/include/__algorithm/partial_sort.h     |  4 +--
 .../include/__algorithm/partial_sort_copy.h   |  2 +-
 libcxx/include/__algorithm/partition.h        |  2 +-
 libcxx/include/__algorithm/prev_permutation.h |  2 +-
 libcxx/include/__algorithm/rotate.h           | 14 ++++----
 libcxx/include/__algorithm/set_intersection.h |  8 ++---
 libcxx/include/__algorithm/shift_left.h       |  2 +-
 libcxx/include/__algorithm/shuffle.h          |  2 +-
 libcxx/include/__algorithm/upper_bound.h      |  2 +-
 libcxx/include/__iterator/advance.h           | 27 +++++++++++---
 .../alg.merge/inplace_merge.compile.pass.cpp  | 35 +++++++++++++++++++
 18 files changed, 115 insertions(+), 39 deletions(-)
 create mode 100644 libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp

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_t<_Ip> __n) {
     _LIBCPP_ASSERT_PEDANTIC(bidirectional_iterator<_Ip> || __n >= 0,
                             "ranges::advance: Can only pass a negative `n` with a bidirectional_iterator.");
 
@@ -120,7 +125,7 @@ struct __advance {
   // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound_sentinel)
   // denotes a range.
   template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
-  _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const {
+  _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_sentinel(_Ip& __i, _Sp __bound_sentinel) {
     // If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound_sentinel)`.
     if constexpr (assignable_from<_Ip&, _Sp>) {
       __i = std::move(__bound_sentinel);
@@ -128,7 +133,7 @@ struct __advance {
     // Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent to `ranges::advance(i, bound_sentinel -
     // i)`.
     else if constexpr (sized_sentinel_for<_Sp, _Ip>) {
-      (*this)(__i, __bound_sentinel - __i);
+      __advance_n(__i, __bound_sentinel - __i);
     }
     // Otherwise, while `bool(i != bound_sentinel)` is true, increments `i`.
     else {
@@ -138,6 +143,20 @@ struct __advance {
     }
   }
 
+public:
+  // 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 {
+    return __advance_n(__i, __n);
+  }
+
+  // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound_sentinel)
+  // denotes a range.
+  template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
+  _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const {
+    __advance_sentinel(__i, std::move(__bound_sentinel));
+  }
+
   // Preconditions:
   //   * If `n > 0`, [i, bound_sentinel) denotes a range.
   //   * If `n == 0`, [i, bound_sentinel) or [bound_sentinel, i) denotes a range.
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp
new file mode 100644
index 0000000000000..c1d0451495725
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// REQUIRES: std-at-least-c++20
+
+// inplace_merge used to use ranges::advance, which can result in ambiguous call
+// https://cplusplus.github.io/LWG/issue4510
+
+#include <algorithm>
+#include <cassert>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+struct OmniConv {
+  OmniConv(const auto&);
+  friend bool operator==(OmniConv, OmniConv); // found by ADL via things related to OmniConv
+
+  friend bool operator<=>(OmniConv, OmniConv);
+};
+
+void test() {
+  OmniConv arr[] = {{1}, {2}, {3}};
+
+  using Iter = bidirectional_iterator<OmniConv*>;
+
+  std::ranges::inplace_merge(Iter(arr), Iter(arr + 1), Iter(arr + 2));
+}

>From 1cecfec4ff9d6f3bf304e1fa2fba7de977afd311 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 1 Feb 2026 10:47:26 +0000
Subject: [PATCH 2/3] test

---
 .../alg.sorting/alg.merge/inplace_merge.compile.pass.cpp      | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp
index c1d0451495725..3186415b06544 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.compile.pass.cpp
@@ -21,9 +21,9 @@
 
 struct OmniConv {
   OmniConv(const auto&);
-  friend bool operator==(OmniConv, OmniConv); // found by ADL via things related to OmniConv
+  friend bool operator==(OmniConv, OmniConv) = default; // found by ADL via things related to OmniConv
 
-  friend bool operator<=>(OmniConv, OmniConv);
+  friend auto operator<=>(OmniConv, OmniConv) = default;
 };
 
 void test() {

>From 647e69aea0a0e8907b329bc42d8ef955680a44a2 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 8 Feb 2026 08:31:02 +0000
Subject: [PATCH 3/3] rename

---
 libcxx/include/__algorithm/copy_backward.h       |  2 +-
 libcxx/include/__algorithm/equal_range.h         |  2 +-
 libcxx/include/__algorithm/find_end.h            | 10 +++++-----
 libcxx/include/__algorithm/iterator_operations.h |  6 +++---
 libcxx/include/__algorithm/move_backward.h       |  2 +-
 libcxx/include/__algorithm/next_permutation.h    |  2 +-
 libcxx/include/__algorithm/partial_sort.h        |  4 ++--
 libcxx/include/__algorithm/partial_sort_copy.h   |  2 +-
 libcxx/include/__algorithm/partition.h           |  2 +-
 libcxx/include/__algorithm/prev_permutation.h    |  2 +-
 libcxx/include/__algorithm/rotate.h              |  2 +-
 libcxx/include/__algorithm/set_intersection.h    |  8 ++++----
 libcxx/include/__algorithm/shift_left.h          |  2 +-
 libcxx/include/__algorithm/shuffle.h             |  2 +-
 libcxx/include/__iterator/advance.h              |  7 ++-----
 15 files changed, 26 insertions(+), 29 deletions(-)

diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h
index bc2445074fb8b..01e56b88482cb 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_sentinel(__first, __last);
+    auto __last_iter          = _IterOps<_AlgPolicy>::__next_until(__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 eba132ca9c81e..ea368f8895ee2 100644
--- a/libcxx/include/__algorithm/equal_range.h
+++ b/libcxx/include/__algorithm/equal_range.h
@@ -36,7 +36,7 @@ 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_sentinel(__first, __last);
+  _Iter __end = _IterOps<_AlgPolicy>::__next_until(__first, __last);
   while (__len != 0) {
     auto __half_len = std::__half_positive(__len);
     _Iter __mid     = _IterOps<_AlgPolicy>::__next_n(__first, __half_len);
diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h
index af67b7c6969fc..dde845f1cddbc 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_sentinel(__first1, __last1); // __last1 is the "default" answer
+  _Iter1 __match_first = _IterOps<_AlgPolicy>::__next_until(__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_sentinel(__first1, __sent1);
-  auto __last2 = _IterOps<_AlgPolicy>::__next_sentinel(__first2, __sent2);
+  auto __last1 = _IterOps<_AlgPolicy>::__next_until(__first1, __sent1);
+  auto __last2 = _IterOps<_AlgPolicy>::__next_until(__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_sentinel(__first1, __sent1);
-  auto __last2 = _IterOps<_AlgPolicy>::__next_sentinel(__first2, __sent2);
+  auto __last1 = _IterOps<_AlgPolicy>::__next_until(__first1, __sent1);
+  auto __last2 = _IterOps<_AlgPolicy>::__next_until(__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/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
index 6c8bf2b1bd88d..a1f2b46a6abb9 100644
--- a/libcxx/include/__algorithm/iterator_operations.h
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -75,8 +75,8 @@ struct _IterOps<_RangeAlgPolicy> {
   }
 
   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);
+  _LIBCPP_HIDE_FROM_ABI static constexpr _Ip __next_until(_Ip __x, _Sp __bound_sentinel) {
+    ranges::__advance::__advance_until(__x, __bound_sentinel);
     return __x;
   }
 
@@ -162,7 +162,7 @@ struct _IterOps<_ClassicAlgPolicy> {
 
   // next
   template <class _Iterator>
-  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iterator __next_sentinel(_Iterator, _Iterator __last) {
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iterator __next_until(_Iterator, _Iterator __last) {
     return __last;
   }
 
diff --git a/libcxx/include/__algorithm/move_backward.h b/libcxx/include/__algorithm/move_backward.h
index e9a4db4a293a2..3025e9faf01d5 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_sentinel(__first, __last);
+    auto __last_iter          = _IterOps<_AlgPolicy>::__next_until(__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 cc18f2a295010..86a5407b92018 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_sentinel(__first, __last);
+  _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::__next_until(__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 b00988a2887ea..037900b6ffd87 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_sentinel(__middle, __last);
+    return _IterOps<_AlgPolicy>::__next_until(__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_sentinel(__middle, __last);
+    return _IterOps<_AlgPolicy>::__next_until(__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 1e4e0728df494..b8d43dd8a21d2 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_sentinel(std::move(__first), std::move(__last)), std::move(__r));
+      _IterOps<_AlgPolicy>::__next_until(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 32af0c3bc6a7d..ff79baff371d5 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_sentinel(__first, __sentinel);
+  _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::__next_until(__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 2d2602ff9cd86..54dc43160fb38 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_sentinel(__first, __last);
+  _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::__next_until(__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 6f59034dcd02e..162eb1ec4e4b0 100644
--- a/libcxx/include/__algorithm/rotate.h
+++ b/libcxx/include/__algorithm/rotate.h
@@ -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_sentinel(__middle, __last);
+  _Iterator __last_iter = _IterOps<_AlgPolicy>::__next_until(__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 945e8eefca8f7..2da5b63af40b7 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_sentinel(std::move(__first1), std::move(__last1)),
-      _IterOps<_AlgPolicy>::__next_sentinel(std::move(__first2), std::move(__last2)),
+      _IterOps<_AlgPolicy>::__next_until(std::move(__first1), std::move(__last1)),
+      _IterOps<_AlgPolicy>::__next_until(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_sentinel(std::move(__first1), std::move(__last1)),
-      _IterOps<_AlgPolicy>::__next_sentinel(std::move(__first2), std::move(__last2)),
+      _IterOps<_AlgPolicy>::__next_until(std::move(__first1), std::move(__last1)),
+      _IterOps<_AlgPolicy>::__next_until(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 25397263731e5..6f8b1838c9be3 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_sentinel(__first, __last);
+    _Iter __end = _IterOps<_AlgPolicy>::__next_until(__first, __last);
     return {std::move(__first), std::move(__end)};
   }
 
diff --git a/libcxx/include/__algorithm/shuffle.h b/libcxx/include/__algorithm/shuffle.h
index 9a5b0b7e8654c..78ed4f29f07b9 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_sentinel(__first, __last_sentinel);
+  auto __original_last = _IterOps<_AlgPolicy>::__next_until(__first, __last_sentinel);
   auto __last          = __original_last;
   difference_type __d  = __last - __first;
   if (__d > 1) {
diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h
index 3a5988ca16643..4780cb1cff1dd 100644
--- a/libcxx/include/__iterator/advance.h
+++ b/libcxx/include/__iterator/advance.h
@@ -125,7 +125,7 @@ struct __advance {
   // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound_sentinel)
   // denotes a range.
   template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
-  _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_sentinel(_Ip& __i, _Sp __bound_sentinel) {
+  _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_until(_Ip& __i, _Sp __bound_sentinel) {
     // If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound_sentinel)`.
     if constexpr (assignable_from<_Ip&, _Sp>) {
       __i = std::move(__bound_sentinel);
@@ -144,17 +144,14 @@ struct __advance {
   }
 
 public:
-  // 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 {
     return __advance_n(__i, __n);
   }
 
-  // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound_sentinel)
-  // denotes a range.
   template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp>
   _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const {
-    __advance_sentinel(__i, std::move(__bound_sentinel));
+    __advance_until(__i, std::move(__bound_sentinel));
   }
 
   // Preconditions:



More information about the libcxx-commits mailing list