[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
Sat Feb 8 18:40:42 PST 2025


https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/121138

>From 9cc07fd86d24a01480c2220a4f9a9616461f2671 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/3] 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 35659572dfef0f28146f1414be4527872bc27431 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/3] 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 fbc75391ebcd1d2d7ac81dee246d895f4bb18c34 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/3] 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;
 }



More information about the libcxx-commits mailing list