[libcxx-commits] [libcxx] [libc++] LWG4490: Allow calling `std::ranges::size` in ranges algorithms (PR #217460)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Aug 19 13:55:04 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: eiytoq (eiytoq)
<details>
<summary>Changes</summary>
LWG4490 allows implementations to use `ranges::size()` to optimize algorithms.
This patch applies this to the following range algorithms:
sorting algorithms
heap algorithms
`ranges::next_permutation`
`ranges::prev_permutation`
`ranges::copy_backward`
`ranges::move_backward`
`ranges::fold_right`
`ranges::fold_right_last`
`ranges::inplace_merge`
`ranges::reverse`
`ranges::reverse_copy`
`ranges::rotate`
`ranges::shuffle`
`ranges::stable_partition`
Fixes #<!-- -->204452
---
Patch is 23.99 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217460.diff
24 Files Affected:
- (modified) libcxx/docs/Status/Cxx29Issues.csv (+1-1)
- (modified) libcxx/include/__algorithm/iterator_operations.h (+13)
- (modified) libcxx/include/__algorithm/ranges_copy_backward.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_fold.h (+9-2)
- (modified) libcxx/include/__algorithm/ranges_inplace_merge.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_is_heap.h (+5-1)
- (modified) libcxx/include/__algorithm/ranges_is_heap_until.h (+5-1)
- (modified) libcxx/include/__algorithm/ranges_make_heap.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_move_backward.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_next_permutation.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_nth_element.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_partial_sort.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_pop_heap.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_prev_permutation.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_push_heap.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_reverse.h (+5-1)
- (modified) libcxx/include/__algorithm/ranges_reverse_copy.h (+7-2)
- (modified) libcxx/include/__algorithm/ranges_rotate.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_shuffle.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_sort.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_sort_heap.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_stable_partition.h (+4-1)
- (modified) libcxx/include/__algorithm/ranges_stable_sort.h (+4-1)
- (added) libcxx/test/libcxx/algorithms/iterator_operations.pass.cpp (+60)
``````````diff
diff --git a/libcxx/docs/Status/Cxx29Issues.csv b/libcxx/docs/Status/Cxx29Issues.csv
index 13056a97782df..c6a7d58168e42 100644
--- a/libcxx/docs/Status/Cxx29Issues.csv
+++ b/libcxx/docs/Status/Cxx29Issues.csv
@@ -11,7 +11,7 @@
"`LWG4385 <https://wg21.link/LWG4385>`__","Including ``<simd>`` doesn't provide ``std::begin``/``end``","2026-06 (Brno)","","","`#204449 <https://github.com/llvm/llvm-project/issues/204449>`__",""
"`LWG4471 <https://wg21.link/LWG4471>`__","Remove test for ``get_env`` ``noexcept``-ness from ``inline_scheduler``","2026-06 (Brno)","","","`#204450 <https://github.com/llvm/llvm-project/issues/204450>`__",""
"`LWG4487 <https://wg21.link/LWG4487>`__","Is member ``is_steady`` of a *Cpp17Clock* type required to be usable in constant expressions?","2026-06 (Brno)","","","`#204451 <https://github.com/llvm/llvm-project/issues/204451>`__",""
-"`LWG4490 <https://wg21.link/LWG4490>`__","Allow calling ``std::ranges::size`` in ranges algorithms","2026-06 (Brno)","","","`#204452 <https://github.com/llvm/llvm-project/issues/204452>`__",""
+"`LWG4490 <https://wg21.link/LWG4490>`__","Allow calling ``std::ranges::size`` in ranges algorithms","2026-06 (Brno)","|Complete|","24","`#204452 <https://github.com/llvm/llvm-project/issues/204452>`__",""
"`LWG4521 <https://wg21.link/LWG4521>`__","Improve [atomics.order] p10 to have a consistent way with [intro.races]","2026-06 (Brno)","","","`#204453 <https://github.com/llvm/llvm-project/issues/204453>`__",""
"`LWG4531 <https://wg21.link/LWG4531>`__","Should there be a feature-test macro update for ``constexpr`` ``std::to_(w)string``?","2026-06 (Brno)","","","`#204454 <https://github.com/llvm/llvm-project/issues/204454>`__",""
"`LWG4567 <https://wg21.link/LWG4567>`__","Feature test macro value for ``apply_result``, ``is_applicable``","2026-06 (Brno)","","","`#204455 <https://github.com/llvm/llvm-project/issues/204455>`__",""
diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
index 1aa2f8d1604f1..273f3298f780f 100644
--- a/libcxx/include/__algorithm/iterator_operations.h
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -22,6 +22,8 @@
#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/readable_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/is_same.h>
@@ -63,6 +65,17 @@ struct _IterOps<_RangeAlgPolicy> {
static constexpr auto next = ranges::next;
static constexpr auto prev = ranges::prev;
static constexpr auto __advance_to = ranges::advance;
+
+ template <ranges::forward_range _Range>
+ _LIBCPP_HIDE_FROM_ABI static constexpr auto __end(_Range&& __range) {
+ if constexpr (ranges::common_range<_Range>) {
+ return ranges::end(__range);
+ } else if constexpr (ranges::random_access_range<_Range> && ranges::sized_range<_Range>) {
+ return ranges::next(ranges::begin(__range), ranges::distance(__range));
+ } else {
+ return ranges::end(__range);
+ }
+ }
};
#endif
diff --git a/libcxx/include/__algorithm/ranges_copy_backward.h b/libcxx/include/__algorithm/ranges_copy_backward.h
index ff4e7c241e1e8..c8f9195a1ff46 100644
--- a/libcxx/include/__algorithm/ranges_copy_backward.h
+++ b/libcxx/include/__algorithm/ranges_copy_backward.h
@@ -47,7 +47,10 @@ struct __copy_backward {
requires indirectly_copyable<iterator_t<_Range>, _Iter>
_LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<borrowed_iterator_t<_Range>, _Iter>
operator()(_Range&& __r, _Iter __result) const {
- return std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
+ auto __first = ranges::begin(__r);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__r);
+
+ return std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
}
};
diff --git a/libcxx/include/__algorithm/ranges_fold.h b/libcxx/include/__algorithm/ranges_fold.h
index a82d9acfcea8c..1c0ac56e1dee8 100644
--- a/libcxx/include/__algorithm/ranges_fold.h
+++ b/libcxx/include/__algorithm/ranges_fold.h
@@ -11,6 +11,7 @@
#define _LIBCPP___ALGORITHM_RANGES_FOLD_H
#include <__algorithm/for_each.h>
+#include <__algorithm/iterator_operations.h>
#include <__concepts/assignable.h>
#include <__concepts/constructible.h>
#include <__concepts/convertible_to.h>
@@ -231,7 +232,10 @@ struct __fold_right {
template <bidirectional_range _Range, class _Tp, __indirectly_binary_right_foldable<_Tp, iterator_t<_Range>> _Func>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range, _Tp __init, _Func __func) {
- return operator()(ranges::begin(__range), ranges::end(__range), std::move(__init), std::ref(__func));
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
+ return operator()(std::move(__first), std::move(__last), std::move(__init), std::ref(__func));
}
};
@@ -255,7 +259,10 @@ struct __fold_right_last {
template <bidirectional_range _Range,
__indirectly_binary_right_foldable<range_value_t<_Range>, iterator_t<_Range>> _Func>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range, _Func __func) {
- return operator()(ranges::begin(__range), ranges::end(__range), std::ref(__func));
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
+ return operator()(std::move(__first), std::move(__last), std::ref(__func));
}
};
diff --git a/libcxx/include/__algorithm/ranges_inplace_merge.h b/libcxx/include/__algorithm/ranges_inplace_merge.h
index 54581aff396ea..7abb1a7f4b55b 100644
--- a/libcxx/include/__algorithm/ranges_inplace_merge.h
+++ b/libcxx/include/__algorithm/ranges_inplace_merge.h
@@ -61,8 +61,11 @@ struct __inplace_merge {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 borrowed_iterator_t<_Range>
operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
return __inplace_merge_impl(
- ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj));
+ std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj));
}
};
diff --git a/libcxx/include/__algorithm/ranges_is_heap.h b/libcxx/include/__algorithm/ranges_is_heap.h
index b4724abfb62a5..db750e6d52fe1 100644
--- a/libcxx/include/__algorithm/ranges_is_heap.h
+++ b/libcxx/include/__algorithm/ranges_is_heap.h
@@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H
#include <__algorithm/is_heap_until.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/make_projected.h>
#include <__config>
#include <__functional/identity.h>
@@ -59,7 +60,10 @@ struct __is_heap {
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
- return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
+ return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_is_heap_until.h b/libcxx/include/__algorithm/ranges_is_heap_until.h
index 25f3b484faa66..92e1cb3887195 100644
--- a/libcxx/include/__algorithm/ranges_is_heap_until.h
+++ b/libcxx/include/__algorithm/ranges_is_heap_until.h
@@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H
#include <__algorithm/is_heap_until.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/make_projected.h>
#include <__config>
#include <__functional/identity.h>
@@ -59,7 +60,10 @@ struct __is_heap_until {
indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
- return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj);
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
+ return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_make_heap.h b/libcxx/include/__algorithm/ranges_make_heap.h
index 97148f77b4181..8a65497c058fb 100644
--- a/libcxx/include/__algorithm/ranges_make_heap.h
+++ b/libcxx/include/__algorithm/ranges_make_heap.h
@@ -63,7 +63,10 @@ struct __make_heap {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
- return __make_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ auto __first = ranges::begin(__r);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__r);
+
+ return __make_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_move_backward.h b/libcxx/include/__algorithm/ranges_move_backward.h
index a4b51d09a68b0..d64f7d18a434c 100644
--- a/libcxx/include/__algorithm/ranges_move_backward.h
+++ b/libcxx/include/__algorithm/ranges_move_backward.h
@@ -49,7 +49,10 @@ struct __move_backward {
requires indirectly_movable<iterator_t<_Range>, _Iter>
_LIBCPP_HIDE_FROM_ABI constexpr move_backward_result<borrowed_iterator_t<_Range>, _Iter>
operator()(_Range&& __range, _Iter __result) const {
- return std::__move_backward<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), std::move(__result));
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
+ return std::__move_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
}
};
diff --git a/libcxx/include/__algorithm/ranges_next_permutation.h b/libcxx/include/__algorithm/ranges_next_permutation.h
index 1b485423e892f..333c33e6fc5c3 100644
--- a/libcxx/include/__algorithm/ranges_next_permutation.h
+++ b/libcxx/include/__algorithm/ranges_next_permutation.h
@@ -54,8 +54,11 @@ struct __next_permutation {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr next_permutation_result<borrowed_iterator_t<_Range>>
operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
auto __result = std::__next_permutation<_RangeAlgPolicy>(
- ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
+ std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
return {std::move(__result.first), std::move(__result.second)};
}
};
diff --git a/libcxx/include/__algorithm/ranges_nth_element.h b/libcxx/include/__algorithm/ranges_nth_element.h
index e92c51e713cb4..771543f28121d 100644
--- a/libcxx/include/__algorithm/ranges_nth_element.h
+++ b/libcxx/include/__algorithm/ranges_nth_element.h
@@ -62,7 +62,10 @@ struct __nth_element {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, _Proj __proj = {}) const {
- return __nth_element_fn_impl(ranges::begin(__r), std::move(__nth), ranges::end(__r), __comp, __proj);
+ auto __first = ranges::begin(__r);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__r);
+
+ return __nth_element_fn_impl(std::move(__first), std::move(__nth), std::move(__last), __comp, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_partial_sort.h b/libcxx/include/__algorithm/ranges_partial_sort.h
index fc8a1f7d93065..51dda25cfba12 100644
--- a/libcxx/include/__algorithm/ranges_partial_sort.h
+++ b/libcxx/include/__algorithm/ranges_partial_sort.h
@@ -60,7 +60,10 @@ struct __partial_sort {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const {
- return __partial_sort_fn_impl(ranges::begin(__r), std::move(__middle), ranges::end(__r), __comp, __proj);
+ auto __first = ranges::begin(__r);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__r);
+
+ return __partial_sort_fn_impl(std::move(__first), std::move(__middle), std::move(__last), __comp, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_pop_heap.h b/libcxx/include/__algorithm/ranges_pop_heap.h
index eccf54c094e3d..6584d749f893a 100644
--- a/libcxx/include/__algorithm/ranges_pop_heap.h
+++ b/libcxx/include/__algorithm/ranges_pop_heap.h
@@ -64,7 +64,10 @@ struct __pop_heap {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
- return __pop_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ auto __first = ranges::begin(__r);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__r);
+
+ return __pop_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_prev_permutation.h b/libcxx/include/__algorithm/ranges_prev_permutation.h
index f2294b1cb00ba..6707ff52f5368 100644
--- a/libcxx/include/__algorithm/ranges_prev_permutation.h
+++ b/libcxx/include/__algorithm/ranges_prev_permutation.h
@@ -54,8 +54,11 @@ struct __prev_permutation {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<borrowed_iterator_t<_Range>>
operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
auto __result = std::__prev_permutation<_RangeAlgPolicy>(
- ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
+ std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
return {std::move(__result.first), std::move(__result.second)};
}
};
diff --git a/libcxx/include/__algorithm/ranges_push_heap.h b/libcxx/include/__algorithm/ranges_push_heap.h
index c5e0465bdcfe1..c5c5ceb4ac865 100644
--- a/libcxx/include/__algorithm/ranges_push_heap.h
+++ b/libcxx/include/__algorithm/ranges_push_heap.h
@@ -63,7 +63,10 @@ struct __push_heap {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
- return __push_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ auto __first = ranges::begin(__r);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__r);
+
+ return __push_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_reverse.h b/libcxx/include/__algorithm/ranges_reverse.h
index 4e82118719772..5b549150f6218 100644
--- a/libcxx/include/__algorithm/ranges_reverse.h
+++ b/libcxx/include/__algorithm/ranges_reverse.h
@@ -9,6 +9,7 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_H
#define _LIBCPP___ALGORITHM_RANGES_REVERSE_H
+#include <__algorithm/iterator_operations.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iter_swap.h>
@@ -61,7 +62,10 @@ struct __reverse {
template <bidirectional_range _Range>
requires permutable<iterator_t<_Range>>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range) const {
- return (*this)(ranges::begin(__range), ranges::end(__range));
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
+ return (*this)(std::move(__first), std::move(__last));
}
};
diff --git a/libcxx/include/__algorithm/ranges_reverse_copy.h b/libcxx/include/__algorithm/ranges_reverse_copy.h
index 9fedab5bd4362..1f1de11f8dca3 100644
--- a/libcxx/include/__algorithm/ranges_reverse_copy.h
+++ b/libcxx/include/__algorithm/ranges_reverse_copy.h
@@ -10,6 +10,7 @@
#define _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H
#include <__algorithm/in_out_result.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/ranges_copy.h>
#include <__config>
#include <__iterator/concepts.h>
@@ -50,8 +51,12 @@ struct __reverse_copy {
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
_LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result<borrowed_iterator_t<_Range>, _OutIter>
operator()(_Range&& __range, _OutIter __result) const {
- auto __ret = ranges::copy(__range | views::reverse, std::move(__result));
- return {ranges::next(ranges::begin(__range), ranges::end(__range)), std::move(__ret.out)};
+ auto __first = ranges::begin(__range);
+ auto __last = ranges::next(__first, _IterOps<_RangeAlgPolicy>::__end(__range));
+
+ auto __ret =
+ ranges::copy(std::make_reverse_iterator(__last), std::make_reverse_iterator(__first), std::move(__result));
+ return {std::move(__last), std::move(__ret.out)};
}
};
diff --git a/libcxx/include/__algorithm/ranges_rotate.h b/libcxx/include/__algorithm/ranges_rotate.h
index c1affc684ae4f..6878fed268de4 100644
--- a/libcxx/include/__algorithm/ranges_rotate.h
+++ b/libcxx/include/__algorithm/ranges_rotate.h
@@ -49,7 +49,10 @@ struct __rotate {
requires permutable<iterator_t<_Range>>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __range, iterator_t<_Range> __middle) const {
- return __rotate_fn_impl(ranges::begin(__range), std::move(__middle), ranges::end(__range));
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
+ return __rotate_fn_impl(std::move(__first), std::move(__middle), std::move(__last));
}
};
diff --git a/libcxx/include/__algorithm/ranges_shuffle.h b/libcxx/include/__algorithm/ranges_shuffle.h
index 87cb3685bb95f..c22780c722a0e 100644
--- a/libcxx/include/__algorithm/ranges_shuffle.h
+++ b/libcxx/include/__algorithm/ranges_shuffle.h
@@ -50,7 +50,10 @@ struct __shuffle {
template <random_access_range _Range, class _Gen>
requires permutable<iterator_t<_Range>> && uniform_random_bit_generator<remove_reference_t<_Gen>>
_LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const {
- return (*this)(ranges::begin(__range), ranges::end(__range), std::forward<_Gen>(__gen));
+ auto __first = ranges::begin(__range);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__range);
+
+ return (*this)(std::move(__first), std::move(__last), std::forward<_Gen>(__gen));
}
};
diff --git a/libcxx/include/__algorithm/ranges_sort.h b/libcxx/include/__algorithm/ranges_sort.h
index 2afad4c41301e..8e3adab29bda2 100644
--- a/libcxx/include/__algorithm/ranges_sort.h
+++ b/libcxx/include/__algorithm/ranges_sort.h
@@ -62,7 +62,10 @@ struct __sort {
requires sortable<iterator_t<_Range>, _Comp, _Proj>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
- return __sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
+ auto __first = ranges::begin(__r);
+ auto __last = _IterOps<_RangeAlgPolicy>::__end(__r);
+
+ return __sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj);
}
};
diff --git a/libcxx/include/__algorithm/ranges_sort_heap.h b/libcxx/include/__algorithm/ranges_sort_heap.h
index d3e20874fac50..f14f37c96a7da 100644
--- a/libcxx/include/__algorithm/ranges_sort_heap.h
+++ b/lib...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/217460
More information about the libcxx-commits
mailing list