diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp index 93090ed6138f8..85557ecbbfabc 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/ranges.swap_ranges.pass.cpp @@ -30,108 +30,40 @@ #include "test_iterators.h" #include "type_algorithms.h" -constexpr void test_different_lengths() { - using Expected = std::ranges::swap_ranges_result; - int i[3] = {1, 2, 3}; - int j[1] = {4}; - std::same_as auto r = std::ranges::swap_ranges(i, i + 3, j, j + 1); - assert(r.in1 == i + 1); - assert(r.in2 == j + 1); - assert(std::ranges::equal(i, std::array{4, 2, 3})); - assert(std::ranges::equal(j, std::array{1})); - std::same_as auto r2 = std::ranges::swap_ranges(i, j); - assert(r2.in1 == i + 1); - assert(r2.in2 == j + 1); - assert(std::ranges::equal(i, std::array{1, 2, 3})); - assert(std::ranges::equal(j, std::array{4})); - std::same_as auto r3 = std::ranges::swap_ranges(j, j + 1, i, i + 3); - assert(r3.in1 == j + 1); - assert(r3.in2 == i + 1); - assert(std::ranges::equal(i, std::array{4, 2, 3})); - assert(std::ranges::equal(j, std::array{1})); - std::same_as auto r4 = std::ranges::swap_ranges(j, i); - assert(r4.in1 == j + 1); - assert(r4.in2 == i + 1); - assert(std::ranges::equal(i, std::array{1, 2, 3})); - assert(std::ranges::equal(j, std::array{4})); -} - -constexpr void test_range() { - std::array r1 = {1, 2, 3}; - std::array r2 = {4, 5, 6}; - - std::same_as::iterator, std::array::iterator>> auto r = - std::ranges::swap_ranges(r1, r2); - assert(r.in1 == r1.end()); - assert(r.in2 == r2.end()); - assert((r1 == std::array{4, 5, 6})); - assert((r2 == std::array{1, 2, 3})); -} - -constexpr void test_borrowed_input_range() { - { - int r1[] = {1, 2, 3}; - int r2[] = {4, 5, 6}; - std::ranges::swap_ranges(std::views::all(r1), r2); - assert(std::ranges::equal(r1, std::array{4, 5, 6})); - assert(std::ranges::equal(r2, std::array{1, 2, 3})); - } - { - int r1[] = {1, 2, 3}; - int r2[] = {4, 5, 6}; - std::ranges::swap_ranges(r1, std::views::all(r2)); - assert(std::ranges::equal(r1, std::array{4, 5, 6})); - assert(std::ranges::equal(r2, std::array{1, 2, 3})); - } - { - int r1[] = {1, 2, 3}; - int r2[] = {4, 5, 6}; - std::ranges::swap_ranges(std::views::all(r1), std::views::all(r2)); - assert(std::ranges::equal(r1, std::array{4, 5, 6})); - assert(std::ranges::equal(r2, std::array{1, 2, 3})); - } -} - -constexpr void test_sentinel() { - int i[3] = {1, 2, 3}; - int j[3] = {4, 5, 6}; - using It = cpp17_input_iterator; - using Sent = sentinel_wrapper; - using Expected = std::ranges::swap_ranges_result; - std::same_as auto r = std::ranges::swap_ranges(It(i), Sent(It(i + 3)), It(j), Sent(It(j + 3))); - assert(base(r.in1) == i + 3); - assert(base(r.in2) == j + 3); - assert(std::ranges::equal(i, std::array{4, 5, 6})); - assert(std::ranges::equal(j, std::array{1, 2, 3})); -} - template TEST_CONSTEXPR_CXX20 void test_iterators() { using Expected = std::ranges::swap_ranges_result; - int a[3] = {1, 2, 3}; - int b[3] = {4, 5, 6}; - std::same_as auto r = - std::ranges::swap_ranges(Iter1(a), sentinel_wrapper(Iter1(a + 3)), Iter2(b), sentinel_wrapper(Iter2(b + 3))); - assert(base(r.in1) == a + 3); - assert(base(r.in2) == b + 3); - assert(std::ranges::equal(a, std::array{4, 5, 6})); - assert(std::ranges::equal(b, std::array{1, 2, 3})); -} - -constexpr void test_rval_range() { - { - using Expected = std::ranges::swap_ranges_result::iterator, std::ranges::dangling>; - std::array r = {1, 2, 3}; - std::same_as auto a = std::ranges::swap_ranges(r, std::array{4, 5, 6}); - assert((r == std::array{4, 5, 6})); - assert(a.in1 == r.begin() + 3); + { // Basic test case: swapping three elements between two arrays + int a[3] = {1, 2, 3}; + int b[3] = {4, 5, 6}; + std::same_as auto r = + std::ranges::swap_ranges(Iter1(a), sentinel_wrapper(Iter1(a + 3)), Iter2(b), sentinel_wrapper(Iter2(b + 3))); + assert(base(r.in1) == a + 3); + assert(base(r.in2) == b + 3); + assert(std::ranges::equal(a, std::array{4, 5, 6})); + assert(std::ranges::equal(b, std::array{1, 2, 3})); } - { - std::array r = {1, 2, 3}; - using Expected = std::ranges::swap_ranges_result::iterator>; - std::same_as auto b = std::ranges::swap_ranges(std::array{4, 5, 6}, r); - assert((r == std::array{4, 5, 6})); - assert(b.in2 == r.begin() + 3); + { // Large-scale test: swapping 100 elements between two different containers + const int N = 100; + std::array a; + std::vector b(N + 2, 42); + b.front() = 1; + b.back() = -1; + for (int i = 0; i < N; ++i) + a[i] = i * i + 1; + std::same_as auto r = std::ranges::swap_ranges( + Iter1(a.data()), + sentinel_wrapper(Iter1(a.data() + N)), + Iter2(b.data() + 1), + sentinel_wrapper(Iter2(b.data() + b.size()))); + assert(base(r.in1) == a.data() + N); + assert(base(r.in2) == b.data() + N + 1); + assert(b.front() == 1); // Ensure that the unswapped portion remains unchanged + assert(b.back() == -1); + for (int i = 0; i < N; ++i) { + assert(a[i] == 42); + assert(b[i + 1] == i * i + 1); + } } } @@ -152,11 +84,97 @@ constexpr void test_vector_bool() { } constexpr bool test() { - test_range(); - test_sentinel(); - test_different_lengths(); - test_borrowed_input_range(); - test_rval_range(); + { // Validate swapping ranges directly + std::array r1 = {1, 2, 3}; + std::array r2 = {4, 5, 6}; + + std::same_as::iterator, std::array::iterator>> auto r = + std::ranges::swap_ranges(r1, r2); + assert(r.in1 == r1.end()); + assert(r.in2 == r2.end()); + assert((r1 == std::array{4, 5, 6})); + assert((r2 == std::array{1, 2, 3})); + } + + { // Validate swapping ranges using iterator and sentinels + int i[3] = {1, 2, 3}; + int j[3] = {4, 5, 6}; + using It = cpp17_input_iterator; + using Sent = sentinel_wrapper; + using Expected = std::ranges::swap_ranges_result; + std::same_as auto r = std::ranges::swap_ranges(It(i), Sent(It(i + 3)), It(j), Sent(It(j + 3))); + assert(base(r.in1) == i + 3); + assert(base(r.in2) == j + 3); + assert(std::ranges::equal(i, std::array{4, 5, 6})); + assert(std::ranges::equal(j, std::array{1, 2, 3})); + } + + { // Validate swapping ranges of different lengths + using Expected = std::ranges::swap_ranges_result; + int i[3] = {1, 2, 3}; + int j[1] = {4}; + std::same_as auto r = std::ranges::swap_ranges(i, i + 3, j, j + 1); + assert(r.in1 == i + 1); + assert(r.in2 == j + 1); + assert(std::ranges::equal(i, std::array{4, 2, 3})); + assert(std::ranges::equal(j, std::array{1})); + std::same_as auto r2 = std::ranges::swap_ranges(i, j); + assert(r2.in1 == i + 1); + assert(r2.in2 == j + 1); + assert(std::ranges::equal(i, std::array{1, 2, 3})); + assert(std::ranges::equal(j, std::array{4})); + std::same_as auto r3 = std::ranges::swap_ranges(j, j + 1, i, i + 3); + assert(r3.in1 == j + 1); + assert(r3.in2 == i + 1); + assert(std::ranges::equal(i, std::array{4, 2, 3})); + assert(std::ranges::equal(j, std::array{1})); + std::same_as auto r4 = std::ranges::swap_ranges(j, i); + assert(r4.in1 == j + 1); + assert(r4.in2 == i + 1); + assert(std::ranges::equal(i, std::array{1, 2, 3})); + assert(std::ranges::equal(j, std::array{4})); + } + + { // Validate swapping when one or both are borrowed input ranges (views) + { + int r1[] = {1, 2, 3}; + int r2[] = {4, 5, 6}; + std::ranges::swap_ranges(std::views::all(r1), r2); + assert(std::ranges::equal(r1, std::array{4, 5, 6})); + assert(std::ranges::equal(r2, std::array{1, 2, 3})); + } + { + int r1[] = {1, 2, 3}; + int r2[] = {4, 5, 6}; + std::ranges::swap_ranges(r1, std::views::all(r2)); + assert(std::ranges::equal(r1, std::array{4, 5, 6})); + assert(std::ranges::equal(r2, std::array{1, 2, 3})); + } + { + int r1[] = {1, 2, 3}; + int r2[] = {4, 5, 6}; + std::ranges::swap_ranges(std::views::all(r1), std::views::all(r2)); + assert(std::ranges::equal(r1, std::array{4, 5, 6})); + assert(std::ranges::equal(r2, std::array{1, 2, 3})); + } + } + + { // Validate swapping involving rvalue ranges + { + using Expected = std::ranges::swap_ranges_result::iterator, std::ranges::dangling>; + std::array r = {1, 2, 3}; + std::same_as auto a = std::ranges::swap_ranges(r, std::array{4, 5, 6}); + assert((r == std::array{4, 5, 6})); + assert(a.in1 == r.begin() + 3); + } + { + std::array r = {1, 2, 3}; + using Expected = std::ranges::swap_ranges_result::iterator>; + std::same_as auto b = std::ranges::swap_ranges(std::array{4, 5, 6}, r); + assert((r == std::array{4, 5, 6})); + assert(b.in2 == r.begin() + 3); + } + } types::for_each(types::cpp20_input_iterator_list(), []() { types::for_each(types::cpp20_input_iterator_list(), []() { diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/swap_ranges.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/swap_ranges.pass.cpp index 01cd33150e236..84ebedf213f5b 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/swap_ranges.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/swap_ranges.pass.cpp @@ -35,12 +35,31 @@ struct TestPtr { struct TestImpl { template TEST_CONSTEXPR_CXX20 void operator()() { - int a[] = {1, 2, 3}; - int b[] = {4, 5, 6}; - Iter2 r = std::swap_ranges(Iter1(a), Iter1(a + 3), Iter2(b)); - assert(base(r) == b + 3); - assert(a[0] == 4 && a[1] == 5 && a[2] == 6); - assert(b[0] == 1 && b[1] == 2 && b[2] == 3); + { // Basic test case: swapping three elements between two arrays + int a[] = {1, 2, 3}; + int b[] = {4, 5, 6}; + Iter2 r = std::swap_ranges(Iter1(a), Iter1(a + 3), Iter2(b)); + assert(base(r) == b + 3); + assert(a[0] == 4 && a[1] == 5 && a[2] == 6); + assert(b[0] == 1 && b[1] == 2 && b[2] == 3); + } + { // Large-scale test: swapping 100 elements between two different containers + const int N = 100; + std::array a; + std::vector b(N + 2, 42); + b.front() = 1; + b.back() = -1; + for (int i = 0; i < N; ++i) + a[i] = i * i + 1; + Iter2 r = std::swap_ranges(Iter1(a.data()), Iter1(a.data() + N), Iter2(b.data() + 1)); + assert(base(r) == b.data() + N + 1); + assert(b.front() == 1); // Ensure that the unswapped portion remains unchanged + assert(b.back() == -1); + for (int i = 0; i < N; ++i) { + assert(a[i] == 42); + assert(b[i + 1] == i * i + 1); + } + } } }; };