[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