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