[libc++] Implement ranges::shift_right#177847
Merged
Conversation
Member
|
@llvm/pr-subscribers-libcxx Author: Hui (huixie90) ChangesPatch is 33.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/177847.diff 18 Files Affected:
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index d2b76cb96e866..0f65770a4fa14 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -394,6 +394,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_reference_from_temporary`` *unimplemented*
---------------------------------------------------------- -----------------
+ ``__cpp_lib_shift`` ``202202L``
+ ---------------------------------------------------------- -----------------
``__cpp_lib_spanstream`` *unimplemented*
---------------------------------------------------------- -----------------
``__cpp_lib_stacktrace`` *unimplemented*
diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index 73f5984768592..ffc586d9630a3 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -38,6 +38,8 @@ What's New in Libc++ 23.0.0?
Implemented Papers
------------------
+- P2440R1: ``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right`` (`Github <https://llvm.org/PR105184>`__)
+
Improvements and New Features
-----------------------------
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 2a5c64a53d79e..fd99ff635aa00 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -46,7 +46,7 @@
"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","|Partial|","","`#105180 <https://github.com/llvm/llvm-project/issues/105180>`__","Implemented the type traits only."
"`P2273R3 <https://wg21.link/P2273R3>`__","Making ``std::unique_ptr`` constexpr","2022-02 (Virtual)","|Complete|","16","`#105182 <https://github.com/llvm/llvm-project/issues/105182>`__",""
"`P2387R3 <https://wg21.link/P2387R3>`__","Pipe support for user-defined range adaptors","2022-02 (Virtual)","|Complete|","19","`#105183 <https://github.com/llvm/llvm-project/issues/105183>`__",""
-"`P2440R1 <https://wg21.link/P2440R1>`__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","|Partial|","","`#105184 <https://github.com/llvm/llvm-project/issues/105184>`__","Only ``ranges::iota`` is implemented."
+"`P2440R1 <https://wg21.link/P2440R1>`__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","|Complete|","23","`#105184 <https://github.com/llvm/llvm-project/issues/105184>`__",""
"`P2441R2 <https://wg21.link/P2441R2>`__","``views::join_with``","2022-02 (Virtual)","|Complete|","21","`#105185 <https://github.com/llvm/llvm-project/issues/105185>`__",""
"`P2442R1 <https://wg21.link/P2442R1>`__","Windowing range adaptors: ``views::chunk`` and ``views::slide``","2022-02 (Virtual)","","","`#105187 <https://github.com/llvm/llvm-project/issues/105187>`__",""
"`P2443R1 <https://wg21.link/P2443R1>`__","``views::chunk_by``","2022-02 (Virtual)","|Complete|","18","`#105188 <https://github.com/llvm/llvm-project/issues/105188>`__",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index a4ad3bedd2460..5be7474278c7f 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -157,6 +157,7 @@ set(files
__algorithm/ranges_set_intersection.h
__algorithm/ranges_set_symmetric_difference.h
__algorithm/ranges_set_union.h
+ __algorithm/ranges_shift_right.h
__algorithm/ranges_shuffle.h
__algorithm/ranges_sort.h
__algorithm/ranges_sort_heap.h
diff --git a/libcxx/include/__algorithm/ranges_shift_right.h b/libcxx/include/__algorithm/ranges_shift_right.h
new file mode 100644
index 0000000000000..9b3f27ea2bb0a
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_shift_right.h
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SHIFT_RIGHT_H
+#define _LIBCPP___ALGORITHM_RANGES_SHIFT_RIGHT_H
+
+#include <__algorithm/iterator_operations.h>
+#include <__algorithm/shift_right.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/permutable.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/subrange.h>
+#include <__utility/move.h>
+#include <iterator>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+namespace __shift_right {
+
+struct __fn {
+ template <permutable _Iter, sentinel_for<_Iter> _Sent>
+ _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter>
+ operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __n) {
+ auto __ret = std::__shift_right<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__n));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+
+ template <forward_range _Range>
+ requires permutable<iterator_t<_Range>>
+ _LIBCPP_HIDE_FROM_ABI static constexpr borrowed_subrange_t<_Range>
+ operator()(_Range&& __range, range_difference_t<_Range> __n) {
+ if constexpr (sized_range<_Range>) {
+ if (__n >= ranges::distance(__range)) {
+ auto __iter = ranges::begin(__range);
+ auto __end = ranges::end(__range);
+ ranges::advance(__iter, __end);
+ return {__iter, std::move(__iter)};
+ }
+ }
+
+ auto __ret = std::__shift_right<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), std::move(__n));
+ return {std::move(__ret.first), std::move(__ret.second)};
+ }
+};
+} // namespace __shift_right
+
+inline namespace __cpo {
+inline constexpr auto shift_right = __shift_right::__fn{};
+} // namespace __cpo
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SHIFT_RIGHT_H
diff --git a/libcxx/include/__algorithm/shift_right.h b/libcxx/include/__algorithm/shift_right.h
index 01853057fc478..338a1401dad72 100644
--- a/libcxx/include/__algorithm/shift_right.h
+++ b/libcxx/include/__algorithm/shift_right.h
@@ -9,12 +9,18 @@
#ifndef _LIBCPP___ALGORITHM_SHIFT_RIGHT_H
#define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/move.h>
#include <__algorithm/move_backward.h>
#include <__algorithm/swap_ranges.h>
+#include <__assert>
#include <__config>
+#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
#include <__utility/swap.h>
+#include <concepts>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -27,36 +33,41 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
-template <class _ForwardIterator>
-inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator
-shift_right(_ForwardIterator __first,
- _ForwardIterator __last,
- typename iterator_traits<_ForwardIterator>::difference_type __n) {
+template <class _AlgPolicy, class _Iter, class _Sent>
+_LIBCPP_HIDE_FROM_ABI constexpr pair<_Iter, _Iter>
+__shift_right(_Iter __first, _Sent __last, typename _IterOps<_AlgPolicy>::template __difference_type<_Iter> __n) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n >= 0, "n must be greater than or equal to 0");
+ _Iter __end = _IterOps<_AlgPolicy>::next(__first, __last);
if (__n == 0) {
- return __first;
+ return pair<_Iter, _Iter>(std::move(__first), std::move(__end));
}
- if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
- decltype(__n) __d = __last - __first;
- if (__n >= __d) {
- return __last;
+ using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iter>;
+
+ if constexpr (derived_from<_IterCategory, random_access_iterator_tag>) {
+ auto __size = __end - __first;
+ if (__n >= __size) {
+ return pair<_Iter, _Iter>(__end, std::move(__end));
}
- _ForwardIterator __m = __first + (__d - __n);
- return std::move_backward(__first, __m, __last);
- } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) {
- _ForwardIterator __m = __last;
+ _Iter __m = __first;
+ _IterOps<_AlgPolicy>::advance(__m, (__size - __n));
+ auto __ret = std::__move_backward<_AlgPolicy>(std::move(__first), std::move(__m), __end);
+ return pair<_Iter, _Iter>(std::move(__ret.second), std::move(__end));
+ } else if constexpr (derived_from<_IterCategory, bidirectional_iterator_tag>) {
+ _Iter __m = __end;
for (; __n > 0; --__n) {
if (__m == __first) {
- return __last;
+ return pair<_Iter, _Iter>(__end, std::move(__end));
}
--__m;
}
- return std::move_backward(__first, __m, __last);
+ auto __ret = std::__move_backward<_AlgPolicy>(std::move(__first), std::move(__m), __end);
+ return pair<_Iter, _Iter>(std::move(__ret.second), std::move(__end));
} else {
- _ForwardIterator __ret = __first;
+ _Iter __ret = __first;
for (; __n > 0; --__n) {
- if (__ret == __last) {
- return __last;
+ if (__ret == __end) {
+ return pair<_Iter, _Iter>(__end, std::move(__end));
}
++__ret;
}
@@ -64,28 +75,28 @@ shift_right(_ForwardIterator __first,
// We have an __n-element scratch space from __first to __ret.
// Slide an __n-element window [__trail, __lead) from left to right.
// We're essentially doing swap_ranges(__first, __ret, __trail, __lead)
- // over and over; but once __lead reaches __last we needn't bother
- // to save the values of elements [__trail, __last).
+ // over and over; but once __lead reaches __end we needn't bother
+ // to save the values of elements [__trail, __end).
auto __trail = __first;
auto __lead = __ret;
while (__trail != __ret) {
- if (__lead == __last) {
- std::move(__first, __trail, __ret);
- return __ret;
+ if (__lead == __end) {
+ std::__move<_AlgPolicy>(std::move(__first), std::move(__trail), __ret);
+ return pair<_Iter, _Iter>(__ret, std::move(__end));
}
++__trail;
++__lead;
}
- _ForwardIterator __mid = __first;
+ _Iter __mid = __first;
while (true) {
- if (__lead == __last) {
- __trail = std::move(__mid, __ret, __trail);
- std::move(__first, __mid, __trail);
- return __ret;
+ if (__lead == __end) {
+ __trail = std::__move<_AlgPolicy>(__mid, __ret, __trail).second;
+ std::__move<_AlgPolicy>(std::move(__first), std::move(__mid), std::move(__trail));
+ return pair<_Iter, _Iter>(__ret, std::move(__end));
}
- swap(*__mid, *__trail);
+ _IterOps<_AlgPolicy>::iter_swap(__mid, __trail);
++__mid;
++__trail;
++__lead;
@@ -96,6 +107,14 @@ shift_right(_ForwardIterator __first,
}
}
+template <class _ForwardIterator>
+_LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator
+shift_right(_ForwardIterator __first,
+ _ForwardIterator __last,
+ typename iterator_traits<_ForwardIterator>::difference_type __n) {
+ return std::__shift_right<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __n).first;
+}
+
#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 64e9fa6306145..1cdbe76287dea 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -1489,6 +1489,13 @@ template<class ForwardIterator>
shift_right(ForwardIterator first, ForwardIterator last,
typename iterator_traits<ForwardIterator>::difference_type n); // C++20
+ template<permutable I, sentinel_for<I> S>
+ constexpr subrange<I> ranges::shift_right(I first, S last, iter_difference_t<I> n); // since C++23
+
+ template<forward_range R>
+ requires permutable<iterator_t<R>>
+ constexpr borrowed_subrange_t<R> ranges::shift_right(R&& r, range_difference_t<R> n) // since C++23
+
template <class InputIterator, class Predicate>
constexpr bool // constexpr since C++20
is_partitioned(InputIterator first, InputIterator last, Predicate pred);
@@ -2035,6 +2042,7 @@ template <class BidirectionalIterator, class Compare>
# include <__algorithm/ranges_ends_with.h>
# include <__algorithm/ranges_find_last.h>
# include <__algorithm/ranges_fold.h>
+# include <__algorithm/ranges_shift_right.h>
# include <__algorithm/ranges_starts_with.h>
# endif // _LIBCPP_STD_VER >= 23
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 62f928667bbd6..307c562a9a5d2 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -760,6 +760,9 @@ module std [system] {
export std.functional.ranges_operations
export std.algorithm.in_in_out_result
}
+ module ranges_shift_right {
+ header "__algorithm/ranges_shift_right.h"
+ }
module ranges_shuffle {
header "__algorithm/ranges_shuffle.h"
}
diff --git a/libcxx/include/version b/libcxx/include/version
index 7d77677a012ce..562538c5393cc 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -236,7 +236,8 @@ __cpp_lib_shared_ptr_arrays 201707L <memory>
201611L // C++17
__cpp_lib_shared_ptr_weak_type 201606L <memory>
__cpp_lib_shared_timed_mutex 201402L <shared_mutex>
-__cpp_lib_shift 201806L <algorithm>
+__cpp_lib_shift 202202L <algorithm>
+ 201806L // C++20
__cpp_lib_smart_ptr_for_overwrite 202002L <memory>
__cpp_lib_smart_ptr_owner_equality 202306L <memory>
__cpp_lib_source_location 201907L <source_location>
@@ -533,6 +534,8 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_ranges_to_container 202202L
# define __cpp_lib_ranges_zip 202110L
// # define __cpp_lib_reference_from_temporary 202202L
+# undef __cpp_lib_shift
+# define __cpp_lib_shift 202202L
// # define __cpp_lib_spanstream 202106L
// # define __cpp_lib_stacktrace 202011L
# define __cpp_lib_stdatomic_h 202011L
diff --git a/libcxx/modules/std/algorithm.inc b/libcxx/modules/std/algorithm.inc
index 95c05f01e5562..768de4bc1dba2 100644
--- a/libcxx/modules/std/algorithm.inc
+++ b/libcxx/modules/std/algorithm.inc
@@ -362,9 +362,11 @@ export namespace std {
using std::shift_right;
+ #if _LIBCPP_STD_VER >= 23
namespace ranges {
- // using std::ranges::shift_right;
+ using std::ranges::shift_right;
}
+ #endif // _LIBCPP_STD_VER >= 23
// [alg.sorting], sorting and related operations
// [alg.sort], sorting
diff --git a/libcxx/test/libcxx/algorithms/alg.modifying.operations/alg.shift/assert.shift_right.pass.cpp b/libcxx/test/libcxx/algorithms/alg.modifying.operations/alg.shift/assert.shift_right.pass.cpp
new file mode 100644
index 0000000000000..0a49a82276c48
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.modifying.operations/alg.shift/assert.shift_right.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <algorithm>
+#include <array>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::array<int, 5> arr = {1, 2, 3, 4, 5};
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::shift_right(arr, -2), "n must be greater than or equal to 0");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::shift_right(arr.begin(), arr.end(), -2), "n must be greater than or equal to 0");
+
+ return 0;
+}
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.shift/ranges_shift_right.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.shift/ranges_shift_right.pass.cpp
new file mode 100644
index 0000000000000..48bb35f4b4589
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.shift/ranges_shift_right.pass.cpp
@@ -0,0 +1,307 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=9000000
+
+// <algorithm>
+
+// template<permutable I, sentinel_for<I> S>
+// constexpr subrange<I> ranges::shift_right(I first, S last, iter_difference_t<I> n);
+
+// template<forward_range R>
+// requires permutable<iterator_t<R>>
+// constexpr borrowed_subrange_t<R> ranges::shift_right(R&& r, range_difference_t<R> n)
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <ranges>
+#include <vector>
+
+#include "almost_satisfies_types.h"
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "MoveOnly.h"
+
+struct InvalidDifferenceT {};
+
+template <class Iter, class Sent = Iter, class N = std::iter_difference_t<Iter>>
+concept HasShiftRightIt = requires(Iter iter, Sent sent, N n) { std::ranges::shift_right(iter, sent, n); };
+
+static_assert(HasShiftRightIt<int*>);
+static_assert(HasShiftRightIt<int*, sentinel_wrapper<int*>>);
+static_assert(HasShiftRightIt<int*, sized_sentinel<int*>>);
+static_assert(!HasShiftRightIt<int*, int*, InvalidDifferenceT>);
+static_assert(!HasShiftRightIt<int*, int, int>);
+
+static_assert(!HasShiftRightIt<ForwardIteratorNotDerivedFrom>);
+static_assert(!HasShiftRightIt<PermutableNotForwardIterator>);
+static_assert(!HasShiftRightIt<PermutableNotSwappable>);
+
+template <class Range, class N = std::ranges::range_difference_t<Range>>
+concept HasShiftRightR = requires(Range range, N n) { std::ranges::shift_right(range, n); };
+
+static_assert(HasShiftRightR<UncheckedRange<int*>>);
+static_assert(!HasShiftRightR<UncheckedRange<int*>, InvalidDifferenceT>);
+
+static_assert(!HasShiftRightR<ForwardRangeNotDerivedFrom>);
+static_assert(!HasShiftRightR<PermutableRangeNotForwardIterator>);
+static_assert(!HasShiftRightR<PermutableRangeNotSwappable>);
+
+struct TrackCopyMove {
+ mutable int copy_count = 0;
+ int move_count = 0;
+
+ constexpr TrackCopyMove() = default;
+ constexpr TrackCopyMove(const TrackCopyMove& other) : copy_count(other.copy_count), move_count(other.move_count) {
+ ++copy_count;
+ ++other.copy_count;
+ }
+
+ constexpr TrackCopyMove(TrackCopyMove&& other) noexcept : copy_count(other.copy_count), move_count(other.move_count) {
+ ++move_count;
+ ++other.move_count;
+ }
+ constexpr TrackCopyMove& operator=(const TrackCopyMove& other) {
+ ++copy_count;
+ ++other.copy_count;
+ return *this;
+ }
+ constexpr TrackCopyMove& operator=(TrackCopyMove&& other) noexcept {
+ ++move_count;
+ ++other.move_count;
+ return *this;...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
91e088f to
eb6ff07
Compare
ldionne
reviewed
Jan 28, 2026
ldionne
requested changes
Feb 6, 2026
ldionne
approved these changes
Feb 13, 2026
| auto __ret = std::__move_backward<_AlgPolicy>(std::move(__first), std::move(__m), __end); | ||
| return pair<_Iter, _Iter>(std::move(__ret.second), std::move(__end)); | ||
| } else if constexpr (derived_from<_IterCategory, bidirectional_iterator_tag>) { | ||
| _Iter __end = _IterOps<_AlgPolicy>::next(__first, __last); |
Member
There was a problem hiding this comment.
It's kinda sad that next doesn't return the number of positions it incremented by: otherwise we could skip the call to distance that follows, and we could do that check even for non-sized-sentinel.
Member
Author
There was a problem hiding this comment.
Hmm, it depends on whether iterator and sentinel are the same type. If they are the same, next simply return the __last without doing any increments
manasij7479
pushed a commit
to manasij7479/llvm-project
that referenced
this pull request
Feb 18, 2026
Implement the `ranges::shift_right` algorithm from [P2440R1](https://wg21.link/P2440R1). Fixes llvm#134062 Fixes llvm#105184
HendrikHuebner
pushed a commit
to HendrikHuebner/llvm-project
that referenced
this pull request
Mar 10, 2026
Implement the `ranges::shift_right` algorithm from [P2440R1](https://wg21.link/P2440R1). Fixes llvm#134062 Fixes llvm#105184
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implement the
ranges::shift_rightalgorithm from P2440R1.Fixes #134062
Fixes #105184