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#include "type_algorithms.h"
31
32template <class Iter>
33struct Test {
34 template <class Policy>
35 void operator()(Policy&& policy) {
36 { // simple test
37 int in[] = {1, 2, 3, 4};
38 int out[std::size(in)];
39
40 decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in + 2), Iter(in + 4), Iter(out));
41 static_assert(std::is_same_v<decltype(ret), Iter>);
42 assert(base(ret) == out + 4);
43
44 int expected[] = {3, 4, 1, 2};
45 assert(std::equal(out, out + 4, expected));
46 }
47 { // rotating an empty range works
48 std::array<int, 0> in = {};
49 std::array<int, 0> out = {};
50
51 decltype(auto) ret =
52 std::rotate_copy(policy, Iter(in.data()), Iter(in.data()), Iter(in.data()), Iter(out.data()));
53 static_assert(std::is_same_v<decltype(ret), Iter>);
54 assert(base(ret) == out.data());
55 }
56 { // rotating an single-element range works
57 int in[] = {1};
58 int out[std::size(in)];
59
60 decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in), Iter(in + 1), Iter(out));
61 static_assert(std::is_same_v<decltype(ret), Iter>);
62 assert(base(ret) == out + 1);
63
64 int expected[] = {1};
65 assert(std::equal(out, out + 1, expected));
66 }
67 { // rotating a two-element range works
68 int in[] = {1, 2};
69 int out[std::size(in)];
70
71 decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in + 1), Iter(in + 2), Iter(out));
72 static_assert(std::is_same_v<decltype(ret), Iter>);
73 assert(base(ret) == out + 2);
74
75 int expected[] = {2, 1};
76 assert(std::equal(out, out + 2, expected));
77 }
78 { // rotating a large range works
79 std::vector<int> data(100);
80 std::iota(first: data.begin(), last: data.end(), value: 0);
81 for (int i = 0; i != 100; ++i) { // check all permutations
82 auto copy = data;
83 std::vector<int> out(100);
84 std::rotate_copy(Iter(data.data()), Iter(data.data() + i), Iter(data.data() + data.size()), Iter(out.data()));
85 assert(out[0] == i);
86 assert(std::adjacent_find(out.begin(), out.end(), [](int lhs, int rhs) {
87 return lhs == 99 ? rhs != 0 : lhs != rhs - 1;
88 }) == out.end());
89 assert(copy == data);
90 }
91 }
92 }
93};
94
95int main(int, char**) {
96 types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{});
97
98 return 0;
99}
100

source code of libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/pstl.rotate_copy.pass.cpp