1*3fbd3eafSArthur O'Dwyer //===----------------------------------------------------------------------===//
2*3fbd3eafSArthur O'Dwyer //
3*3fbd3eafSArthur O'Dwyer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*3fbd3eafSArthur O'Dwyer // See https://llvm.org/LICENSE.txt for license information.
5*3fbd3eafSArthur O'Dwyer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*3fbd3eafSArthur O'Dwyer //
7*3fbd3eafSArthur O'Dwyer //===----------------------------------------------------------------------===//
8*3fbd3eafSArthur O'Dwyer
9*3fbd3eafSArthur O'Dwyer // UNSUPPORTED: c++03, c++11, c++14, c++17
10*3fbd3eafSArthur O'Dwyer
11*3fbd3eafSArthur O'Dwyer // <algorithm>
12*3fbd3eafSArthur O'Dwyer
13*3fbd3eafSArthur O'Dwyer // template<class ForwardIterator>
14*3fbd3eafSArthur O'Dwyer // constexpr ForwardIterator
15*3fbd3eafSArthur O'Dwyer // shift_left(ForwardIterator first, ForwardIterator last,
16*3fbd3eafSArthur O'Dwyer // typename iterator_traits<ForwardIterator>::difference_type n);
17*3fbd3eafSArthur O'Dwyer
18*3fbd3eafSArthur O'Dwyer #include <algorithm>
19*3fbd3eafSArthur O'Dwyer #include <cassert>
20*3fbd3eafSArthur O'Dwyer
21*3fbd3eafSArthur O'Dwyer #include "test_macros.h"
22*3fbd3eafSArthur O'Dwyer #include "test_iterators.h"
23*3fbd3eafSArthur O'Dwyer #include "MoveOnly.h"
24*3fbd3eafSArthur O'Dwyer
25*3fbd3eafSArthur O'Dwyer template<class T, class Iter>
test()26*3fbd3eafSArthur O'Dwyer constexpr bool test()
27*3fbd3eafSArthur O'Dwyer {
28*3fbd3eafSArthur O'Dwyer int orig[] = {3,1,4,1,5, 9,2,6,5,3, 5,8,9,7,9};
29*3fbd3eafSArthur O'Dwyer T work[] = {3,1,4,1,5, 9,2,6,5,3, 5,8,9,7,9};
30*3fbd3eafSArthur O'Dwyer
31*3fbd3eafSArthur O'Dwyer for (int n = 0; n <= 15; ++n) {
32*3fbd3eafSArthur O'Dwyer for (int k = 0; k <= n+2; ++k) {
33*3fbd3eafSArthur O'Dwyer std::copy(orig, orig+n, work);
34*3fbd3eafSArthur O'Dwyer Iter it = std::shift_left(Iter(work), Iter(work+n), k);
35*3fbd3eafSArthur O'Dwyer if (0 <= k && k < n) {
36*3fbd3eafSArthur O'Dwyer assert(it == Iter(work+n-k));
37*3fbd3eafSArthur O'Dwyer assert(std::equal(orig+k, orig+n, work, work+n-k));
38*3fbd3eafSArthur O'Dwyer } else {
39*3fbd3eafSArthur O'Dwyer assert(it == Iter(work));
40*3fbd3eafSArthur O'Dwyer assert(std::equal(orig, orig+n, work, work+n));
41*3fbd3eafSArthur O'Dwyer }
42*3fbd3eafSArthur O'Dwyer }
43*3fbd3eafSArthur O'Dwyer }
44*3fbd3eafSArthur O'Dwyer
45*3fbd3eafSArthur O'Dwyer // n == 0
46*3fbd3eafSArthur O'Dwyer {
47*3fbd3eafSArthur O'Dwyer T input[] = { 0, 1, 2 };
48*3fbd3eafSArthur O'Dwyer const T expected[] = { 0, 1, 2 };
49*3fbd3eafSArthur O'Dwyer Iter b = Iter(std::begin(input));
50*3fbd3eafSArthur O'Dwyer Iter e = Iter(std::end(input));
51*3fbd3eafSArthur O'Dwyer Iter it = std::shift_left(b, e, 0);
52*3fbd3eafSArthur O'Dwyer assert(std::equal(std::begin(expected), std::end(expected), b, e));
53*3fbd3eafSArthur O'Dwyer assert(it == e);
54*3fbd3eafSArthur O'Dwyer }
55*3fbd3eafSArthur O'Dwyer
56*3fbd3eafSArthur O'Dwyer // n > 0 && n < len
57*3fbd3eafSArthur O'Dwyer {
58*3fbd3eafSArthur O'Dwyer T input[] = { 0, 1, 2 };
59*3fbd3eafSArthur O'Dwyer const T expected[] = { 1, 2 };
60*3fbd3eafSArthur O'Dwyer Iter b = Iter(std::begin(input));
61*3fbd3eafSArthur O'Dwyer Iter e = Iter(std::end(input));
62*3fbd3eafSArthur O'Dwyer Iter it = std::shift_left(b, e, 1);
63*3fbd3eafSArthur O'Dwyer assert(std::equal(std::begin(expected), std::end(expected), b, it));
64*3fbd3eafSArthur O'Dwyer }
65*3fbd3eafSArthur O'Dwyer {
66*3fbd3eafSArthur O'Dwyer T input[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
67*3fbd3eafSArthur O'Dwyer const T expected[] = { 3, 4, 5, 6, 7, 8 };
68*3fbd3eafSArthur O'Dwyer Iter b = Iter(std::begin(input));
69*3fbd3eafSArthur O'Dwyer Iter e = Iter(std::end(input));
70*3fbd3eafSArthur O'Dwyer Iter it = std::shift_left(b, e, 2);
71*3fbd3eafSArthur O'Dwyer assert(std::equal(std::begin(expected), std::end(expected), b, it));
72*3fbd3eafSArthur O'Dwyer }
73*3fbd3eafSArthur O'Dwyer {
74*3fbd3eafSArthur O'Dwyer T input[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
75*3fbd3eafSArthur O'Dwyer const T expected[] = { 7, 8 };
76*3fbd3eafSArthur O'Dwyer Iter b = Iter(std::begin(input));
77*3fbd3eafSArthur O'Dwyer Iter e = Iter(std::end(input));
78*3fbd3eafSArthur O'Dwyer Iter it = std::shift_left(b, e, 6);
79*3fbd3eafSArthur O'Dwyer assert(std::equal(std::begin(expected), std::end(expected), b, it));
80*3fbd3eafSArthur O'Dwyer }
81*3fbd3eafSArthur O'Dwyer
82*3fbd3eafSArthur O'Dwyer // n == len
83*3fbd3eafSArthur O'Dwyer {
84*3fbd3eafSArthur O'Dwyer T input[] = { 0, 1, 2 };
85*3fbd3eafSArthur O'Dwyer const T expected[] = { 0, 1, 2 };
86*3fbd3eafSArthur O'Dwyer Iter b = Iter(std::begin(input));
87*3fbd3eafSArthur O'Dwyer Iter e = Iter(std::end(input));
88*3fbd3eafSArthur O'Dwyer Iter it = std::shift_left(b, e, std::size(input));
89*3fbd3eafSArthur O'Dwyer assert(std::equal(std::begin(expected), std::end(expected), b, e));
90*3fbd3eafSArthur O'Dwyer assert(it == b);
91*3fbd3eafSArthur O'Dwyer }
92*3fbd3eafSArthur O'Dwyer
93*3fbd3eafSArthur O'Dwyer // n > len
94*3fbd3eafSArthur O'Dwyer {
95*3fbd3eafSArthur O'Dwyer T input[] = { 0, 1, 2 };
96*3fbd3eafSArthur O'Dwyer const T expected[] = { 0, 1, 2 };
97*3fbd3eafSArthur O'Dwyer Iter b = Iter(std::begin(input));
98*3fbd3eafSArthur O'Dwyer Iter e = Iter(std::end(input));
99*3fbd3eafSArthur O'Dwyer Iter it = std::shift_left(b, e, std::size(input) + 1);
100*3fbd3eafSArthur O'Dwyer assert(std::equal(std::begin(expected), std::end(expected), b, e));
101*3fbd3eafSArthur O'Dwyer assert(it == b);
102*3fbd3eafSArthur O'Dwyer }
103*3fbd3eafSArthur O'Dwyer
104*3fbd3eafSArthur O'Dwyer return true;
105*3fbd3eafSArthur O'Dwyer }
106*3fbd3eafSArthur O'Dwyer
main(int,char **)107*3fbd3eafSArthur O'Dwyer int main(int, char**)
108*3fbd3eafSArthur O'Dwyer {
109*3fbd3eafSArthur O'Dwyer test<int, forward_iterator<int*>>();
110*3fbd3eafSArthur O'Dwyer test<int, bidirectional_iterator<int*>>();
111*3fbd3eafSArthur O'Dwyer test<int, random_access_iterator<int*>>();
112*3fbd3eafSArthur O'Dwyer test<int, int*>();
113*3fbd3eafSArthur O'Dwyer test<MoveOnly, forward_iterator<MoveOnly*>>();
114*3fbd3eafSArthur O'Dwyer test<MoveOnly, bidirectional_iterator<MoveOnly*>>();
115*3fbd3eafSArthur O'Dwyer test<MoveOnly, random_access_iterator<MoveOnly*>>();
116*3fbd3eafSArthur O'Dwyer test<MoveOnly, MoveOnly*>();
117*3fbd3eafSArthur O'Dwyer
118*3fbd3eafSArthur O'Dwyer static_assert(test<int, forward_iterator<int*>>());
119*3fbd3eafSArthur O'Dwyer static_assert(test<int, bidirectional_iterator<int*>>());
120*3fbd3eafSArthur O'Dwyer static_assert(test<int, random_access_iterator<int*>>());
121*3fbd3eafSArthur O'Dwyer static_assert(test<int, int*>());
122*3fbd3eafSArthur O'Dwyer static_assert(test<MoveOnly, forward_iterator<MoveOnly*>>());
123*3fbd3eafSArthur O'Dwyer static_assert(test<MoveOnly, bidirectional_iterator<MoveOnly*>>());
124*3fbd3eafSArthur O'Dwyer static_assert(test<MoveOnly, random_access_iterator<MoveOnly*>>());
125*3fbd3eafSArthur O'Dwyer static_assert(test<MoveOnly, MoveOnly*>());
126*3fbd3eafSArthur O'Dwyer
127*3fbd3eafSArthur O'Dwyer return 0;
128*3fbd3eafSArthur O'Dwyer }
129