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 // UNSUPPORTED: c++03, c++11, c++14, c++17
12 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
13
14 // template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2>
15 // requires indirectly_swappable<I1, I2>
16 // constexpr ranges::swap_ranges_result<I1, I2>
17 // ranges::swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2);
18 // template<input_range R1, input_range R2>
19 // requires indirectly_swappable<iterator_t<R1>, iterator_t<R2>>
20 // constexpr ranges::swap_ranges_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
21 // ranges::swap_ranges(R1&& r1, R2&& r2);
22
23 #include <algorithm>
24 #include <array>
25 #include <cassert>
26 #include <ranges>
27
28 #include "test_iterators.h"
29
test_different_lengths()30 constexpr void test_different_lengths() {
31 using Expected = std::ranges::swap_ranges_result<int*, int*>;
32 int i[3] = {1, 2, 3};
33 int j[1] = {4};
34 std::same_as<Expected> auto r = std::ranges::swap_ranges(i, i + 3, j, j + 1);
35 assert(r.in1 == i + 1);
36 assert(r.in2 == j + 1);
37 assert(i[0] == 4);
38 assert(i[1] == 2);
39 assert(i[2] == 3);
40 assert(j[0] == 1);
41 std::same_as<Expected> auto r2 = std::ranges::swap_ranges(i, j);
42 assert(r2.in1 == i + 1);
43 assert(r2.in2 == j + 1);
44 assert(i[0] == 1);
45 assert(i[1] == 2);
46 assert(i[2] == 3);
47 assert(j[0] == 4);
48 std::same_as<Expected> auto r3 = std::ranges::swap_ranges(j, j + 1, i, i + 3);
49 assert(r3.in1 == j + 1);
50 assert(r3.in2 == i + 1);
51 assert(i[0] == 4);
52 assert(i[1] == 2);
53 assert(i[2] == 3);
54 assert(j[0] == 1);
55 std::same_as<Expected> auto r4 = std::ranges::swap_ranges(j, i);
56 assert(r4.in1 == j + 1);
57 assert(r4.in2 == i + 1);
58 assert(i[0] == 1);
59 assert(i[1] == 2);
60 assert(i[2] == 3);
61 assert(j[0] == 4);
62 }
63
test_range()64 constexpr void test_range() {
65 std::array r1 = {1, 2, 3};
66 std::array r2 = {4, 5, 6};
67
68
69 std::same_as<std::ranges::in_in_result<int*, int*>> auto r = std::ranges::swap_ranges(r1, r2);
70 assert(r.in1 == r1.end());
71 assert(r.in2 == r2.end());
72
73 assert((r1 == std::array{4, 5, 6}));
74 assert((r2 == std::array{1, 2, 3}));
75 }
76
test_borrowed_input_range()77 constexpr void test_borrowed_input_range() {
78 {
79 int r1[] = {1, 2, 3};
80 int r2[] = {4, 5, 6};
81 std::ranges::swap_ranges(std::views::all(r1), r2);
82 assert(r1[0] == 4);
83 assert(r1[1] == 5);
84 assert(r1[2] == 6);
85 assert(r2[0] == 1);
86 assert(r2[1] == 2);
87 assert(r2[2] == 3);
88 }
89 {
90 int r1[] = {1, 2, 3};
91 int r2[] = {4, 5, 6};
92 std::ranges::swap_ranges(r1, std::views::all(r2));
93 assert(r1[0] == 4);
94 assert(r1[1] == 5);
95 assert(r1[2] == 6);
96 assert(r2[0] == 1);
97 assert(r2[1] == 2);
98 assert(r2[2] == 3);
99 }
100 {
101 int r1[] = {1, 2, 3};
102 int r2[] = {4, 5, 6};
103 std::ranges::swap_ranges(std::views::all(r1), std::views::all(r2));
104 assert(r1[0] == 4);
105 assert(r1[1] == 5);
106 assert(r1[2] == 6);
107 assert(r2[0] == 1);
108 assert(r2[1] == 2);
109 assert(r2[2] == 3);
110 }
111 }
112
test_sentinel()113 constexpr void test_sentinel() {
114 int i[3] = {1, 2, 3};
115 int j[3] = {4, 5, 6};
116 using It = cpp17_input_iterator<int*>;
117 using Sent = sentinel_wrapper<It>;
118 using Expected = std::ranges::swap_ranges_result<It, It>;
119 std::same_as<Expected> auto r =
120 std::ranges::swap_ranges(It(i), Sent(It(i + 3)), It(j), Sent(It(j + 3)));
121 assert(base(r.in1) == i + 3);
122 assert(base(r.in2) == j + 3);
123 assert(i[0] == 4);
124 assert(i[1] == 5);
125 assert(i[2] == 6);
126 assert(j[0] == 1);
127 assert(j[1] == 2);
128 assert(j[2] == 3);
129 }
130
131 template <class Iter1, class Iter2>
test_iterators()132 constexpr void test_iterators() {
133 using Expected = std::ranges::swap_ranges_result<Iter1, Iter2>;
134 int i[3] = {1, 2, 3};
135 int j[3] = {4, 5, 6};
136 std::same_as<Expected> auto r =
137 std::ranges::swap_ranges(Iter1(i), sentinel_wrapper(Iter1(i + 3)), Iter2(j), sentinel_wrapper(Iter2(j + 3)));
138 assert(base(r.in1) == i + 3);
139 assert(base(r.in2) == j + 3);
140 assert(i[0] == 4);
141 assert(i[1] == 5);
142 assert(i[2] == 6);
143 assert(j[0] == 1);
144 assert(j[1] == 2);
145 assert(j[2] == 3);
146 }
147
test_rval_range()148 constexpr void test_rval_range() {
149 {
150 using Expected = std::ranges::swap_ranges_result<int*, std::ranges::dangling>;
151 std::array<int, 3> r = {1, 2, 3};
152 std::same_as<Expected> auto a = std::ranges::swap_ranges(r, std::array{4, 5, 6});
153 assert((r == std::array{4, 5, 6}));
154 assert(a.in1 == r.begin() + 3);
155 }
156 {
157 std::array<int, 3> r = {1, 2, 3};
158 using Expected = std::ranges::swap_ranges_result<std::ranges::dangling, int*>;
159 std::same_as<Expected> auto b = std::ranges::swap_ranges(std::array{4, 5, 6}, r);
160 assert((r == std::array{4, 5, 6}));
161 assert(b.in2 == r.begin() + 3);
162 }
163 }
164
165 template <class Out>
test_proxy_in_iterators()166 constexpr void test_proxy_in_iterators() {
167 test_iterators<ProxyIterator<cpp20_input_iterator<int*>>, Out>();
168 test_iterators<ProxyIterator<forward_iterator<int*>>, Out>();
169 test_iterators<ProxyIterator<bidirectional_iterator<int*>>, Out>();
170 test_iterators<ProxyIterator<random_access_iterator<int*>>, Out>();
171 test_iterators<ProxyIterator<contiguous_iterator<int*>>, Out>();
172 }
173
test()174 constexpr bool test() {
175 test_range();
176
177 test_iterators<cpp20_input_iterator<int*>, cpp20_input_iterator<int*>>();
178 test_iterators<cpp20_input_iterator<int*>, forward_iterator<int*>>();
179 test_iterators<cpp20_input_iterator<int*>, bidirectional_iterator<int*>>();
180 test_iterators<cpp20_input_iterator<int*>, random_access_iterator<int*>>();
181 test_iterators<cpp20_input_iterator<int*>, int*>();
182
183 test_iterators<forward_iterator<int*>, cpp20_input_iterator<int*>>();
184 test_iterators<forward_iterator<int*>, forward_iterator<int*>>();
185 test_iterators<forward_iterator<int*>, bidirectional_iterator<int*>>();
186 test_iterators<forward_iterator<int*>, random_access_iterator<int*>>();
187 test_iterators<forward_iterator<int*>, int*>();
188
189 test_iterators<bidirectional_iterator<int*>, cpp20_input_iterator<int*>>();
190 test_iterators<bidirectional_iterator<int*>, forward_iterator<int*>>();
191 test_iterators<bidirectional_iterator<int*>, bidirectional_iterator<int*>>();
192 test_iterators<bidirectional_iterator<int*>, random_access_iterator<int*>>();
193 test_iterators<bidirectional_iterator<int*>, int*>();
194
195 test_iterators<random_access_iterator<int*>, cpp20_input_iterator<int*>>();
196 test_iterators<random_access_iterator<int*>, forward_iterator<int*>>();
197 test_iterators<random_access_iterator<int*>, bidirectional_iterator<int*>>();
198 test_iterators<random_access_iterator<int*>, random_access_iterator<int*>>();
199 test_iterators<random_access_iterator<int*>, int*>();
200
201 test_iterators<int*, cpp20_input_iterator<int*>>();
202 test_iterators<int*, forward_iterator<int*>>();
203 test_iterators<int*, bidirectional_iterator<int*>>();
204 test_iterators<int*, random_access_iterator<int*>>();
205 test_iterators<int*, int*>();
206
207 test_proxy_in_iterators<ProxyIterator<cpp20_input_iterator<int*>>>();
208 test_proxy_in_iterators<ProxyIterator<forward_iterator<int*>>>();
209 test_proxy_in_iterators<ProxyIterator<bidirectional_iterator<int*>>>();
210 test_proxy_in_iterators<ProxyIterator<random_access_iterator<int*>>>();
211 test_proxy_in_iterators<ProxyIterator<contiguous_iterator<int*>>>();
212
213 test_sentinel();
214 test_different_lengths();
215 test_borrowed_input_range();
216 test_rval_range();
217
218 return true;
219 }
220
221 static_assert(std::same_as<std::ranges::swap_ranges_result<int, char>, std::ranges::in_in_result<int, char>>);
222
main(int,char **)223 int main(int, char**) {
224 test();
225 static_assert(test());
226
227 return 0;
228 }
229