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