Skip to content

Commit 7747973

Browse files
committed
[libc++][ranges] implement 'ranges.shift_left.pass.cpp' to test 'ranges::shift_left.h'
1 parent 9bd0eac commit 7747973

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <algorithm>
10+
11+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
12+
13+
// template<permutable I, sentinel_for<I> S>
14+
// constexpr subrange<I> ranges::shift_left(I first, S last, iter_difference_t<I> n);
15+
16+
// template<forward_range R>
17+
// requires permutable<iterator_t<R>>
18+
// constexpr borrowed_subrange_t<R> ranges::shift_left(R&& r, range_difference_t<R> n)
19+
20+
#include <algorithm>
21+
#include <array>
22+
#include <ranges>
23+
#include <iterator>
24+
25+
#include "almost_satisfies_types.h"
26+
#include "test_iterators.h"
27+
#include "MoveOnly.h"
28+
29+
template <class Iter, class Sent = Iter, class Count = std::size_t>
30+
concept HasShiftLeftIt = requires(Iter iter, Sent sent, Count n) { std::ranges::shift_left(iter, sent, n); };
31+
32+
static_assert(HasShiftLeftIt<int*>);
33+
static_assert(!HasShiftLeftIt<ForwardIteratorNotDerivedFrom>);
34+
static_assert(!HasShiftLeftIt<PermutableNotForwardIterator>);
35+
static_assert(!HasShiftLeftIt<PermutableNotSwappable>);
36+
37+
template <class Range, class Count = std::size_t>
38+
concept HasShiftLeftR = requires(Range range, Count n) { std::ranges::shift_left(range, n); };
39+
40+
static_assert(HasShiftLeftR<UncheckedRange<int*>>);
41+
static_assert(!HasShiftLeftR<ForwardRangeNotDerivedFrom>);
42+
static_assert(!HasShiftLeftR<PermutableRangeNotForwardIterator>);
43+
static_assert(!HasShiftLeftR<PermutableRangeNotSwappable>);
44+
45+
template <class Iter, class Sent>
46+
constexpr void test_iter_sent() {
47+
{
48+
const std::array<int, 15> original = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9};
49+
std::array<int, 15> scratch;
50+
51+
// (iterator, sentinel) overload
52+
for (size_t n = 0; n <= 15; ++n) {
53+
for (size_t k = 0; k <= n + 2; ++k) {
54+
auto begin = Iter(scratch.data());
55+
auto end = Sent(Iter(scratch.data() + n));
56+
std::ranges::copy(original.begin(), original.begin() + n, begin);
57+
auto result = std::ranges::shift_left(begin, end, k);
58+
59+
assert(result.begin() == begin);
60+
if (k < n) {
61+
assert(result.end() == Iter(scratch.data() + n - k));
62+
assert(std::ranges::equal(original.begin() + k, original.begin() + n, result.begin(), result.end()));
63+
} else {
64+
assert(result.end() == begin);
65+
assert(std::ranges::equal(original.begin(), original.begin() + n, begin, end));
66+
}
67+
}
68+
}
69+
70+
// (range) overload
71+
for (size_t n = 0; n <= 15; ++n) {
72+
for (size_t k = 0; k <= n + 2; ++k) {
73+
auto begin = Iter(scratch.data());
74+
auto end = Sent(Iter(scratch.data() + n));
75+
std::ranges::copy(original.begin(), original.begin() + n, begin);
76+
auto range = std::ranges::subrange(begin, end);
77+
auto result = std::ranges::shift_left(range, k);
78+
79+
assert(result.begin() == begin);
80+
if (k < n) {
81+
assert(result.end() == Iter(scratch.data() + n - k));
82+
assert(std::ranges::equal(original.begin() + k, original.begin() + n, begin, result.end()));
83+
} else {
84+
assert(result.end() == begin);
85+
assert(std::ranges::equal(original.begin(), original.begin() + n, begin, end));
86+
}
87+
}
88+
}
89+
}
90+
91+
// n == 0
92+
{
93+
std::array<int, 3> input = {0, 1, 2};
94+
const std::array<int, 3> expected = {0, 1, 2};
95+
96+
{ // (iterator, sentinel) overload
97+
auto in = input;
98+
auto begin = Iter(in.data());
99+
auto end = Sent(Iter(in.data() + in.size()));
100+
auto result = std::ranges::shift_left(begin, end, 0);
101+
assert(std::ranges::equal(expected, result));
102+
assert(result.begin() == begin);
103+
assert(result.end() == end);
104+
}
105+
106+
{ // (range) overload
107+
auto in = input;
108+
auto begin = Iter(in.data());
109+
auto end = Sent(Iter(in.data() + in.size()));
110+
auto range = std::ranges::subrange(begin, end);
111+
auto result = std::ranges::shift_left(range, 0);
112+
assert(std::ranges::equal(expected, result));
113+
assert(result.begin() == begin);
114+
assert(result.end() == end);
115+
}
116+
}
117+
118+
// n == len
119+
{
120+
std::array<int, 3> input = {0, 1, 2};
121+
const std::array<int, 3> expected = {0, 1, 2};
122+
123+
{ // (iterator, sentinel) overload
124+
auto in = input;
125+
auto begin = Iter(in.data());
126+
auto end = Sent(Iter(in.data() + in.size()));
127+
auto result = std::ranges::shift_left(begin, end, input.size());
128+
assert(std::ranges::equal(expected, input));
129+
assert(result.begin() == begin);
130+
assert(result.end() == begin);
131+
}
132+
133+
{ // (range) overload
134+
auto in = input;
135+
auto begin = Iter(in.data());
136+
auto end = Sent(Iter(in.data() + in.size()));
137+
auto range = std::ranges::subrange(begin, end);
138+
auto result = std::ranges::shift_left(range, input.size());
139+
assert(std::ranges::equal(expected, input));
140+
assert(result.begin() == begin);
141+
assert(result.end() == begin);
142+
}
143+
}
144+
145+
// n > len
146+
{
147+
std::array<int, 3> input = {0, 1, 2};
148+
const std::array<int, 3> expected = {0, 1, 2};
149+
150+
{ // (iterator, sentinel) overload
151+
auto in = input;
152+
auto begin = Iter(in.data());
153+
auto end = Sent(Iter(in.data() + in.size()));
154+
auto result = std::ranges::shift_left(begin, end, input.size() + 1);
155+
assert(std::ranges::equal(expected, input));
156+
assert(result.begin() == begin);
157+
assert(result.end() == begin);
158+
}
159+
160+
{ // (range) overload
161+
auto in = input;
162+
auto begin = Iter(in.data());
163+
auto end = Sent(Iter(in.data() + in.size()));
164+
auto range = std::ranges::subrange(begin, end);
165+
auto result = std::ranges::shift_left(range, input.size() + 1);
166+
assert(std::ranges::equal(expected, input));
167+
assert(result.begin() == begin);
168+
assert(result.end() == begin);
169+
}
170+
}
171+
}
172+
173+
template <class Iter>
174+
constexpr void test_iter() {
175+
test_iter_sent<Iter, Iter>();
176+
test_iter_sent<Iter, sentinel_wrapper<Iter>>();
177+
test_iter_sent<Iter, sized_sentinel<Iter>>();
178+
}
179+
180+
constexpr bool test() {
181+
test_iter<forward_iterator<int*>>();
182+
test_iter<bidirectional_iterator<int*>>();
183+
test_iter<random_access_iterator<int*>>();
184+
test_iter<contiguous_iterator<int*>>();
185+
test_iter<int*>();
186+
return true;
187+
}
188+
189+
int main(int, char**) {
190+
test();
191+
static_assert(test());
192+
193+
return 0;
194+
}

0 commit comments

Comments
 (0)