[libcxx-commits] [libcxx] [libc++][ranges] implement `ranges::shift_left` (PR #83231)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jan 11 01:08:31 PST 2026
================
@@ -0,0 +1,195 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// template<permutable I, sentinel_for<I> S>
+// constexpr subrange<I> ranges::shift_left(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_left(R&& r, range_difference_t<R> n)
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <ranges>
+#include <iterator>
+
+#include "almost_satisfies_types.h"
+#include "test_iterators.h"
+#include "MoveOnly.h"
+
+struct InvalidDifferenceT {};
+
+template <class Iter, class Sent = Iter, class N = std::iter_difference_t<Iter>>
+concept HasShiftLeftIt = requires(Iter iter, Sent sent, N n) { std::ranges::shift_left(iter, sent, n); };
+
+static_assert(HasShiftLeftIt<int*>);
+static_assert(HasShiftLeftIt<int*, sentinel_wrapper<int*>>);
+static_assert(HasShiftLeftIt<int*, sized_sentinel<int*>>);
+static_assert(!HasShiftLeftIt<int*, int*, InvalidDifferenceT>);
+
+static_assert(!HasShiftLeftIt<ForwardIteratorNotDerivedFrom>);
+static_assert(!HasShiftLeftIt<PermutableNotForwardIterator>);
+static_assert(!HasShiftLeftIt<PermutableNotSwappable>);
+
+template <class Range, class N = std::ranges::range_difference_t<Range>>
+concept HasShiftLeftR = requires(Range range, N n) { std::ranges::shift_left(range, n); };
+
+static_assert(HasShiftLeftR<UncheckedRange<int*>>);
+static_assert(!HasShiftLeftR<UncheckedRange<int*>, InvalidDifferenceT>);
+
+static_assert(!HasShiftLeftR<ForwardRangeNotDerivedFrom>);
+static_assert(!HasShiftLeftR<PermutableRangeNotForwardIterator>);
+static_assert(!HasShiftLeftR<PermutableRangeNotSwappable>);
+
+template <class Iter, class Sent>
+constexpr void test_iter_sent() {
+ {
+ const std::array<int, 8> original = {3, 1, 4, 1, 5, 9, 2, 6};
+ std::array<int, 8> scratch;
+
+ // (iterator, sentinel) overload
+ for (size_t n = 0; n <= original.size(); ++n) {
+ for (size_t k = 0; k <= n + 2; ++k) {
+ auto begin = Iter(scratch.data());
+ auto end = Sent(Iter(scratch.data() + n));
+ std::ranges::copy(original.begin(), original.begin() + n, begin);
+ auto result = std::ranges::shift_left(begin, end, k);
----------------
huixie90 wrote:
please test the return type of the function
```
std::same_as<std::ranges::subrange<Iter>> decltype(auto) result = ...
```
https://github.com/llvm/llvm-project/pull/83231
More information about the libcxx-commits
mailing list