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 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 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 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 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> 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 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 constexpr bool test() { 166 test_range(); 167 168 test_iterators<cpp20_input_iterator<int*>, cpp20_input_iterator<int*>>(); 169 test_iterators<cpp20_input_iterator<int*>, forward_iterator<int*>>(); 170 test_iterators<cpp20_input_iterator<int*>, bidirectional_iterator<int*>>(); 171 test_iterators<cpp20_input_iterator<int*>, random_access_iterator<int*>>(); 172 test_iterators<cpp20_input_iterator<int*>, int*>(); 173 174 test_iterators<forward_iterator<int*>, cpp20_input_iterator<int*>>(); 175 test_iterators<forward_iterator<int*>, forward_iterator<int*>>(); 176 test_iterators<forward_iterator<int*>, bidirectional_iterator<int*>>(); 177 test_iterators<forward_iterator<int*>, random_access_iterator<int*>>(); 178 test_iterators<forward_iterator<int*>, int*>(); 179 180 test_iterators<bidirectional_iterator<int*>, cpp20_input_iterator<int*>>(); 181 test_iterators<bidirectional_iterator<int*>, forward_iterator<int*>>(); 182 test_iterators<bidirectional_iterator<int*>, bidirectional_iterator<int*>>(); 183 test_iterators<bidirectional_iterator<int*>, random_access_iterator<int*>>(); 184 test_iterators<bidirectional_iterator<int*>, int*>(); 185 186 test_iterators<random_access_iterator<int*>, cpp20_input_iterator<int*>>(); 187 test_iterators<random_access_iterator<int*>, forward_iterator<int*>>(); 188 test_iterators<random_access_iterator<int*>, bidirectional_iterator<int*>>(); 189 test_iterators<random_access_iterator<int*>, random_access_iterator<int*>>(); 190 test_iterators<random_access_iterator<int*>, int*>(); 191 192 test_iterators<int*, cpp20_input_iterator<int*>>(); 193 test_iterators<int*, forward_iterator<int*>>(); 194 test_iterators<int*, bidirectional_iterator<int*>>(); 195 test_iterators<int*, random_access_iterator<int*>>(); 196 test_iterators<int*, int*>(); 197 198 test_sentinel(); 199 test_different_lengths(); 200 test_borrowed_input_range(); 201 test_rval_range(); 202 203 return true; 204 } 205 206 static_assert(std::same_as<std::ranges::swap_ranges_result<int, char>, std::ranges::in_in_result<int, char>>); 207 208 int main(int, char**) { 209 test(); 210 static_assert(test()); 211 212 return 0; 213 } 214