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 | // UNSUPPORTED: c++03, c++11, c++14 |
10 | |
11 | // UNSUPPORTED: libcpp-has-no-incomplete-pstl |
12 | |
13 | // <algorithm> |
14 | |
15 | // template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> |
16 | // ForwardIterator2 |
17 | // rotate_copy(ExecutionPolicy&& exec, |
18 | // ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, |
19 | // ForwardIterator2 result); |
20 | |
21 | #include <algorithm> |
22 | #include <array> |
23 | #include <cassert> |
24 | #include <numeric> |
25 | #include <vector> |
26 | |
27 | #include "test_macros.h" |
28 | #include "test_execution_policies.h" |
29 | #include "test_iterators.h" |
30 | |
31 | template <class Iter> |
32 | struct Test { |
33 | template <class Policy> |
34 | void operator()(Policy&& policy) { |
35 | { // simple test |
36 | int in[] = {1, 2, 3, 4}; |
37 | int out[std::size(in)]; |
38 | |
39 | decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in + 2), Iter(in + 4), Iter(out)); |
40 | static_assert(std::is_same_v<decltype(ret), Iter>); |
41 | assert(base(ret) == out + 4); |
42 | |
43 | int expected[] = {3, 4, 1, 2}; |
44 | assert(std::equal(out, out + 4, expected)); |
45 | } |
46 | { // rotating an empty range works |
47 | std::array<int, 0> in = {}; |
48 | std::array<int, 0> out = {}; |
49 | |
50 | decltype(auto) ret = |
51 | std::rotate_copy(policy, Iter(in.data()), Iter(in.data()), Iter(in.data()), Iter(out.data())); |
52 | static_assert(std::is_same_v<decltype(ret), Iter>); |
53 | assert(base(ret) == out.data()); |
54 | } |
55 | { // rotating an single-element range works |
56 | int in[] = {1}; |
57 | int out[std::size(in)]; |
58 | |
59 | decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in), Iter(in + 1), Iter(out)); |
60 | static_assert(std::is_same_v<decltype(ret), Iter>); |
61 | assert(base(ret) == out + 1); |
62 | |
63 | int expected[] = {1}; |
64 | assert(std::equal(out, out + 1, expected)); |
65 | } |
66 | { // rotating a two-element range works |
67 | int in[] = {1, 2}; |
68 | int out[std::size(in)]; |
69 | |
70 | decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in + 1), Iter(in + 2), Iter(out)); |
71 | static_assert(std::is_same_v<decltype(ret), Iter>); |
72 | assert(base(ret) == out + 2); |
73 | |
74 | int expected[] = {2, 1}; |
75 | assert(std::equal(out, out + 2, expected)); |
76 | } |
77 | { // rotating a large range works |
78 | std::vector<int> data(100); |
79 | std::iota(first: data.begin(), last: data.end(), value: 0); |
80 | for (int i = 0; i != 100; ++i) { // check all permutations |
81 | auto copy = data; |
82 | std::vector<int> out(100); |
83 | std::rotate_copy(Iter(data.data()), Iter(data.data() + i), Iter(data.data() + data.size()), Iter(out.data())); |
84 | assert(out[0] == i); |
85 | assert(std::adjacent_find(out.begin(), out.end(), [](int lhs, int rhs) { |
86 | return lhs == 99 ? rhs != 0 : lhs != rhs - 1; |
87 | }) == out.end()); |
88 | assert(copy == data); |
89 | } |
90 | } |
91 | } |
92 | }; |
93 | |
94 | int main(int, char**) { |
95 | types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{}); |
96 | |
97 | return 0; |
98 | } |
99 | |