xref: /llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate_copy.pass.cpp (revision 3ed89b51da38f081fedb57727076262abb81d149)
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 // template<ForwardIterator InIter, OutputIterator<auto, InIter::reference> OutIter>
12 //   constexpr OutIter          // constexpr after C++17
13 //   rotate_copy(InIter first, InIter middle, InIter last, OutIter result);
14 
15 // Older compilers don't support std::is_constant_evaluated
16 // UNSUPPORTED: clang-4, clang-5, clang-6, clang-7, clang-8
17 // UNSUPPORTED: apple-clang-9, apple-clang-10
18 
19 #include <algorithm>
20 #include <cassert>
21 
22 #include "test_macros.h"
23 #include "test_iterators.h"
24 
25 
26 template <class InIter, class OutIter>
27 TEST_CONSTEXPR_CXX20 void test() {
28   int ia[] = {0, 1, 2, 3};
29   const unsigned sa = sizeof(ia) / sizeof(ia[0]);
30   int ib[sa] = {0};
31 
32   OutIter r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia), OutIter(ib));
33   assert(base(r) == ib);
34 
35   r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia + 1), OutIter(ib));
36   assert(base(r) == ib + 1);
37   assert(ib[0] == 0);
38 
39   r = std::rotate_copy(InIter(ia), InIter(ia + 1), InIter(ia + 1), OutIter(ib));
40   assert(base(r) == ib + 1);
41   assert(ib[0] == 0);
42 
43   r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia + 2), OutIter(ib));
44   assert(base(r) == ib + 2);
45   assert(ib[0] == 0);
46   assert(ib[1] == 1);
47 
48   r = std::rotate_copy(InIter(ia), InIter(ia + 1), InIter(ia + 2), OutIter(ib));
49   assert(base(r) == ib + 2);
50   assert(ib[0] == 1);
51   assert(ib[1] == 0);
52 
53   r = std::rotate_copy(InIter(ia), InIter(ia + 2), InIter(ia + 2), OutIter(ib));
54   assert(base(r) == ib + 2);
55   assert(ib[0] == 0);
56   assert(ib[1] == 1);
57 
58   r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia + 3), OutIter(ib));
59   assert(base(r) == ib + 3);
60   assert(ib[0] == 0);
61   assert(ib[1] == 1);
62   assert(ib[2] == 2);
63 
64   r = std::rotate_copy(InIter(ia), InIter(ia + 1), InIter(ia + 3), OutIter(ib));
65   assert(base(r) == ib + 3);
66   assert(ib[0] == 1);
67   assert(ib[1] == 2);
68   assert(ib[2] == 0);
69 
70   r = std::rotate_copy(InIter(ia), InIter(ia + 2), InIter(ia + 3), OutIter(ib));
71   assert(base(r) == ib + 3);
72   assert(ib[0] == 2);
73   assert(ib[1] == 0);
74   assert(ib[2] == 1);
75 
76   r = std::rotate_copy(InIter(ia), InIter(ia + 3), InIter(ia + 3), OutIter(ib));
77   assert(base(r) == ib + 3);
78   assert(ib[0] == 0);
79   assert(ib[1] == 1);
80   assert(ib[2] == 2);
81 
82   r = std::rotate_copy(InIter(ia), InIter(ia), InIter(ia + 4), OutIter(ib));
83   assert(base(r) == ib + 4);
84   assert(ib[0] == 0);
85   assert(ib[1] == 1);
86   assert(ib[2] == 2);
87   assert(ib[3] == 3);
88 
89   r = std::rotate_copy(InIter(ia), InIter(ia + 1), InIter(ia + 4), OutIter(ib));
90   assert(base(r) == ib + 4);
91   assert(ib[0] == 1);
92   assert(ib[1] == 2);
93   assert(ib[2] == 3);
94   assert(ib[3] == 0);
95 
96   r = std::rotate_copy(InIter(ia), InIter(ia + 2), InIter(ia + 4), OutIter(ib));
97   assert(base(r) == ib + 4);
98   assert(ib[0] == 2);
99   assert(ib[1] == 3);
100   assert(ib[2] == 0);
101   assert(ib[3] == 1);
102 
103   r = std::rotate_copy(InIter(ia), InIter(ia + 3), InIter(ia + 4), OutIter(ib));
104   assert(base(r) == ib + 4);
105   assert(ib[0] == 3);
106   assert(ib[1] == 0);
107   assert(ib[2] == 1);
108   assert(ib[3] == 2);
109 
110   r = std::rotate_copy(InIter(ia), InIter(ia + 4), InIter(ia + 4), OutIter(ib));
111   assert(base(r) == ib + 4);
112   assert(ib[0] == 0);
113   assert(ib[1] == 1);
114   assert(ib[2] == 2);
115   assert(ib[3] == 3);
116 
117   {
118     int ints[] = {1, 3, 5, 2, 5, 6};
119     int const n_ints = sizeof(ints)/sizeof(int);
120     int zeros[n_ints] = {0};
121 
122     const size_t N = 2;
123     const auto middle = std::begin(ints) + N;
124     auto it = std::rotate_copy(std::begin(ints), middle, std::end(ints), std::begin(zeros));
125     assert(std::distance(std::begin(zeros), it) == n_ints);
126     assert(std::equal(std::begin(ints), middle, std::begin(zeros) + n_ints - N));
127     assert(std::equal(middle, std::end(ints), std::begin(zeros)));
128   }
129 }
130 
131 TEST_CONSTEXPR_CXX20 bool all_tests() {
132   test<bidirectional_iterator<const int*>, output_iterator<int*> >();
133   test<bidirectional_iterator<const int*>, forward_iterator<int*> >();
134   test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
135   test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
136   test<bidirectional_iterator<const int*>, int*>();
137 
138   test<random_access_iterator<const int*>, output_iterator<int*> >();
139   test<random_access_iterator<const int*>, forward_iterator<int*> >();
140   test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
141   test<random_access_iterator<const int*>, random_access_iterator<int*> >();
142   test<random_access_iterator<const int*>, int*>();
143 
144   test<const int*, output_iterator<int*> >();
145   test<const int*, forward_iterator<int*> >();
146   test<const int*, bidirectional_iterator<int*> >();
147   test<const int*, random_access_iterator<int*> >();
148   test<const int*, int*>();
149 
150   return true;
151 }
152 
153 int main(int, char**) {
154   all_tests();
155 
156 #if TEST_STD_VER > 17
157   static_assert(all_tests());
158 #endif
159   return 0;
160 }
161