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