[libcxx-commits] [libcxx] [libc++][test] Refactor tests for ranges::swap_range algorithms (PR #121138)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Feb 10 10:15:52 PST 2025
https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/121138
>From 1339b3011f400175e3c76ce539d3646593345ba8 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Wed, 25 Dec 2024 18:33:05 -0500
Subject: [PATCH 1/5] Refactor tests for swap_range algorithms
---
.../alg.swap/iter_swap.pass.cpp | 43 ++--
.../alg.swap/ranges.swap_ranges.pass.cpp | 186 ++++++--------
.../alg.swap/swap_ranges.pass.cpp | 231 +++++++-----------
3 files changed, 184 insertions(+), 276 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/iter_swap.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/iter_swap.pass.cpp
index b3a9f5fc259ef7f..72485b9d7e5eb72 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/iter_swap.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/iter_swap.pass.cpp
@@ -17,28 +17,37 @@
#include <cassert>
#include "test_macros.h"
+#include "test_iterators.h"
+#include "type_algorithms.h"
-#if TEST_STD_VER > 17
-constexpr bool test_swap_constexpr()
-{
+template <class Iter1>
+struct Test {
+ template <class Iter2>
+ TEST_CONSTEXPR_CXX20 void operator()() {
int i = 1;
int j = 2;
- std::iter_swap(&i, &j);
- return i == 2 && j == 1;
+ std::iter_swap(Iter1(&i), Iter2(&j));
+ assert(i == 2 && j == 1);
+ }
+};
+
+struct TestIterators {
+ template <class Iter>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ types::for_each(types::forward_iterator_list<int*>(), Test<Iter>());
+ }
+};
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ types::for_each(types::forward_iterator_list<int*>(), TestIterators());
+ return true;
}
-#endif // TEST_STD_VER > 17
-int main(int, char**)
-{
- int i = 1;
- int j = 2;
- std::iter_swap(&i, &j);
- assert(i == 2);
- assert(j == 1);
-
-#if TEST_STD_VER > 17
- static_assert(test_swap_constexpr());
-#endif // TEST_STD_VER > 17
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 20
+ static_assert(test());
+#endif
return 0;
}
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 a8d69b2832b4626..aec0d6ad1c0e168 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
@@ -25,50 +25,42 @@
#include <ranges>
#include "test_iterators.h"
+#include "type_algorithms.h"
constexpr void test_different_lengths() {
- using Expected = std::ranges::swap_ranges_result<int*, int*>;
- int i[3] = {1, 2, 3};
- int j[1] = {4};
+ using Expected = std::ranges::swap_ranges_result<int*, int*>;
+ int i[3] = {1, 2, 3};
+ int j[1] = {4};
std::same_as<Expected> auto r = std::ranges::swap_ranges(i, i + 3, j, j + 1);
assert(r.in1 == i + 1);
assert(r.in2 == j + 1);
- assert(i[0] == 4);
- assert(i[1] == 2);
- assert(i[2] == 3);
- assert(j[0] == 1);
+ assert(std::ranges::equal(i, std::array{4, 2, 3}));
+ assert(std::ranges::equal(j, std::array{1}));
std::same_as<Expected> auto r2 = std::ranges::swap_ranges(i, j);
assert(r2.in1 == i + 1);
assert(r2.in2 == j + 1);
- assert(i[0] == 1);
- assert(i[1] == 2);
- assert(i[2] == 3);
- assert(j[0] == 4);
+ assert(std::ranges::equal(i, std::array{1, 2, 3}));
+ assert(std::ranges::equal(j, std::array{4}));
std::same_as<Expected> auto r3 = std::ranges::swap_ranges(j, j + 1, i, i + 3);
assert(r3.in1 == j + 1);
assert(r3.in2 == i + 1);
- assert(i[0] == 4);
- assert(i[1] == 2);
- assert(i[2] == 3);
- assert(j[0] == 1);
+ assert(std::ranges::equal(i, std::array{4, 2, 3}));
+ assert(std::ranges::equal(j, std::array{1}));
std::same_as<Expected> auto r4 = std::ranges::swap_ranges(j, i);
assert(r4.in1 == j + 1);
assert(r4.in2 == i + 1);
- assert(i[0] == 1);
- assert(i[1] == 2);
- assert(i[2] == 3);
- assert(j[0] == 4);
+ 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<std::ranges::in_in_result<std::array<int, 3>::iterator, std::array<int, 3>::iterator>> auto r = std::ranges::swap_ranges(r1, r2);
+ std::same_as<std::ranges::in_in_result<std::array<int, 3>::iterator, std::array<int, 3>::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}));
}
@@ -78,75 +70,79 @@ 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(r1[0] == 4);
- assert(r1[1] == 5);
- assert(r1[2] == 6);
- assert(r2[0] == 1);
- assert(r2[1] == 2);
- assert(r2[2] == 3);
+ 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(r1[0] == 4);
- assert(r1[1] == 5);
- assert(r1[2] == 6);
- assert(r2[0] == 1);
- assert(r2[1] == 2);
- assert(r2[2] == 3);
+ 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(r1[0] == 4);
- assert(r1[1] == 5);
- assert(r1[2] == 6);
- assert(r2[0] == 1);
- assert(r2[1] == 2);
- assert(r2[2] == 3);
+ 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<int*>;
- using Sent = sentinel_wrapper<It>;
- using Expected = std::ranges::swap_ranges_result<It, It>;
- std::same_as<Expected> auto r =
- std::ranges::swap_ranges(It(i), Sent(It(i + 3)), It(j), Sent(It(j + 3)));
+ int i[3] = {1, 2, 3};
+ int j[3] = {4, 5, 6};
+ using It = cpp17_input_iterator<int*>;
+ using Sent = sentinel_wrapper<It>;
+ using Expected = std::ranges::swap_ranges_result<It, It>;
+ std::same_as<Expected> 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(i[0] == 4);
- assert(i[1] == 5);
- assert(i[2] == 6);
- assert(j[0] == 1);
- assert(j[1] == 2);
- assert(j[2] == 3);
+ assert(std::ranges::equal(i, std::array{4, 5, 6}));
+ assert(std::ranges::equal(j, std::array{1, 2, 3}));
}
-template <class Iter1, class Iter2>
-constexpr void test_iterators() {
- using Expected = std::ranges::swap_ranges_result<Iter1, Iter2>;
- int i[3] = {1, 2, 3};
- int j[3] = {4, 5, 6};
- std::same_as<Expected> auto r =
- std::ranges::swap_ranges(Iter1(i), sentinel_wrapper(Iter1(i + 3)), Iter2(j), sentinel_wrapper(Iter2(j + 3)));
- assert(base(r.in1) == i + 3);
- assert(base(r.in2) == j + 3);
- assert(i[0] == 4);
- assert(i[1] == 5);
- assert(i[2] == 6);
- assert(j[0] == 1);
- assert(j[1] == 2);
- assert(j[2] == 3);
-}
+template <class Iter1>
+struct Test {
+ template <class Iter2>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ using Expected = std::ranges::swap_ranges_result<Iter1, Iter2>;
+ int a[3] = {1, 2, 3};
+ int b[3] = {4, 5, 6};
+ std::same_as<Expected> 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}));
+ }
+};
+
+struct TestIterators {
+ template <class Iter>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ types::for_each(types::cpp20_input_iterator_list<int*>(), Test<Iter>());
+ }
+};
+
+template <class Ptr>
+using cpp20_proxy_in_iterator_list =
+ types::type_list<Cpp20InputProxyIterator<Ptr>,
+ ForwardProxyIterator<Ptr>,
+ BidirectionalProxyIterator<Ptr>,
+ RandomAccessProxyIterator<Ptr>,
+ ContiguousProxyIterator<Ptr>>;
+
+struct TestProxyInIterators {
+ template <class Iter>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ types::for_each(cpp20_proxy_in_iterator_list<int*>(), Test<Iter>());
+ }
+};
constexpr void test_rval_range() {
{
- using Expected = std::ranges::swap_ranges_result<std::array<int, 3>::iterator, std::ranges::dangling>;
+ using Expected = std::ranges::swap_ranges_result<std::array<int, 3>::iterator, std::ranges::dangling>;
std::array<int, 3> r = {1, 2, 3};
std::same_as<Expected> auto a = std::ranges::swap_ranges(r, std::array{4, 5, 6});
assert((r == std::array{4, 5, 6}));
@@ -154,65 +150,21 @@ constexpr void test_rval_range() {
}
{
std::array<int, 3> r = {1, 2, 3};
- using Expected = std::ranges::swap_ranges_result<std::ranges::dangling, std::array<int, 3>::iterator>;
+ using Expected = std::ranges::swap_ranges_result<std::ranges::dangling, std::array<int, 3>::iterator>;
std::same_as<Expected> 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);
}
}
-template <class Out>
-constexpr void test_proxy_in_iterators() {
- test_iterators<ProxyIterator<cpp20_input_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<forward_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<bidirectional_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<random_access_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<contiguous_iterator<int*>>, Out>();
-}
-
constexpr bool test() {
test_range();
-
- test_iterators<cpp20_input_iterator<int*>, cpp20_input_iterator<int*>>();
- test_iterators<cpp20_input_iterator<int*>, forward_iterator<int*>>();
- test_iterators<cpp20_input_iterator<int*>, bidirectional_iterator<int*>>();
- test_iterators<cpp20_input_iterator<int*>, random_access_iterator<int*>>();
- test_iterators<cpp20_input_iterator<int*>, int*>();
-
- test_iterators<forward_iterator<int*>, cpp20_input_iterator<int*>>();
- test_iterators<forward_iterator<int*>, forward_iterator<int*>>();
- test_iterators<forward_iterator<int*>, bidirectional_iterator<int*>>();
- test_iterators<forward_iterator<int*>, random_access_iterator<int*>>();
- test_iterators<forward_iterator<int*>, int*>();
-
- test_iterators<bidirectional_iterator<int*>, cpp20_input_iterator<int*>>();
- test_iterators<bidirectional_iterator<int*>, forward_iterator<int*>>();
- test_iterators<bidirectional_iterator<int*>, bidirectional_iterator<int*>>();
- test_iterators<bidirectional_iterator<int*>, random_access_iterator<int*>>();
- test_iterators<bidirectional_iterator<int*>, int*>();
-
- test_iterators<random_access_iterator<int*>, cpp20_input_iterator<int*>>();
- test_iterators<random_access_iterator<int*>, forward_iterator<int*>>();
- test_iterators<random_access_iterator<int*>, bidirectional_iterator<int*>>();
- test_iterators<random_access_iterator<int*>, random_access_iterator<int*>>();
- test_iterators<random_access_iterator<int*>, int*>();
-
- test_iterators<int*, cpp20_input_iterator<int*>>();
- test_iterators<int*, forward_iterator<int*>>();
- test_iterators<int*, bidirectional_iterator<int*>>();
- test_iterators<int*, random_access_iterator<int*>>();
- test_iterators<int*, int*>();
-
- test_proxy_in_iterators<ProxyIterator<cpp20_input_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<forward_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<bidirectional_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<random_access_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<contiguous_iterator<int*>>>();
-
test_sentinel();
test_different_lengths();
test_borrowed_input_range();
test_rval_range();
+ types::for_each(types::cpp20_input_iterator_list<int*>(), TestIterators());
+ types::for_each(cpp20_proxy_in_iterator_list<int*>(), TestProxyInIterators());
return true;
}
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 8bfbcd755e39f74..09374b9a64bf11e 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
@@ -14,162 +14,109 @@
// swap_ranges(Iter1 first1, Iter1 last1, Iter2 first2);
#include <algorithm>
+#include <array>
#include <cassert>
#include <memory>
#include <utility>
#include "test_macros.h"
#include "test_iterators.h"
-
-template<class Iter1, class Iter2>
-void
-test()
-{
- int i[3] = {1, 2, 3};
- int j[3] = {4, 5, 6};
- Iter2 r = std::swap_ranges(Iter1(i), Iter1(i+3), Iter2(j));
- assert(base(r) == j+3);
- assert(i[0] == 4);
- assert(i[1] == 5);
- assert(i[2] == 6);
- assert(j[0] == 1);
- assert(j[1] == 2);
- assert(j[2] == 3);
+#include "type_algorithms.h"
+
+template <class Iter1>
+struct Test1 {
+ template <class Iter2>
+ 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);
+ }
+};
+
+struct TestPtr {
+ template <class Iter>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ types::for_each(types::forward_iterator_list<int*>(), Test1<Iter>());
+ }
+};
+
+TEST_CONSTEXPR_CXX20 bool test_ptr() {
+ types::for_each(types::forward_iterator_list<int*>(), TestPtr());
+ return true;
}
#if TEST_STD_VER >= 11
-template<class Iter1, class Iter2>
-void
-test1()
-{
- std::unique_ptr<int> i[3];
+template <class Iter1>
+struct Test2 {
+ template <class Iter2>
+ TEST_CONSTEXPR_CXX23 void operator()() {
+ std::unique_ptr<int> a[3];
for (int k = 0; k < 3; ++k)
- i[k].reset(new int(k+1));
- std::unique_ptr<int> j[3];
+ a[k].reset(new int(k + 1));
+ std::unique_ptr<int> b[3];
for (int k = 0; k < 3; ++k)
- j[k].reset(new int(k+4));
- Iter2 r = std::swap_ranges(Iter1(i), Iter1(i+3), Iter2(j));
- assert(base(r) == j+3);
- assert(*i[0] == 4);
- assert(*i[1] == 5);
- assert(*i[2] == 6);
- assert(*j[0] == 1);
- assert(*j[1] == 2);
- assert(*j[2] == 3);
+ b[k].reset(new int(k + 4));
+ 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);
+ }
+};
+
+struct TestUnqPtr {
+ template <class Iter>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), Test2<Iter>());
+ }
+};
+
+TEST_CONSTEXPR_CXX23 bool test_unq_ptr() {
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUnqPtr());
+ return true;
}
-#endif // TEST_STD_VER >= 11
-
-void test2()
-{
- {
- int src[2][2] = {{0, 1}, {2, 3}};
- decltype(src) dest = {{9, 8}, {7, 6}};
-
- std::swap(src, dest);
-
- assert ( src[0][0] == 9 );
- assert ( src[0][1] == 8 );
- assert ( src[1][0] == 7 );
- assert ( src[1][1] == 6 );
-
- assert ( dest[0][0] == 0 );
- assert ( dest[0][1] == 1 );
- assert ( dest[1][0] == 2 );
- assert ( dest[1][1] == 3 );
- }
-
- {
- int src[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
- decltype(src) dest = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
-
- std::swap(src, dest);
-
- assert ( src[0][0] == 9 );
- assert ( src[0][1] == 8 );
- assert ( src[0][2] == 7 );
- assert ( src[1][0] == 6 );
- assert ( src[1][1] == 5 );
- assert ( src[1][2] == 4 );
- assert ( src[2][0] == 3 );
- assert ( src[2][1] == 2 );
- assert ( src[2][2] == 1 );
-
- assert ( dest[0][0] == 0 );
- assert ( dest[0][1] == 1 );
- assert ( dest[0][2] == 2 );
- assert ( dest[1][0] == 3 );
- assert ( dest[1][1] == 4 );
- assert ( dest[1][2] == 5 );
- assert ( dest[2][0] == 6 );
- assert ( dest[2][1] == 7 );
- assert ( dest[2][2] == 8 );
- }
-}
-
-#if TEST_STD_VER > 17
-constexpr bool test_swap_constexpr()
-{
- int i[3] = {1, 2, 3};
- int j[3] = {4, 5, 6};
- std::swap_ranges(i, i+3, j);
- return i[0] == 4 &&
- i[1] == 5 &&
- i[2] == 6 &&
- j[0] == 1 &&
- j[1] == 2 &&
- j[2] == 3;
+#endif
+
+TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
+ {
+ std::array<int, 3> a = {1, 2, 3}, a0 = a;
+ std::array<int, 3> b = {4, 5, 6}, b0 = b;
+ std::swap_ranges(a.begin(), a.end(), b.begin());
+ assert(a == b0);
+ assert(b == a0);
+ }
+ {
+ std::array<std::array<int, 2>, 2> a = {{{0, 1}, {2, 3}}}, a0 = a;
+ std::array<std::array<int, 2>, 2> b = {{{9, 8}, {7, 6}}}, b0 = b;
+ std::swap(a, b);
+ assert(a == b0);
+ assert(b == a0);
+ }
+ {
+ std::array<std::array<int, 3>, 3> a = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}}, a0 = a;
+ std::array<std::array<int, 3>, 3> b = {{{9, 8, 7}, {6, 5, 4}, {3, 2, 1}}}, b0 = b;
+ std::swap(a, b);
+ assert(a == b0);
+ assert(b == a0);
+ }
+
+ return true;
}
-#endif // TEST_STD_VER > 17
-
-int main(int, char**)
-{
- test<forward_iterator<int*>, forward_iterator<int*> >();
- test<forward_iterator<int*>, bidirectional_iterator<int*> >();
- test<forward_iterator<int*>, random_access_iterator<int*> >();
- test<forward_iterator<int*>, int*>();
-
- test<bidirectional_iterator<int*>, forward_iterator<int*> >();
- test<bidirectional_iterator<int*>, bidirectional_iterator<int*> >();
- test<bidirectional_iterator<int*>, random_access_iterator<int*> >();
- test<bidirectional_iterator<int*>, int*>();
-
- test<random_access_iterator<int*>, forward_iterator<int*> >();
- test<random_access_iterator<int*>, bidirectional_iterator<int*> >();
- test<random_access_iterator<int*>, random_access_iterator<int*> >();
- test<random_access_iterator<int*>, int*>();
-
- test<int*, forward_iterator<int*> >();
- test<int*, bidirectional_iterator<int*> >();
- test<int*, random_access_iterator<int*> >();
- test<int*, int*>();
+int main(int, char**) {
+ test_simple_cases();
+ test_ptr();
#if TEST_STD_VER >= 11
- test1<forward_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();
- test1<forward_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();
- test1<forward_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();
- test1<forward_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
-
- test1<bidirectional_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();
- test1<bidirectional_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();
- test1<bidirectional_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();
- test1<bidirectional_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
-
- test1<random_access_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();
- test1<random_access_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();
- test1<random_access_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();
- test1<random_access_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();
-
- test1<std::unique_ptr<int>*, forward_iterator<std::unique_ptr<int>*> >();
- test1<std::unique_ptr<int>*, bidirectional_iterator<std::unique_ptr<int>*> >();
- test1<std::unique_ptr<int>*, random_access_iterator<std::unique_ptr<int>*> >();
- test1<std::unique_ptr<int>*, std::unique_ptr<int>*>();
-#endif // TEST_STD_VER >= 11
-
-#if TEST_STD_VER > 17
- static_assert(test_swap_constexpr());
-#endif // TEST_STD_VER > 17
-
- test2();
-
+ test_unq_ptr();
+#endif
+#if TEST_STD_VER >= 20
+ static_assert(test_simple_cases());
+ static_assert(test_ptr());
+#endif
+#if TEST_STD_VER >= 23
+ static_assert(test_unq_ptr());
+#endif
return 0;
}
>From bf5350d696fc3ce663831942211afbfc89529182 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sat, 8 Feb 2025 16:40:34 -0500
Subject: [PATCH 2/5] Further refactoring by addressing ldionne's comments
---
.../alg.swap/iter_swap.pass.cpp | 27 ++-
.../alg.swap/ranges.swap_ranges.pass.cpp | 60 +++----
.../alg.swap/swap_ranges.pass.cpp | 98 +++++------
.../utility/utility.swap/swap_array.pass.cpp | 166 ++++++++++--------
4 files changed, 176 insertions(+), 175 deletions(-)
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/iter_swap.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/iter_swap.pass.cpp
index 72485b9d7e5eb72..283832ec656ab8f 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/iter_swap.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/iter_swap.pass.cpp
@@ -10,8 +10,7 @@
// template<Iterator Iter1, Iterator Iter2>
// requires HasSwap<Iter1::reference, Iter2::reference>
-// void
-// iter_swap(Iter1 a, Iter2 b);
+// void iter_swap(Iter1 a, Iter2 b); // constexpr since C++20
#include <algorithm>
#include <cassert>
@@ -20,22 +19,22 @@
#include "test_iterators.h"
#include "type_algorithms.h"
-template <class Iter1>
-struct Test {
- template <class Iter2>
- TEST_CONSTEXPR_CXX20 void operator()() {
- int i = 1;
- int j = 2;
- std::iter_swap(Iter1(&i), Iter2(&j));
- assert(i == 2 && j == 1);
- }
-};
-
struct TestIterators {
template <class Iter>
TEST_CONSTEXPR_CXX20 void operator()() {
- types::for_each(types::forward_iterator_list<int*>(), Test<Iter>());
+ types::for_each(types::forward_iterator_list<int*>(), TestImpl<Iter>());
}
+
+ template <class Iter1>
+ struct TestImpl {
+ template <class Iter2>
+ TEST_CONSTEXPR_CXX20 void operator()() {
+ int i = 1;
+ int j = 2;
+ std::iter_swap(Iter1(&i), Iter2(&j));
+ assert(i == 2 && j == 1);
+ }
+ };
};
TEST_CONSTEXPR_CXX20 bool test() {
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 aec0d6ad1c0e168..9b61768cffd9746 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
@@ -24,6 +24,8 @@
#include <cassert>
#include <ranges>
+#include <cstdio>
+
#include "test_iterators.h"
#include "type_algorithms.h"
@@ -102,43 +104,18 @@ constexpr void test_sentinel() {
assert(std::ranges::equal(j, std::array{1, 2, 3}));
}
-template <class Iter1>
-struct Test {
- template <class Iter2>
- TEST_CONSTEXPR_CXX20 void operator()() {
- using Expected = std::ranges::swap_ranges_result<Iter1, Iter2>;
- int a[3] = {1, 2, 3};
- int b[3] = {4, 5, 6};
- std::same_as<Expected> 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}));
- }
-};
-
-struct TestIterators {
- template <class Iter>
- TEST_CONSTEXPR_CXX20 void operator()() {
- types::for_each(types::cpp20_input_iterator_list<int*>(), Test<Iter>());
- }
-};
-
-template <class Ptr>
-using cpp20_proxy_in_iterator_list =
- types::type_list<Cpp20InputProxyIterator<Ptr>,
- ForwardProxyIterator<Ptr>,
- BidirectionalProxyIterator<Ptr>,
- RandomAccessProxyIterator<Ptr>,
- ContiguousProxyIterator<Ptr>>;
-
-struct TestProxyInIterators {
- template <class Iter>
- TEST_CONSTEXPR_CXX20 void operator()() {
- types::for_each(cpp20_proxy_in_iterator_list<int*>(), Test<Iter>());
- }
-};
+template <class Iter1, class Iter2>
+TEST_CONSTEXPR_CXX20 void test_iterators() {
+ using Expected = std::ranges::swap_ranges_result<Iter1, Iter2>;
+ int a[3] = {1, 2, 3};
+ int b[3] = {4, 5, 6};
+ std::same_as<Expected> 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() {
{
@@ -163,8 +140,13 @@ constexpr bool test() {
test_different_lengths();
test_borrowed_input_range();
test_rval_range();
- types::for_each(types::cpp20_input_iterator_list<int*>(), TestIterators());
- types::for_each(cpp20_proxy_in_iterator_list<int*>(), TestProxyInIterators());
+
+ types::for_each(types::cpp20_input_iterator_list<int*>(), []<class Iter1>() {
+ types::for_each(types::cpp20_input_iterator_list<int*>(), []<class Iter2>() {
+ test_iterators<Iter1, Iter2>();
+ test_iterators<ProxyIterator<Iter1>, ProxyIterator<Iter2>>();
+ });
+ });
return true;
}
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 09374b9a64bf11e..bc6ceb752c5366c 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
@@ -23,60 +23,50 @@
#include "test_iterators.h"
#include "type_algorithms.h"
-template <class Iter1>
-struct Test1 {
- template <class Iter2>
- 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);
- }
-};
-
struct TestPtr {
template <class Iter>
TEST_CONSTEXPR_CXX20 void operator()() {
- types::for_each(types::forward_iterator_list<int*>(), Test1<Iter>());
+ types::for_each(types::forward_iterator_list<int*>(), TestPtrImpl<Iter>());
}
-};
-TEST_CONSTEXPR_CXX20 bool test_ptr() {
- types::for_each(types::forward_iterator_list<int*>(), TestPtr());
- return true;
-}
-
-#if TEST_STD_VER >= 11
-template <class Iter1>
-struct Test2 {
- template <class Iter2>
- TEST_CONSTEXPR_CXX23 void operator()() {
- std::unique_ptr<int> a[3];
- for (int k = 0; k < 3; ++k)
- a[k].reset(new int(k + 1));
- std::unique_ptr<int> b[3];
- for (int k = 0; k < 3; ++k)
- b[k].reset(new int(k + 4));
- 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);
- }
+ template <class Iter1>
+ struct TestPtrImpl {
+ template <class Iter2>
+ 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);
+ }
+ };
};
-struct TestUnqPtr {
+#if TEST_STD_VER >= 11
+struct TestUniquePtr {
template <class Iter>
TEST_CONSTEXPR_CXX20 void operator()() {
- types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), Test2<Iter>());
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtrImpl<Iter>());
}
-};
-TEST_CONSTEXPR_CXX23 bool test_unq_ptr() {
- types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUnqPtr());
- return true;
-}
+ template <class Iter1>
+ struct TestUniquePtrImpl {
+ template <class Iter2>
+ TEST_CONSTEXPR_CXX23 void operator()() {
+ std::unique_ptr<int> a[3];
+ for (int k = 0; k < 3; ++k)
+ a[k].reset(new int(k + 1));
+ std::unique_ptr<int> b[3];
+ for (int k = 0; k < 3; ++k)
+ b[k].reset(new int(k + 4));
+ 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);
+ }
+ };
+};
#endif
TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
@@ -90,14 +80,14 @@ TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
{
std::array<std::array<int, 2>, 2> a = {{{0, 1}, {2, 3}}}, a0 = a;
std::array<std::array<int, 2>, 2> b = {{{9, 8}, {7, 6}}}, b0 = b;
- std::swap(a, b);
+ std::swap_ranges(a.begin(), a.end(), b.begin());
assert(a == b0);
assert(b == a0);
}
{
std::array<std::array<int, 3>, 3> a = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}}, a0 = a;
std::array<std::array<int, 3>, 3> b = {{{9, 8, 7}, {6, 5, 4}, {3, 2, 1}}}, b0 = b;
- std::swap(a, b);
+ std::swap_ranges(a.begin(), a.end(), b.begin());
assert(a == b0);
assert(b == a0);
}
@@ -105,18 +95,20 @@ TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX20 bool tests() {
test_simple_cases();
- test_ptr();
+ types::for_each(types::forward_iterator_list<int*>(), TestPtr());
#if TEST_STD_VER >= 11
- test_unq_ptr();
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
#endif
+ return true;
+}
+
+int main(int, char**) {
+ tests();
#if TEST_STD_VER >= 20
- static_assert(test_simple_cases());
- static_assert(test_ptr());
-#endif
-#if TEST_STD_VER >= 23
- static_assert(test_unq_ptr());
+ static_assert(tests());
#endif
+
return 0;
}
diff --git a/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp b/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
index 3d562ddd3fc61c5..a64d69754b7bd83 100644
--- a/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
+++ b/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
@@ -10,8 +10,7 @@
// template<ValueType T, size_t N>
// requires Swappable<T>
-// void
-// swap(T (&a)[N], T (&b)[N]);
+// void swap(T (&a)[N], T (&b)[N]); // constexpr since C++20
#include <algorithm>
#include <cassert>
@@ -21,26 +20,23 @@
#include "test_macros.h"
-
#if TEST_STD_VER >= 11
struct CopyOnly {
- CopyOnly() {}
- CopyOnly(CopyOnly const&) noexcept {}
- CopyOnly& operator=(CopyOnly const&) { return *this; }
+ TEST_CONSTEXPR_CXX20 CopyOnly() {}
+ TEST_CONSTEXPR_CXX20 CopyOnly(CopyOnly const&) noexcept {}
+ TEST_CONSTEXPR_CXX20 CopyOnly& operator=(CopyOnly const&) { return *this; }
};
-
struct NoexceptMoveOnly {
- NoexceptMoveOnly() {}
- NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
- NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
+ TEST_CONSTEXPR_CXX20 NoexceptMoveOnly() {}
+ TEST_CONSTEXPR_CXX20 NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
+ TEST_CONSTEXPR_CXX20 NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
};
struct NotMoveConstructible {
- NotMoveConstructible() {}
- NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
-private:
- NotMoveConstructible(NotMoveConstructible&&);
+ TEST_CONSTEXPR_CXX20 NotMoveConstructible() {}
+ TEST_CONSTEXPR_CXX20 NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
+ NotMoveConstructible(NotMoveConstructible&&) = delete;
};
template <class Tp>
@@ -51,71 +47,103 @@ auto can_swap_test(...) -> std::false_type;
template <class Tp>
constexpr bool can_swap() {
- return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
+ return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
}
#endif
-#if TEST_STD_VER > 17
-constexpr bool test_swap_constexpr()
-{
+TEST_CONSTEXPR_CXX20 bool test() {
+ {
int i[3] = {1, 2, 3};
int j[3] = {4, 5, 6};
std::swap(i, j);
- return i[0] == 4 &&
- i[1] == 5 &&
- i[2] == 6 &&
- j[0] == 1 &&
- j[1] == 2 &&
- j[2] == 3;
-}
-#endif // TEST_STD_VER > 17
-
-int main(int, char**)
-{
- {
- int i[3] = {1, 2, 3};
- int j[3] = {4, 5, 6};
- std::swap(i, j);
- assert(i[0] == 4);
- assert(i[1] == 5);
- assert(i[2] == 6);
- assert(j[0] == 1);
- assert(j[1] == 2);
- assert(j[2] == 3);
- }
+ assert(i[0] == 4);
+ assert(i[1] == 5);
+ assert(i[2] == 6);
+ assert(j[0] == 1);
+ assert(j[1] == 2);
+ assert(j[2] == 3);
+ }
+ {
+ int a[2][2] = {{0, 1}, {2, 3}};
+ decltype(a) b = {{9, 8}, {7, 6}};
+
+ std::swap(a, b);
+
+ assert(a[0][0] == 9);
+ assert(a[0][1] == 8);
+ assert(a[1][0] == 7);
+ assert(a[1][1] == 6);
+
+ assert(b[0][0] == 0);
+ assert(b[0][1] == 1);
+ assert(b[1][0] == 2);
+ assert(b[1][1] == 3);
+ }
+
+ {
+ int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
+ decltype(a) b = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
+
+ std::swap(a, b);
+
+ assert(a[0][0] == 9);
+ assert(a[0][1] == 8);
+ assert(a[0][2] == 7);
+ assert(a[1][0] == 6);
+ assert(a[1][1] == 5);
+ assert(a[1][2] == 4);
+ assert(a[2][0] == 3);
+ assert(a[2][1] == 2);
+ assert(a[2][2] == 1);
+
+ assert(b[0][0] == 0);
+ assert(b[0][1] == 1);
+ assert(b[0][2] == 2);
+ assert(b[1][0] == 3);
+ assert(b[1][1] == 4);
+ assert(b[1][2] == 5);
+ assert(b[2][0] == 6);
+ assert(b[2][1] == 7);
+ assert(b[2][2] == 8);
+ }
#if TEST_STD_VER >= 11
- {
- std::unique_ptr<int> i[3];
- for (int k = 0; k < 3; ++k)
- i[k].reset(new int(k+1));
- std::unique_ptr<int> j[3];
- for (int k = 0; k < 3; ++k)
- j[k].reset(new int(k+4));
- std::swap(i, j);
- assert(*i[0] == 4);
- assert(*i[1] == 5);
- assert(*i[2] == 6);
- assert(*j[0] == 1);
- assert(*j[1] == 2);
- assert(*j[2] == 3);
- }
- {
- using CA = CopyOnly[42];
- using MA = NoexceptMoveOnly[42];
- using NA = NotMoveConstructible[42];
- static_assert(can_swap<CA&>(), "");
- static_assert(can_swap<MA&>(), "");
- static_assert(!can_swap<NA&>(), "");
-
- CA ca;
- MA ma;
- static_assert(!noexcept(std::swap(ca, ca)), "");
- static_assert(noexcept(std::swap(ma, ma)), "");
- }
+ {
+ std::unique_ptr<int> i[3];
+ for (int k = 0; k < 3; ++k)
+ i[k].reset(new int(k + 1));
+ std::unique_ptr<int> j[3];
+ for (int k = 0; k < 3; ++k)
+ j[k].reset(new int(k + 4));
+ std::swap(i, j);
+ assert(*i[0] == 4);
+ assert(*i[1] == 5);
+ assert(*i[2] == 6);
+ assert(*j[0] == 1);
+ assert(*j[1] == 2);
+ assert(*j[2] == 3);
+ }
+ {
+ using CA = CopyOnly[42];
+ using MA = NoexceptMoveOnly[42];
+ using NA = NotMoveConstructible[42];
+ static_assert(can_swap<CA&>(), "");
+ static_assert(can_swap<MA&>(), "");
+ static_assert(!can_swap<NA&>(), "");
+
+ CA ca;
+ MA ma;
+ static_assert(!noexcept(std::swap(ca, ca)), "");
+ static_assert(noexcept(std::swap(ma, ma)), "");
+ }
#endif
+ return true;
+}
+
+int main(int, char**) {
+ test();
#if TEST_STD_VER > 17
- static_assert(test_swap_constexpr());
+ static_assert(test());
#endif // TEST_STD_VER > 17
return 0;
>From c27f0e38ddee79c56ff05379bca5e9163e7862de Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sat, 8 Feb 2025 21:40:09 -0500
Subject: [PATCH 3/5] Run constexpr test with unique_ptr only since C++23
---
.../alg.swap/swap_ranges.pass.cpp | 31 ++++++++-----
.../utility/utility.swap/swap_array.pass.cpp | 45 ++++++++++++-------
2 files changed, 48 insertions(+), 28 deletions(-)
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 bc6ceb752c5366c..44d8a7ef75f7402 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
@@ -26,11 +26,11 @@
struct TestPtr {
template <class Iter>
TEST_CONSTEXPR_CXX20 void operator()() {
- types::for_each(types::forward_iterator_list<int*>(), TestPtrImpl<Iter>());
+ types::for_each(types::forward_iterator_list<int*>(), TestImpl<Iter>());
}
template <class Iter1>
- struct TestPtrImpl {
+ struct TestImpl {
template <class Iter2>
TEST_CONSTEXPR_CXX20 void operator()() {
int a[] = {1, 2, 3};
@@ -46,12 +46,12 @@ struct TestPtr {
#if TEST_STD_VER >= 11
struct TestUniquePtr {
template <class Iter>
- TEST_CONSTEXPR_CXX20 void operator()() {
- types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtrImpl<Iter>());
+ TEST_CONSTEXPR_CXX23 void operator()() {
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestImpl<Iter>());
}
template <class Iter1>
- struct TestUniquePtrImpl {
+ struct TestImpl {
template <class Iter2>
TEST_CONSTEXPR_CXX23 void operator()() {
std::unique_ptr<int> a[3];
@@ -67,6 +67,12 @@ struct TestUniquePtr {
}
};
};
+
+// This test is constexpr only since C++23 because constexpr std::unique_ptr is only available since C++23
+TEST_CONSTEXPR_CXX23 bool test_unique_ptr() {
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
+ return true;
+}
#endif
TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
@@ -95,19 +101,22 @@ TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
return true;
}
-TEST_CONSTEXPR_CXX20 bool tests() {
+TEST_CONSTEXPR_CXX20 bool test() {
test_simple_cases();
types::for_each(types::forward_iterator_list<int*>(), TestPtr());
-#if TEST_STD_VER >= 11
- types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
-#endif
return true;
}
int main(int, char**) {
- tests();
+ test();
+#if TEST_STD_VER >= 11
+ test_unique_ptr();
+#endif
#if TEST_STD_VER >= 20
- static_assert(tests());
+ static_assert(test());
+#endif
+#if TEST_STD_VER >= 23
+ static_assert(test_unique_ptr());
#endif
return 0;
diff --git a/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp b/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
index a64d69754b7bd83..3491f0ed48e6e28 100644
--- a/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
+++ b/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
@@ -51,6 +51,26 @@ constexpr bool can_swap() {
}
#endif
+#if TEST_STD_VER >= 11
+// This test is constexpr only since C++23 because constexpr std::unique_ptr is only available since C++23
+TEST_CONSTEXPR_CXX23 bool test_unique_ptr() {
+ std::unique_ptr<int> i[3];
+ for (int k = 0; k < 3; ++k)
+ i[k].reset(new int(k + 1));
+ std::unique_ptr<int> j[3];
+ for (int k = 0; k < 3; ++k)
+ j[k].reset(new int(k + 4));
+ std::swap(i, j);
+ assert(*i[0] == 4);
+ assert(*i[1] == 5);
+ assert(*i[2] == 6);
+ assert(*j[0] == 1);
+ assert(*j[1] == 2);
+ assert(*j[2] == 3);
+ return true;
+}
+#endif
+
TEST_CONSTEXPR_CXX20 bool test() {
{
int i[3] = {1, 2, 3};
@@ -107,21 +127,6 @@ TEST_CONSTEXPR_CXX20 bool test() {
assert(b[2][2] == 8);
}
#if TEST_STD_VER >= 11
- {
- std::unique_ptr<int> i[3];
- for (int k = 0; k < 3; ++k)
- i[k].reset(new int(k + 1));
- std::unique_ptr<int> j[3];
- for (int k = 0; k < 3; ++k)
- j[k].reset(new int(k + 4));
- std::swap(i, j);
- assert(*i[0] == 4);
- assert(*i[1] == 5);
- assert(*i[2] == 6);
- assert(*j[0] == 1);
- assert(*j[1] == 2);
- assert(*j[2] == 3);
- }
{
using CA = CopyOnly[42];
using MA = NoexceptMoveOnly[42];
@@ -142,9 +147,15 @@ TEST_CONSTEXPR_CXX20 bool test() {
int main(int, char**) {
test();
-#if TEST_STD_VER > 17
+#if TEST_STD_VER >= 11
+ test_unique_ptr();
+#endif
+#if TEST_STD_VER >= 20
static_assert(test());
-#endif // TEST_STD_VER > 17
+#endif
+#if TEST_STD_VER >= 23
+ static_assert(test_unique_ptr());
+#endif
return 0;
}
>From d9b0723cae8b0fbb34719ac338458100ad196dee Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sun, 9 Feb 2025 23:09:10 -0500
Subject: [PATCH 4/5] Introduce a single top-level test() function
---
.../alg.swap/swap_ranges.pass.cpp | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
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 44d8a7ef75f7402..325b8b15ad6e4c7 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
@@ -18,6 +18,7 @@
#include <cassert>
#include <memory>
#include <utility>
+#include <__type_traits/is_constant_evaluated.h>
#include "test_macros.h"
#include "test_iterators.h"
@@ -67,12 +68,6 @@ struct TestUniquePtr {
}
};
};
-
-// This test is constexpr only since C++23 because constexpr std::unique_ptr is only available since C++23
-TEST_CONSTEXPR_CXX23 bool test_unique_ptr() {
- types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
- return true;
-}
#endif
TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
@@ -104,20 +99,25 @@ TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
TEST_CONSTEXPR_CXX20 bool test() {
test_simple_cases();
types::for_each(types::forward_iterator_list<int*>(), TestPtr());
+
+ if (std::__libcpp_is_constant_evaluated()) {
+#if TEST_STD_VER >= 23
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
+#endif
+ } else {
+#if TEST_STD_VER >= 11
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
+#endif
+ }
+
return true;
}
int main(int, char**) {
test();
-#if TEST_STD_VER >= 11
- test_unique_ptr();
-#endif
#if TEST_STD_VER >= 20
static_assert(test());
#endif
-#if TEST_STD_VER >= 23
- static_assert(test_unique_ptr());
-#endif
return 0;
}
>From cbea0f484ac53193a673bfbf7160187b750d53ec Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sun, 9 Feb 2025 23:31:40 -0500
Subject: [PATCH 5/5] Templatize test_simple_cases()
---
.../alg.swap/swap_ranges.pass.cpp | 47 ++++++++++++++-----
1 file changed, 35 insertions(+), 12 deletions(-)
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 325b8b15ad6e4c7..46ff9a0ecc16dcf 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
@@ -17,8 +17,8 @@
#include <array>
#include <cassert>
#include <memory>
+#include <type_traits>
#include <utility>
-#include <__type_traits/is_constant_evaluated.h>
#include "test_macros.h"
#include "test_iterators.h"
@@ -70,25 +70,39 @@ struct TestUniquePtr {
};
#endif
+template <template <class> class Iter1, template <class> class Iter2>
TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
+ {
+ int a[2] = {1, 2};
+ int b[2] = {4, 5};
+ std::swap_ranges(Iter1<int*>(a), Iter1<int*>(a + 2), Iter2<int*>(b));
+ assert(a[0] == 4 && a[1] == 5);
+ assert(b[0] == 1 && b[1] == 2);
+ }
{
std::array<int, 3> a = {1, 2, 3}, a0 = a;
std::array<int, 3> b = {4, 5, 6}, b0 = b;
- std::swap_ranges(a.begin(), a.end(), b.begin());
+ using It1 = Iter1<std::array<int, 3>::iterator>;
+ using It2 = Iter2<std::array<int, 3>::iterator>;
+ std::swap_ranges(It1(a.begin()), It1(a.end()), It2(b.begin()));
assert(a == b0);
assert(b == a0);
}
{
std::array<std::array<int, 2>, 2> a = {{{0, 1}, {2, 3}}}, a0 = a;
std::array<std::array<int, 2>, 2> b = {{{9, 8}, {7, 6}}}, b0 = b;
- std::swap_ranges(a.begin(), a.end(), b.begin());
+ using It1 = Iter1<std::array<std::array<int, 2>, 2>::iterator>;
+ using It2 = Iter2<std::array<std::array<int, 2>, 2>::iterator>;
+ std::swap_ranges(It1(a.begin()), It1(a.end()), It2(b.begin()));
assert(a == b0);
assert(b == a0);
}
{
std::array<std::array<int, 3>, 3> a = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}}, a0 = a;
std::array<std::array<int, 3>, 3> b = {{{9, 8, 7}, {6, 5, 4}, {3, 2, 1}}}, b0 = b;
- std::swap_ranges(a.begin(), a.end(), b.begin());
+ using It1 = Iter1<std::array<std::array<int, 3>, 3>::iterator>;
+ using It2 = Iter2<std::array<std::array<int, 3>, 3>::iterator>;
+ std::swap_ranges(It1(a.begin()), It1(a.end()), It2(b.begin()));
assert(a == b0);
assert(b == a0);
}
@@ -97,18 +111,27 @@ TEST_CONSTEXPR_CXX20 bool test_simple_cases() {
}
TEST_CONSTEXPR_CXX20 bool test() {
- test_simple_cases();
+ test_simple_cases<forward_iterator, forward_iterator>();
+ test_simple_cases<forward_iterator, bidirectional_iterator>();
+ test_simple_cases<forward_iterator, random_access_iterator>();
+ test_simple_cases<bidirectional_iterator, forward_iterator>();
+ test_simple_cases<bidirectional_iterator, bidirectional_iterator>();
+ test_simple_cases<bidirectional_iterator, random_access_iterator>();
+ test_simple_cases<random_access_iterator, random_access_iterator>();
+#if TEST_STD_VER >= 20
+ test_simple_cases<std::type_identity_t, std::type_identity_t>();
+#endif
+
types::for_each(types::forward_iterator_list<int*>(), TestPtr());
- if (std::__libcpp_is_constant_evaluated()) {
-#if TEST_STD_VER >= 23
+#if TEST_STD_VER >= 11 && TEST_STD_VER <= 17
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
+#elif TEST_STD_VER == 20
+ if (!std::is_constant_evaluated())
types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
+#elif TEST_STD_VER >= 23
+ types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
#endif
- } else {
-#if TEST_STD_VER >= 11
- types::for_each(types::forward_iterator_list<std::unique_ptr<int>*>(), TestUniquePtr());
-#endif
- }
return true;
}
More information about the libcxx-commits
mailing list