[libcxx-commits] [libcxx] [libc++][test] Refactor tests for std::{copy, move, fill} algorithms (PR #120909)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Sun Dec 22 16:00:04 PST 2024


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

>From 0348081a6e19272545cf4789156d46f53752cb45 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sun, 22 Dec 2024 10:51:48 -0500
Subject: [PATCH 1/2] Refactor tests for std::{copy, move, fill} algorithms

---
 .../alg.copy/common.h                         |  30 +++
 .../alg.copy/copy.pass.cpp                    |  53 ++---
 .../alg.copy/copy_backward.pass.cpp           |  87 +++----
 .../alg.copy/copy_if.pass.cpp                 |  83 +++----
 .../alg.copy/copy_n.pass.cpp                  | 105 +++------
 .../alg.copy/pstl.copy.pass.cpp               |   1 +
 .../alg.copy/pstl.copy_n.pass.cpp             |   3 +-
 .../alg.fill/fill.pass.cpp                    |   1 +
 .../alg.fill/fill_n.pass.cpp                  | 214 ++++++++----------
 .../alg.fill/pstl.fill.pass.cpp               |   1 +
 .../alg.fill/pstl.fill_n.pass.cpp             |   1 +
 .../alg.move/move.pass.cpp                    | 109 ++++-----
 .../alg.move/move_backward.pass.cpp           | 118 +++++-----
 .../alg.move/pstl.move.pass.cpp               |   1 +
 14 files changed, 351 insertions(+), 456 deletions(-)
 create mode 100644 libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/common.h

diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/common.h b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/common.h
new file mode 100644
index 00000000000000..562ae5121e4287
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/common.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_STD_ALGORITHMS_ALG_MODIFYING_OPERATIONS_ALG_COPY_COMMON_H
+#define TEST_STD_ALGORITHMS_ALG_MODIFYING_OPERATIONS_ALG_COPY_COMMON_H
+
+#include <cstdint>
+#include "test_macros.h"
+
+class PaddedBase {
+public:
+  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
+
+  std::int16_t a_;
+  std::int8_t b_;
+};
+
+class Derived : public PaddedBase {
+public:
+  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+
+  std::int8_t c_;
+};
+
+#endif
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
index b5f0a32b986a03..e781feacb8bd93 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
@@ -15,23 +15,30 @@
 #include <algorithm>
 #include <cassert>
 
+#include "common.h"
 #include "test_macros.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 
-class PaddedBase {
-public:
-  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
-
-  std::int16_t a_;
-  std::int8_t b_;
-};
-
-class Derived : public PaddedBase {
-public:
-  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+TEST_CONSTEXPR_CXX20 void test_padding() {
+  { // Make sure that padding bits aren't copied
+    Derived src(1, 2, 3);
+    Derived dst(4, 5, 6);
+    std::copy(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst));
+    assert(dst.a_ == 1);
+    assert(dst.b_ == 2);
+    assert(dst.c_ == 6);
+  }
+}
 
-  std::int8_t c_;
-};
+TEST_CONSTEXPR_CXX20 void test_overlapping() {
+  { // Make sure that overlapping ranges can be copied
+    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    std::copy(a + 3, a + 10, a);
+    int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
+    assert(std::equal(a, a + 10, expected));
+  }
+}
 
 template <class InIter>
 struct Test {
@@ -60,23 +67,9 @@ struct TestInIters {
 };
 
 TEST_CONSTEXPR_CXX20 bool test() {
-  types::for_each(types::cpp17_input_iterator_list<int*>(), TestInIters());
-
-  { // Make sure that padding bits aren't copied
-    Derived src(1, 2, 3);
-    Derived dst(4, 5, 6);
-    std::copy(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst));
-    assert(dst.a_ == 1);
-    assert(dst.b_ == 2);
-    assert(dst.c_ == 6);
-  }
-
-  { // Make sure that overlapping ranges can be copied
-    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-    std::copy(a + 3, a + 10, a);
-    int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
-    assert(std::equal(a, a + 10, expected));
-  }
+  types::for_each(types::cpp17_input_iterator_list<const int*>(), TestInIters());
+  test_padding();
+  test_overlapping();
 
   return true;
 }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
index 928903de1ade2d..3629da78cbcc6a 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
@@ -16,69 +16,30 @@
 #include <algorithm>
 #include <cassert>
 
+#include "common.h"
 #include "test_macros.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 #include "user_defined_integral.h"
 
-class PaddedBase {
-public:
-  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
-
-  std::int16_t a_;
-  std::int8_t b_;
-};
-
-class Derived : public PaddedBase {
-public:
-  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
-
-  std::int8_t c_;
-};
-
-template <class InIter, class OutIter>
-TEST_CONSTEXPR_CXX20 void
-test_copy_backward()
-{
-  {
+template <class InIter>
+struct TestOutIters {
+  template <class OutIter>
+  TEST_CONSTEXPR_CXX20 void operator()() {
     const unsigned N = 1000;
-    int ia[N] = {};
+    int ia[N]        = {};
     for (unsigned i = 0; i < N; ++i)
-        ia[i] = i;
+      ia[i] = i;
     int ib[N] = {0};
 
-    OutIter r = std::copy_backward(InIter(ia), InIter(ia+N), OutIter(ib+N));
+    OutIter r = std::copy_backward(InIter(ia), InIter(ia + N), OutIter(ib + N));
     assert(base(r) == ib);
     for (unsigned i = 0; i < N; ++i)
-        assert(ia[i] == ib[i]);
+      assert(ia[i] == ib[i]);
   }
-}
-
-TEST_CONSTEXPR_CXX20 bool
-test()
-{
-    test_copy_backward<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_backward<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_backward<bidirectional_iterator<const int*>, int*>();
-
-    test_copy_backward<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_backward<random_access_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_backward<random_access_iterator<const int*>, int*>();
-
-    test_copy_backward<const int*, bidirectional_iterator<int*> >();
-    test_copy_backward<const int*, random_access_iterator<int*> >();
-    test_copy_backward<const int*, int*>();
-
-#if TEST_STD_VER > 17
-    test_copy_backward<contiguous_iterator<const int*>, bidirectional_iterator<int*>>();
-    test_copy_backward<contiguous_iterator<const int*>, random_access_iterator<int*>>();
-    test_copy_backward<contiguous_iterator<const int*>, int*>();
-
-    test_copy_backward<bidirectional_iterator<const int*>, contiguous_iterator<int*>>();
-    test_copy_backward<random_access_iterator<const int*>, contiguous_iterator<int*>>();
-    test_copy_backward<contiguous_iterator<const int*>, contiguous_iterator<int*>>();
-    test_copy_backward<const int*, contiguous_iterator<int*>>();
-#endif
+};
 
+TEST_CONSTEXPR_CXX20 void test_padding() {
   { // Make sure that padding bits aren't copied
     Derived src(1, 2, 3);
     Derived dst(4, 5, 6);
@@ -88,23 +49,37 @@ test()
     assert(dst.b_ == 2);
     assert(dst.c_ == 6);
   }
+}
 
+TEST_CONSTEXPR_CXX20 void test_overlapping() {
   { // Make sure that overlapping ranges can be copied
     int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     std::copy_backward(a, a + 7, a + 10);
     int expected[] = {1, 2, 3, 1, 2, 3, 4, 5, 6, 7};
     assert(std::equal(a, a + 10, expected));
   }
+}
+
+struct TestInIters {
+  template <class InIter>
+  TEST_CONSTEXPR_CXX20 void operator()() {
+    types::for_each(types::bidirectional_iterator_list<int*>(), TestOutIters<InIter>());
+  }
+};
+
+TEST_CONSTEXPR_CXX20 bool test() {
+  types::for_each(types::bidirectional_iterator_list<const int*>(), TestInIters());
+  test_padding();
+  test_overlapping();
 
-    return true;
+  return true;
 }
 
-int main(int, char**)
-{
-    test();
+int main(int, char**) {
+  test();
 
 #if TEST_STD_VER > 17
-    static_assert(test());
+  static_assert(test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
index 57214e65455b45..3bee77738e3423 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_if.pass.cpp
@@ -19,75 +19,48 @@
 
 #include "test_macros.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 
-struct Pred
-{
-    TEST_CONSTEXPR_CXX14 bool operator()(int i) {return i % 3 == 0;}
+struct Pred {
+  TEST_CONSTEXPR_CXX14 bool operator()(int i) { return i % 3 == 0; }
 };
 
-template <class InIter, class OutIter>
-TEST_CONSTEXPR_CXX20 void
-test_copy_if()
-{
+template <class InIter>
+struct TestOutIters {
+  template <class OutIter>
+  TEST_CONSTEXPR_CXX20 void operator()() {
     const unsigned N = 1000;
-    int ia[N] = {};
+    int ia[N]        = {};
     for (unsigned i = 0; i < N; ++i)
-        ia[i] = i;
+      ia[i] = i;
     int ib[N] = {0};
 
-    OutIter r = std::copy_if(InIter(ia), InIter(ia+N), OutIter(ib), Pred());
-    assert(base(r) == ib+N/3+1);
-    for (unsigned i = 0; i < N/3+1; ++i)
-        assert(ib[i] % 3 == 0);
-}
-
-TEST_CONSTEXPR_CXX20 bool
-test()
-{
-    test_copy_if<cpp17_input_iterator<const int*>, cpp17_output_iterator<int*> >();
-    test_copy_if<cpp17_input_iterator<const int*>, cpp17_input_iterator<int*> >();
-    test_copy_if<cpp17_input_iterator<const int*>, forward_iterator<int*> >();
-    test_copy_if<cpp17_input_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_if<cpp17_input_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_if<cpp17_input_iterator<const int*>, int*>();
-
-    test_copy_if<forward_iterator<const int*>, cpp17_output_iterator<int*> >();
-    test_copy_if<forward_iterator<const int*>, cpp17_input_iterator<int*> >();
-    test_copy_if<forward_iterator<const int*>, forward_iterator<int*> >();
-    test_copy_if<forward_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_if<forward_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_if<forward_iterator<const int*>, int*>();
-
-    test_copy_if<bidirectional_iterator<const int*>, cpp17_output_iterator<int*> >();
-    test_copy_if<bidirectional_iterator<const int*>, cpp17_input_iterator<int*> >();
-    test_copy_if<bidirectional_iterator<const int*>, forward_iterator<int*> >();
-    test_copy_if<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_if<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_if<bidirectional_iterator<const int*>, int*>();
-
-    test_copy_if<random_access_iterator<const int*>, cpp17_output_iterator<int*> >();
-    test_copy_if<random_access_iterator<const int*>, cpp17_input_iterator<int*> >();
-    test_copy_if<random_access_iterator<const int*>, forward_iterator<int*> >();
-    test_copy_if<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_if<random_access_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_if<random_access_iterator<const int*>, int*>();
+    OutIter r = std::copy_if(InIter(ia), InIter(ia + N), OutIter(ib), Pred());
+    assert(base(r) == ib + N / 3 + 1);
+    for (unsigned i = 0; i < N / 3 + 1; ++i)
+      assert(ib[i] % 3 == 0);
+  }
+};
 
-    test_copy_if<const int*, cpp17_output_iterator<int*> >();
-    test_copy_if<const int*, cpp17_input_iterator<int*> >();
-    test_copy_if<const int*, forward_iterator<int*> >();
-    test_copy_if<const int*, bidirectional_iterator<int*> >();
-    test_copy_if<const int*, random_access_iterator<int*> >();
-    test_copy_if<const int*, int*>();
+struct TestInIters {
+  template <class InIter>
+  TEST_CONSTEXPR_CXX20 void operator()() {
+    types::for_each(
+        types::concatenate_t<types::cpp17_input_iterator_list<int*>, types::type_list<cpp17_output_iterator<int*> > >(),
+        TestOutIters<InIter>());
+  }
+};
 
+TEST_CONSTEXPR_CXX20 bool test() {
+  types::for_each(types::cpp17_input_iterator_list<const int*>(), TestInIters());
   return true;
 }
 
-int main(int, char**)
-{
-    test();
+int main(int, char**) {
+  test();
 
 #if TEST_STD_VER > 17
-    static_assert(test());
+  static_assert(test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
index b0acc1060101c2..28362f4f990997 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
@@ -15,44 +15,15 @@
 #include <algorithm>
 #include <cassert>
 
+#include "common.h"
 #include "test_macros.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 #include "user_defined_integral.h"
 
 typedef UserDefinedIntegral<unsigned> UDI;
 
-class PaddedBase {
-public:
-  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
-
-  std::int16_t a_;
-  std::int8_t b_;
-};
-
-class Derived : public PaddedBase {
-public:
-  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
-
-  std::int8_t c_;
-};
-
-template <class InIter, class OutIter>
-TEST_CONSTEXPR_CXX20 void
-test_copy_n()
-{
-  {
-    const unsigned N = 1000;
-    int ia[N] = {};
-    for (unsigned i = 0; i < N; ++i)
-        ia[i] = i;
-    int ib[N] = {0};
-
-    OutIter r = std::copy_n(InIter(ia), UDI(N/2), OutIter(ib));
-    assert(base(r) == ib+N/2);
-    for (unsigned i = 0; i < N/2; ++i)
-        assert(ia[i] == ib[i]);
-  }
-
+TEST_CONSTEXPR_CXX20 void test_padding() {
   { // Make sure that padding bits aren't copied
     Derived src(1, 2, 3);
     Derived dst(4, 5, 6);
@@ -61,7 +32,9 @@ test_copy_n()
     assert(dst.b_ == 2);
     assert(dst.c_ == 6);
   }
+}
 
+TEST_CONSTEXPR_CXX20 void test_overlapping() {
   { // Make sure that overlapping ranges can be copied
     int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     std::copy_n(a + 3, 7, a);
@@ -70,53 +43,45 @@ test_copy_n()
   }
 }
 
-TEST_CONSTEXPR_CXX20 bool
-test()
-{
-    test_copy_n<cpp17_input_iterator<const int*>, cpp17_output_iterator<int*> >();
-    test_copy_n<cpp17_input_iterator<const int*>, cpp17_input_iterator<int*> >();
-    test_copy_n<cpp17_input_iterator<const int*>, forward_iterator<int*> >();
-    test_copy_n<cpp17_input_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_n<cpp17_input_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_n<cpp17_input_iterator<const int*>, int*>();
-
-    test_copy_n<forward_iterator<const int*>, cpp17_output_iterator<int*> >();
-    test_copy_n<forward_iterator<const int*>, cpp17_input_iterator<int*> >();
-    test_copy_n<forward_iterator<const int*>, forward_iterator<int*> >();
-    test_copy_n<forward_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_n<forward_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_n<forward_iterator<const int*>, int*>();
+template <class InIter>
+struct TestOutIters {
+  template <class OutIter>
+  TEST_CONSTEXPR_CXX20 void operator()() {
+    const unsigned N = 1000;
+    int ia[N]        = {};
+    for (unsigned i = 0; i < N; ++i)
+      ia[i] = i;
+    int ib[N] = {0};
 
-    test_copy_n<bidirectional_iterator<const int*>, cpp17_output_iterator<int*> >();
-    test_copy_n<bidirectional_iterator<const int*>, cpp17_input_iterator<int*> >();
-    test_copy_n<bidirectional_iterator<const int*>, forward_iterator<int*> >();
-    test_copy_n<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_n<bidirectional_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_n<bidirectional_iterator<const int*>, int*>();
+    OutIter r = std::copy_n(InIter(ia), UDI(N / 2), OutIter(ib));
+    assert(base(r) == ib + N / 2);
+    for (unsigned i = 0; i < N / 2; ++i)
+      assert(ia[i] == ib[i]);
+  }
+};
 
-    test_copy_n<random_access_iterator<const int*>, cpp17_output_iterator<int*> >();
-    test_copy_n<random_access_iterator<const int*>, cpp17_input_iterator<int*> >();
-    test_copy_n<random_access_iterator<const int*>, forward_iterator<int*> >();
-    test_copy_n<random_access_iterator<const int*>, bidirectional_iterator<int*> >();
-    test_copy_n<random_access_iterator<const int*>, random_access_iterator<int*> >();
-    test_copy_n<random_access_iterator<const int*>, int*>();
+struct TestInIters {
+  template <class InIter>
+  TEST_CONSTEXPR_CXX20 void operator()() {
+    types::for_each(
+        types::concatenate_t<types::cpp17_input_iterator_list<int*>, types::type_list<cpp17_output_iterator<int*> > >(),
+        TestOutIters<InIter>());
+  }
+};
 
-    test_copy_n<const int*, cpp17_output_iterator<int*> >();
-    test_copy_n<const int*, cpp17_input_iterator<int*> >();
-    test_copy_n<const int*, forward_iterator<int*> >();
-    test_copy_n<const int*, bidirectional_iterator<int*> >();
-    test_copy_n<const int*, random_access_iterator<int*> >();
-    test_copy_n<const int*, int*>();
+TEST_CONSTEXPR_CXX20 bool test() {
+  types::for_each(types::cpp17_input_iterator_list<const int*>(), TestInIters());
+  test_padding();
+  test_overlapping();
 
   return true;
 }
 
-int main(int, char**)
-{
-    test();
+int main(int, char**) {
+  test();
 
 #if TEST_STD_VER > 17
-    static_assert(test());
+  static_assert(test());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/pstl.copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/pstl.copy.pass.cpp
index bee1ef9bcec332..6229aac733a9c4 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/pstl.copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/pstl.copy.pass.cpp
@@ -23,6 +23,7 @@
 #include "test_macros.h"
 #include "test_execution_policies.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 
 EXECUTION_POLICY_SFINAE_TEST(copy);
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/pstl.copy_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/pstl.copy_n.pass.cpp
index 128108ac13811b..7208be75c70d03 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/pstl.copy_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/pstl.copy_n.pass.cpp
@@ -23,6 +23,7 @@
 #include "test_macros.h"
 #include "test_execution_policies.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 
 EXECUTION_POLICY_SFINAE_TEST(copy_n);
 
@@ -58,7 +59,7 @@ struct TestIteratorsInt {
 };
 
 struct CopiedToTester {
-  bool copied_to = false;
+  bool copied_to   = false;
   CopiedToTester() = default;
   CopiedToTester(const CopiedToTester&) {}
   CopiedToTester& operator=(const CopiedToTester&) {
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
index 619dc7242a3660..46b33d1727a716 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp
@@ -21,6 +21,7 @@
 
 #include "test_macros.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 
 template <class Iter, class Container>
 TEST_CONSTEXPR_CXX20 void
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
index 7d6770de702bf3..103976f77410b9 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
@@ -14,160 +14,138 @@
 //   fill_n(Iter first, Size n, const T& value);
 
 #include <algorithm>
+#include <array>
 #include <cassert>
+#include <cstddef>
 
 #include "test_macros.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 #include "user_defined_integral.h"
 
-#if TEST_STD_VER > 17
-TEST_CONSTEXPR bool test_constexpr() {
-    const std::size_t N = 5;
-    int ib[] = {0, 0, 0, 0, 0, 0}; // one bigger than N
-
-    auto it = std::fill_n(std::begin(ib), N, 5);
-    return it == (std::begin(ib) + N)
-        && std::all_of(std::begin(ib), it, [](int a) {return a == 5; })
-        && *it == 0 // don't overwrite the last value in the output array
-        ;
-    }
-#endif
-
 typedef UserDefinedIntegral<unsigned> UDI;
 
-template <class Iter>
-void
-test_char()
-{
-    char a[4] = {};
-    Iter it = std::fill_n(Iter(a), UDI(4), char(1));
-    assert(base(it) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
+template <class Iter, class Container>
+TEST_CONSTEXPR_CXX20 void
+test(Container& in,
+     typename Container::iterator first,
+     size_t n,
+     typename Container::value_type value,
+     const Container& expected) {
+  Iter it = std::fill_n(Iter(first), UDI(n), value);
+  assert(base(it) == first + n);
+  assert(in == expected);
 }
 
-template <class Iter>
-void
-test_int()
-{
-    int a[4] = {};
-    Iter it = std::fill_n(Iter(a), UDI(4), 1);
-    assert(base(it) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
-}
+template <class T>
+struct Test {
+  template <class Iter>
+  TEST_CONSTEXPR_CXX20 void operator()() {
+    {
+      std::array<T, 4> in       = {1, 2, 3, 4};
+      std::array<T, 4> expected = {5, 5, 5, 5};
+      test<Iter>(in, in.begin(), 4, 5, expected);
+    }
+    {
+      std::array<T, 4> in       = {1, 2, 3, 4};
+      std::array<T, 4> expected = {1, 5, 5, 4};
+      test<Iter>(in, in.begin() + 1, 2, 5, expected);
+    }
+  }
+};
 
-void
-test_int_array()
-{
+TEST_CONSTEXPR void test_int_array() {
+  {
     int a[4] = {};
     assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
-    assert(a[0] == 1);
-    assert(a[1] == 1);
-    assert(a[2] == 1);
-    assert(a[3] == 1);
+    assert(a[0] == 1 && a[1] == 1 && a[2] == 1 && a[3] == 1);
+  }
+  {
+    const std::size_t N = 5;
+    int ib[]            = {0, 0, 0, 0, 0, 0}; // one bigger than N
+
+    auto it = std::fill_n(std::begin(ib), N, 5);
+    assert(it == (std::begin(ib) + N) && std::all_of(std::begin(ib), it, [](int a) { return a == 5; }) &&
+           *it == 0 // don't overwrite the last value in the output array
+    );
+  }
 }
 
 struct source {
-    source() : i(0) { }
-
-    operator int() const { return i++; }
-    mutable int i;
+  TEST_CONSTEXPR source() = default;
+  TEST_CONSTEXPR_CXX20 operator int() const { return 1; }
 };
 
-void
-test_int_array_struct_source()
-{
-    int a[4] = {};
-    assert(std::fill_n(a, UDI(4), source()) == a + 4);
-    assert(a[0] == 0);
-    assert(a[1] == 1);
-    assert(a[2] == 2);
-    assert(a[3] == 3);
+TEST_CONSTEXPR_CXX20 void test_int_array_struct_source() {
+  int a[4] = {};
+  assert(std::fill_n(a, UDI(4), source()) == a + 4);
+  assert(a[0] == 1);
+  assert(a[1] == 1);
+  assert(a[2] == 1);
+  assert(a[3] == 1);
 }
 
-struct test1 {
-    test1() : c(0) { }
-    test1(char xc) : c(xc + 1) { }
-    char c;
-};
-
-void
-test_struct_array()
-{
-    test1 test1a[4] = {};
-    assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
-    assert(test1a[0].c == 11);
-    assert(test1a[1].c == 11);
-    assert(test1a[2].c == 11);
-    assert(test1a[3].c == 11);
-}
+class A {
+  char a_;
 
-class A
-{
-    char a_;
 public:
-    A() {}
-    explicit A(char a) : a_(a) {}
-    operator unsigned char() const {return 'b';}
+  TEST_CONSTEXPR A() : a_('a') {};
+  TEST_CONSTEXPR explicit A(char a) : a_(a) {}
+  TEST_CONSTEXPR operator unsigned char() const { return 'b'; }
 
-    friend bool operator==(const A& x, const A& y)
-        {return x.a_ == y.a_;}
+  TEST_CONSTEXPR friend bool operator==(const A& x, const A& y) { return x.a_ == y.a_; }
 };
 
-void
-test5()
-{
-    A a[3];
-    assert(std::fill_n(&a[0], UDI(3), A('a')) == a+3);
-    assert(a[0] == A('a'));
-    assert(a[1] == A('a'));
-    assert(a[2] == A('a'));
-}
+struct B {
+  TEST_CONSTEXPR B() : c(0) {}
+  TEST_CONSTEXPR B(char xc) : c(xc + 1) {}
+  char c;
+};
 
-struct Storage
-{
-  union
-  {
+struct Storage {
+  union {
     unsigned char a;
     unsigned char b;
   };
 };
 
-void test6()
-{
-  Storage foo[5];
-  std::fill_n(&foo[0], UDI(5), Storage());
+TEST_CONSTEXPR_CXX20 void test_struct_array() {
+  {
+    A a[3];
+    assert(std::fill_n(&a[0], UDI(3), A('a')) == a + 3);
+    assert(a[0] == A('a'));
+    assert(a[1] == A('a'));
+    assert(a[2] == A('a'));
+  }
+  {
+    B test1a[4] = {};
+    assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
+    assert(test1a[0].c == 11);
+    assert(test1a[1].c == 11);
+    assert(test1a[2].c == 11);
+    assert(test1a[3].c == 11);
+  }
+  {
+    Storage foo[5];
+    std::fill_n(&foo[0], UDI(5), Storage());
+  }
 }
 
+TEST_CONSTEXPR_CXX20 bool test() {
+  types::for_each(types::forward_iterator_list<char*>(), Test<char>());
+  types::for_each(types::forward_iterator_list<int*>(), Test<int>());
 
-int main(int, char**)
-{
-    test_char<cpp17_output_iterator<char*> >();
-    test_char<forward_iterator<char*> >();
-    test_char<bidirectional_iterator<char*> >();
-    test_char<random_access_iterator<char*> >();
-    test_char<char*>();
+  test_int_array();
+  test_struct_array();
+  test_int_array_struct_source();
 
-    test_int<cpp17_output_iterator<int*> >();
-    test_int<forward_iterator<int*> >();
-    test_int<bidirectional_iterator<int*> >();
-    test_int<random_access_iterator<int*> >();
-    test_int<int*>();
-
-    test_int_array();
-    test_int_array_struct_source();
-    test_struct_array();
-
-    test5();
-    test6();
+  return true;
+}
 
-#if TEST_STD_VER > 17
-    static_assert(test_constexpr());
+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.fill/pstl.fill.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill.pass.cpp
index 556326fb0894ca..e456fa8986aad5 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill.pass.cpp
@@ -23,6 +23,7 @@
 #include "test_macros.h"
 #include "test_execution_policies.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 
 EXECUTION_POLICY_SFINAE_TEST(fill);
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill_n.pass.cpp
index 4abbd6f7a17c3d..51232dfef16062 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/pstl.fill_n.pass.cpp
@@ -23,6 +23,7 @@
 #include "test_macros.h"
 #include "test_execution_policies.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 
 EXECUTION_POLICY_SFINAE_TEST(fill_n);
 
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
index b1ad6873bc5e5a..1b85fbbfd7c6da 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
@@ -22,38 +22,62 @@
 #include <memory>
 
 #include "MoveOnly.h"
+#include "../alg.copy/common.h"
 #include "test_iterators.h"
 #include "test_macros.h"
+#include "type_algorithms.h"
+
+TEST_CONSTEXPR_CXX20 void test_padding() { // Make sure that padding bits aren't copied
+  Derived src(1, 2, 3);
+  Derived dst(4, 5, 6);
+  std::move(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst));
+  assert(dst.a_ == 1);
+  assert(dst.b_ == 2);
+  assert(dst.c_ == 6);
+}
 
-class PaddedBase {
-public:
-  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
-
-  std::int16_t a_;
-  std::int8_t b_;
-};
-
-class Derived : public PaddedBase {
-public:
-  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+TEST_CONSTEXPR_CXX20 void test_overlapping() { // Make sure that overlapping ranges can be copied
+  int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+  std::move(a + 3, a + 10, a);
+  int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
+  assert(std::equal(a, a + 10, expected));
+}
 
-  std::int8_t c_;
-};
+TEST_CONSTEXPR_CXX20 void test_moveonly() { // Make sure that the algorithm works with move-only types
+  // When non-trivial
+  {
+    MoveOnly from[3] = {1, 2, 3};
+    MoveOnly to[3]   = {};
+    std::move(std::begin(from), std::end(from), std::begin(to));
+    assert(to[0] == MoveOnly(1));
+    assert(to[1] == MoveOnly(2));
+    assert(to[2] == MoveOnly(3));
+  }
+  // When trivial
+  {
+    TrivialMoveOnly from[3] = {1, 2, 3};
+    TrivialMoveOnly to[3]   = {};
+    std::move(std::begin(from), std::end(from), std::begin(to));
+    assert(to[0] == TrivialMoveOnly(1));
+    assert(to[1] == TrivialMoveOnly(2));
+    assert(to[2] == TrivialMoveOnly(3));
+  }
+}
 
 template <class InIter>
 struct Test {
   template <class OutIter>
   TEST_CONSTEXPR_CXX20 void operator()() {
     const unsigned N = 1000;
-    int ia[N] = {};
+    int ia[N]        = {};
     for (unsigned i = 0; i < N; ++i)
-        ia[i] = i;
+      ia[i] = i;
     int ib[N] = {0};
 
-    OutIter r = std::move(InIter(ia), InIter(ia+N), OutIter(ib));
-    assert(base(r) == ib+N);
+    OutIter r = std::move(InIter(ia), InIter(ia + N), OutIter(ib));
+    assert(base(r) == ib + N);
     for (unsigned i = 0; i < N; ++i)
-        assert(ia[i] == ib[i]);
+      assert(ia[i] == ib[i]);
   }
 };
 
@@ -73,13 +97,13 @@ struct Test1 {
     const unsigned N = 100;
     std::unique_ptr<int> ia[N];
     for (unsigned i = 0; i < N; ++i)
-        ia[i].reset(new int(i));
+      ia[i].reset(new int(i));
     std::unique_ptr<int> ib[N];
 
-    OutIter r = std::move(InIter(ia), InIter(ia+N), OutIter(ib));
-    assert(base(r) == ib+N);
+    OutIter r = std::move(InIter(ia), InIter(ia + N), OutIter(ib));
+    assert(base(r) == ib + N);
     for (unsigned i = 0; i < N; ++i)
-        assert(*ib[i] == static_cast<int>(i));
+      assert(*ib[i] == static_cast<int>(i));
   }
 };
 
@@ -96,44 +120,9 @@ TEST_CONSTEXPR_CXX20 bool test() {
   types::for_each(types::cpp17_input_iterator_list<int*>(), TestOutIters());
   if (TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED)
     types::for_each(types::cpp17_input_iterator_list<std::unique_ptr<int>*>(), Test1OutIters());
-
-  { // Make sure that padding bits aren't copied
-    Derived src(1, 2, 3);
-    Derived dst(4, 5, 6);
-    std::move(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst));
-    assert(dst.a_ == 1);
-    assert(dst.b_ == 2);
-    assert(dst.c_ == 6);
-  }
-
-  { // Make sure that overlapping ranges can be copied
-    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-    std::move(a + 3, a + 10, a);
-    int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
-    assert(std::equal(a, a + 10, expected));
-  }
-
-  // Make sure that the algorithm works with move-only types
-  {
-    // When non-trivial
-    {
-      MoveOnly from[3] = {1, 2, 3};
-      MoveOnly to[3] = {};
-      std::move(std::begin(from), std::end(from), std::begin(to));
-      assert(to[0] == MoveOnly(1));
-      assert(to[1] == MoveOnly(2));
-      assert(to[2] == MoveOnly(3));
-    }
-    // When trivial
-    {
-      TrivialMoveOnly from[3] = {1, 2, 3};
-      TrivialMoveOnly to[3] = {};
-      std::move(std::begin(from), std::end(from), std::begin(to));
-      assert(to[0] == TrivialMoveOnly(1));
-      assert(to[1] == TrivialMoveOnly(2));
-      assert(to[2] == TrivialMoveOnly(3));
-    }
-  }
+  test_padding();
+  test_overlapping();
+  test_moveonly();
 
   return true;
 }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
index 61dea47b510716..2c64edb529f7bb 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
@@ -21,47 +21,70 @@
 #include <memory>
 
 #include "MoveOnly.h"
+#include "../alg.copy/common.h"
 #include "test_iterators.h"
 #include "test_macros.h"
+#include "type_algorithms.h"
+
+TEST_CONSTEXPR_CXX20 void test_padding() { // Make sure that padding bits aren't copied
+  Derived src(1, 2, 3);
+  Derived dst(4, 5, 6);
+  std::move_backward(
+      static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst) + 1);
+  assert(dst.a_ == 1);
+  assert(dst.b_ == 2);
+  assert(dst.c_ == 6);
+}
 
-class PaddedBase {
-public:
-  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
-
-  std::int16_t a_;
-  std::int8_t b_;
-};
-
-class Derived : public PaddedBase {
-public:
-  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+TEST_CONSTEXPR_CXX20 void test_overlapping() { // Make sure that overlapping ranges can be copied
+  int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+  std::move_backward(a, a + 7, a + 10);
+  int expected[] = {1, 2, 3, 1, 2, 3, 4, 5, 6, 7};
+  assert(std::equal(a, a + 10, expected));
+}
 
-  std::int8_t c_;
-};
+TEST_CONSTEXPR_CXX20 void test_moveonly() { // Make sure that the algorithm works with move-only types
+  // When non-trivial
+  {
+    MoveOnly from[3] = {1, 2, 3};
+    MoveOnly to[3]   = {};
+    std::move_backward(std::begin(from), std::end(from), std::end(to));
+    assert(to[0] == MoveOnly(1));
+    assert(to[1] == MoveOnly(2));
+    assert(to[2] == MoveOnly(3));
+  }
+  // When trivial
+  {
+    TrivialMoveOnly from[3] = {1, 2, 3};
+    TrivialMoveOnly to[3]   = {};
+    std::move_backward(std::begin(from), std::end(from), std::end(to));
+    assert(to[0] == TrivialMoveOnly(1));
+    assert(to[1] == TrivialMoveOnly(2));
+    assert(to[2] == TrivialMoveOnly(3));
+  }
+}
 
 template <class InIter>
 struct Test {
   template <class OutIter>
   TEST_CONSTEXPR_CXX20 void operator()() {
     const unsigned N = 1000;
-    int ia[N] = {};
+    int ia[N]        = {};
     for (unsigned i = 0; i < N; ++i)
-        ia[i] = i;
+      ia[i] = i;
     int ib[N] = {0};
 
-    OutIter r = std::move_backward(InIter(ia), InIter(ia+N), OutIter(ib+N));
+    OutIter r = std::move_backward(InIter(ia), InIter(ia + N), OutIter(ib + N));
     assert(base(r) == ib);
     for (unsigned i = 0; i < N; ++i)
-        assert(ia[i] == ib[i]);
+      assert(ia[i] == ib[i]);
   }
 };
 
 struct TestOutIters {
   template <class InIter>
   TEST_CONSTEXPR_CXX20 void operator()() {
-    types::for_each(
-        types::concatenate_t<types::bidirectional_iterator_list<int*> >(),
-        Test<InIter>());
+    types::for_each(types::concatenate_t<types::bidirectional_iterator_list<int*> >(), Test<InIter>());
   }
 };
 
@@ -72,21 +95,21 @@ struct Test1 {
     const unsigned N = 100;
     std::unique_ptr<int> ia[N];
     for (unsigned i = 0; i < N; ++i)
-        ia[i].reset(new int(i));
+      ia[i].reset(new int(i));
     std::unique_ptr<int> ib[N];
 
-    OutIter r = std::move_backward(InIter(ia), InIter(ia+N), OutIter(ib+N));
+    OutIter r = std::move_backward(InIter(ia), InIter(ia + N), OutIter(ib + N));
     assert(base(r) == ib);
     for (unsigned i = 0; i < N; ++i)
-        assert(*ib[i] == static_cast<int>(i));
+      assert(*ib[i] == static_cast<int>(i));
   }
 };
 
 struct Test1OutIters {
   template <class InIter>
   TEST_CONSTEXPR_CXX23 void operator()() {
-    types::for_each(types::concatenate_t<types::bidirectional_iterator_list<std::unique_ptr<int>*> >(),
-                    Test1<InIter>());
+    types::for_each(
+        types::concatenate_t<types::bidirectional_iterator_list<std::unique_ptr<int>*> >(), Test1<InIter>());
   }
 };
 
@@ -94,51 +117,14 @@ TEST_CONSTEXPR_CXX20 bool test() {
   types::for_each(types::bidirectional_iterator_list<int*>(), TestOutIters());
   if (TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED)
     types::for_each(types::bidirectional_iterator_list<std::unique_ptr<int>*>(), Test1OutIters());
-
-  { // Make sure that padding bits aren't copied
-    Derived src(1, 2, 3);
-    Derived dst(4, 5, 6);
-    std::move_backward(
-        static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst) + 1);
-    assert(dst.a_ == 1);
-    assert(dst.b_ == 2);
-    assert(dst.c_ == 6);
-  }
-
-  { // Make sure that overlapping ranges can be copied
-    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-    std::move_backward(a, a + 7, a + 10);
-    int expected[] = {1, 2, 3, 1, 2, 3, 4, 5, 6, 7};
-    assert(std::equal(a, a + 10, expected));
-  }
-
-  // Make sure that the algorithm works with move-only types
-  {
-    // When non-trivial
-    {
-      MoveOnly from[3] = {1, 2, 3};
-      MoveOnly to[3] = {};
-      std::move_backward(std::begin(from), std::end(from), std::end(to));
-      assert(to[0] == MoveOnly(1));
-      assert(to[1] == MoveOnly(2));
-      assert(to[2] == MoveOnly(3));
-    }
-    // When trivial
-    {
-      TrivialMoveOnly from[3] = {1, 2, 3};
-      TrivialMoveOnly to[3] = {};
-      std::move_backward(std::begin(from), std::end(from), std::end(to));
-      assert(to[0] == TrivialMoveOnly(1));
-      assert(to[1] == TrivialMoveOnly(2));
-      assert(to[2] == TrivialMoveOnly(3));
-    }
-  }
+  test_padding();
+  test_overlapping();
+  test_moveonly();
 
   return true;
 }
 
-int main(int, char**)
-{
+int main(int, char**) {
   test();
 #if TEST_STD_VER >= 20
   static_assert(test());
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.move.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.move.pass.cpp
index e4cc5649ce5d81..a82a068caf0319 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.move.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.move.pass.cpp
@@ -23,6 +23,7 @@
 #include "test_macros.h"
 #include "test_execution_policies.h"
 #include "test_iterators.h"
+#include "type_algorithms.h"
 
 EXECUTION_POLICY_SFINAE_TEST(move);
 

>From 2e22e584e934f93978e85b9df8acbed138429985 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sun, 22 Dec 2024 13:45:23 -0500
Subject: [PATCH 2/2] Apply @philnik777 suggestions

---
 .../alg.copy/common.h                         | 30 -------
 .../alg.copy/copy.pass.cpp                    | 48 ++++++-----
 .../alg.copy/copy_backward.pass.cpp           | 43 ++++++----
 .../alg.copy/copy_n.pass.cpp                  | 50 ++++++-----
 .../alg.fill/fill_n.pass.cpp                  | 30 +++----
 .../alg.move/move.pass.cpp                    | 84 ++++++++++--------
 .../alg.move/move_backward.pass.cpp           | 86 ++++++++++---------
 7 files changed, 187 insertions(+), 184 deletions(-)
 delete mode 100644 libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/common.h

diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/common.h b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/common.h
deleted file mode 100644
index 562ae5121e4287..00000000000000
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/common.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TEST_STD_ALGORITHMS_ALG_MODIFYING_OPERATIONS_ALG_COPY_COMMON_H
-#define TEST_STD_ALGORITHMS_ALG_MODIFYING_OPERATIONS_ALG_COPY_COMMON_H
-
-#include <cstdint>
-#include "test_macros.h"
-
-class PaddedBase {
-public:
-  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
-
-  std::int16_t a_;
-  std::int8_t b_;
-};
-
-class Derived : public PaddedBase {
-public:
-  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
-
-  std::int8_t c_;
-};
-
-#endif
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
index e781feacb8bd93..3752afcfb32877 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp
@@ -15,30 +15,24 @@
 #include <algorithm>
 #include <cassert>
 
-#include "common.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 #include "type_algorithms.h"
 
-TEST_CONSTEXPR_CXX20 void test_padding() {
-  { // Make sure that padding bits aren't copied
-    Derived src(1, 2, 3);
-    Derived dst(4, 5, 6);
-    std::copy(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst));
-    assert(dst.a_ == 1);
-    assert(dst.b_ == 2);
-    assert(dst.c_ == 6);
-  }
-}
+class PaddedBase {
+public:
+  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
 
-TEST_CONSTEXPR_CXX20 void test_overlapping() {
-  { // Make sure that overlapping ranges can be copied
-    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-    std::copy(a + 3, a + 10, a);
-    int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
-    assert(std::equal(a, a + 10, expected));
-  }
-}
+  std::int16_t a_;
+  std::int8_t b_;
+};
+
+class Derived : public PaddedBase {
+public:
+  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+
+  std::int8_t c_;
+};
 
 template <class InIter>
 struct Test {
@@ -68,8 +62,20 @@ struct TestInIters {
 
 TEST_CONSTEXPR_CXX20 bool test() {
   types::for_each(types::cpp17_input_iterator_list<const int*>(), TestInIters());
-  test_padding();
-  test_overlapping();
+  { // Make sure that padding bits aren't copied
+    Derived src(1, 2, 3);
+    Derived dst(4, 5, 6);
+    std::copy(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst));
+    assert(dst.a_ == 1);
+    assert(dst.b_ == 2);
+    assert(dst.c_ == 6);
+  }
+  { // Make sure that overlapping ranges can be copied
+    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    std::copy(a + 3, a + 10, a);
+    int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
+    assert(std::equal(a, a + 10, expected));
+  }
 
   return true;
 }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
index 3629da78cbcc6a..d7ef6612ae4974 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp
@@ -16,12 +16,26 @@
 #include <algorithm>
 #include <cassert>
 
-#include "common.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 #include "type_algorithms.h"
 #include "user_defined_integral.h"
 
+class PaddedBase {
+public:
+  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
+
+  std::int16_t a_;
+  std::int8_t b_;
+};
+
+class Derived : public PaddedBase {
+public:
+  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+
+  std::int8_t c_;
+};
+
 template <class InIter>
 struct TestOutIters {
   template <class OutIter>
@@ -39,7 +53,16 @@ struct TestOutIters {
   }
 };
 
-TEST_CONSTEXPR_CXX20 void test_padding() {
+struct TestInIters {
+  template <class InIter>
+  TEST_CONSTEXPR_CXX20 void operator()() {
+    types::for_each(types::bidirectional_iterator_list<int*>(), TestOutIters<InIter>());
+  }
+};
+
+TEST_CONSTEXPR_CXX20 bool test() {
+  types::for_each(types::bidirectional_iterator_list<const int*>(), TestInIters());
+
   { // Make sure that padding bits aren't copied
     Derived src(1, 2, 3);
     Derived dst(4, 5, 6);
@@ -49,28 +72,12 @@ TEST_CONSTEXPR_CXX20 void test_padding() {
     assert(dst.b_ == 2);
     assert(dst.c_ == 6);
   }
-}
-
-TEST_CONSTEXPR_CXX20 void test_overlapping() {
   { // Make sure that overlapping ranges can be copied
     int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     std::copy_backward(a, a + 7, a + 10);
     int expected[] = {1, 2, 3, 1, 2, 3, 4, 5, 6, 7};
     assert(std::equal(a, a + 10, expected));
   }
-}
-
-struct TestInIters {
-  template <class InIter>
-  TEST_CONSTEXPR_CXX20 void operator()() {
-    types::for_each(types::bidirectional_iterator_list<int*>(), TestOutIters<InIter>());
-  }
-};
-
-TEST_CONSTEXPR_CXX20 bool test() {
-  types::for_each(types::bidirectional_iterator_list<const int*>(), TestInIters());
-  test_padding();
-  test_overlapping();
 
   return true;
 }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
index 28362f4f990997..71f1ef3173ade9 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp
@@ -15,33 +15,27 @@
 #include <algorithm>
 #include <cassert>
 
-#include "common.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 #include "type_algorithms.h"
 #include "user_defined_integral.h"
 
-typedef UserDefinedIntegral<unsigned> UDI;
+class PaddedBase {
+public:
+  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
 
-TEST_CONSTEXPR_CXX20 void test_padding() {
-  { // Make sure that padding bits aren't copied
-    Derived src(1, 2, 3);
-    Derived dst(4, 5, 6);
-    std::copy_n(static_cast<PaddedBase*>(&src), 1, static_cast<PaddedBase*>(&dst));
-    assert(dst.a_ == 1);
-    assert(dst.b_ == 2);
-    assert(dst.c_ == 6);
-  }
-}
+  std::int16_t a_;
+  std::int8_t b_;
+};
 
-TEST_CONSTEXPR_CXX20 void test_overlapping() {
-  { // Make sure that overlapping ranges can be copied
-    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-    std::copy_n(a + 3, 7, a);
-    int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
-    assert(std::equal(a, a + 10, expected));
-  }
-}
+class Derived : public PaddedBase {
+public:
+  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+
+  std::int8_t c_;
+};
+
+typedef UserDefinedIntegral<unsigned> UDI;
 
 template <class InIter>
 struct TestOutIters {
@@ -71,8 +65,20 @@ struct TestInIters {
 
 TEST_CONSTEXPR_CXX20 bool test() {
   types::for_each(types::cpp17_input_iterator_list<const int*>(), TestInIters());
-  test_padding();
-  test_overlapping();
+  { // Make sure that padding bits aren't copied
+    Derived src(1, 2, 3);
+    Derived dst(4, 5, 6);
+    std::copy_n(static_cast<PaddedBase*>(&src), 1, static_cast<PaddedBase*>(&dst));
+    assert(dst.a_ == 1);
+    assert(dst.b_ == 2);
+    assert(dst.c_ == 6);
+  }
+  { // Make sure that overlapping ranges can be copied
+    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    std::copy_n(a + 3, 7, a);
+    int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
+    assert(std::equal(a, a + 10, expected));
+  }
 
   return true;
 }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
index 103976f77410b9..cfb0f94084c163 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
@@ -27,13 +27,9 @@ typedef UserDefinedIntegral<unsigned> UDI;
 
 template <class Iter, class Container>
 TEST_CONSTEXPR_CXX20 void
-test(Container& in,
-     typename Container::iterator first,
-     size_t n,
-     typename Container::value_type value,
-     const Container& expected) {
-  Iter it = std::fill_n(Iter(first), UDI(n), value);
-  assert(base(it) == first + n);
+test(Container in, size_t from, size_t n, typename Container::value_type value, Container expected) {
+  Iter it = std::fill_n(Iter(in.data() + from), UDI(n), value);
+  assert(base(it) == in.data() + from + n);
   assert(in == expected);
 }
 
@@ -44,22 +40,23 @@ struct Test {
     {
       std::array<T, 4> in       = {1, 2, 3, 4};
       std::array<T, 4> expected = {5, 5, 5, 5};
-      test<Iter>(in, in.begin(), 4, 5, expected);
+      test<Iter>(in, 0, 4, 5, expected);
     }
     {
       std::array<T, 4> in       = {1, 2, 3, 4};
       std::array<T, 4> expected = {1, 5, 5, 4};
-      test<Iter>(in, in.begin() + 1, 2, 5, expected);
+      test<Iter>(in, 1, 2, 5, expected);
     }
   }
 };
 
-TEST_CONSTEXPR void test_int_array() {
+TEST_CONSTEXPR_CXX20 void test_int_array() {
   {
     int a[4] = {};
     assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
     assert(a[0] == 1 && a[1] == 1 && a[2] == 1 && a[3] == 1);
   }
+#if TEST_STD_VER >= 11
   {
     const std::size_t N = 5;
     int ib[]            = {0, 0, 0, 0, 0, 0}; // one bigger than N
@@ -69,6 +66,7 @@ TEST_CONSTEXPR void test_int_array() {
            *it == 0 // don't overwrite the last value in the output array
     );
   }
+#endif
 }
 
 struct source {
@@ -118,12 +116,12 @@ TEST_CONSTEXPR_CXX20 void test_struct_array() {
     assert(a[2] == A('a'));
   }
   {
-    B test1a[4] = {};
-    assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
-    assert(test1a[0].c == 11);
-    assert(test1a[1].c == 11);
-    assert(test1a[2].c == 11);
-    assert(test1a[3].c == 11);
+    B b[4] = {};
+    assert(std::fill_n(b, UDI(4), static_cast<char>(10)) == b + 4);
+    assert(b[0].c == 11);
+    assert(b[1].c == 11);
+    assert(b[2].c == 11);
+    assert(b[3].c == 11);
   }
   {
     Storage foo[5];
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
index 1b85fbbfd7c6da..5324a327b50bcb 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp
@@ -22,47 +22,24 @@
 #include <memory>
 
 #include "MoveOnly.h"
-#include "../alg.copy/common.h"
 #include "test_iterators.h"
 #include "test_macros.h"
 #include "type_algorithms.h"
 
-TEST_CONSTEXPR_CXX20 void test_padding() { // Make sure that padding bits aren't copied
-  Derived src(1, 2, 3);
-  Derived dst(4, 5, 6);
-  std::move(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst));
-  assert(dst.a_ == 1);
-  assert(dst.b_ == 2);
-  assert(dst.c_ == 6);
-}
+class PaddedBase {
+public:
+  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
 
-TEST_CONSTEXPR_CXX20 void test_overlapping() { // Make sure that overlapping ranges can be copied
-  int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-  std::move(a + 3, a + 10, a);
-  int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
-  assert(std::equal(a, a + 10, expected));
-}
+  std::int16_t a_;
+  std::int8_t b_;
+};
 
-TEST_CONSTEXPR_CXX20 void test_moveonly() { // Make sure that the algorithm works with move-only types
-  // When non-trivial
-  {
-    MoveOnly from[3] = {1, 2, 3};
-    MoveOnly to[3]   = {};
-    std::move(std::begin(from), std::end(from), std::begin(to));
-    assert(to[0] == MoveOnly(1));
-    assert(to[1] == MoveOnly(2));
-    assert(to[2] == MoveOnly(3));
-  }
-  // When trivial
-  {
-    TrivialMoveOnly from[3] = {1, 2, 3};
-    TrivialMoveOnly to[3]   = {};
-    std::move(std::begin(from), std::end(from), std::begin(to));
-    assert(to[0] == TrivialMoveOnly(1));
-    assert(to[1] == TrivialMoveOnly(2));
-    assert(to[2] == TrivialMoveOnly(3));
-  }
-}
+class Derived : public PaddedBase {
+public:
+  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+
+  std::int8_t c_;
+};
 
 template <class InIter>
 struct Test {
@@ -120,9 +97,40 @@ TEST_CONSTEXPR_CXX20 bool test() {
   types::for_each(types::cpp17_input_iterator_list<int*>(), TestOutIters());
   if (TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED)
     types::for_each(types::cpp17_input_iterator_list<std::unique_ptr<int>*>(), Test1OutIters());
-  test_padding();
-  test_overlapping();
-  test_moveonly();
+  { // Make sure that padding bits aren't copied
+    Derived src(1, 2, 3);
+    Derived dst(4, 5, 6);
+    std::move(static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst));
+    assert(dst.a_ == 1);
+    assert(dst.b_ == 2);
+    assert(dst.c_ == 6);
+  }
+  { // Make sure that overlapping ranges can be copied
+    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    std::move(a + 3, a + 10, a);
+    int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10};
+    assert(std::equal(a, a + 10, expected));
+  }
+  { // Make sure that the algorithm works with move-only types
+    // When non-trivial
+    {
+      MoveOnly from[3] = {1, 2, 3};
+      MoveOnly to[3]   = {};
+      std::move(std::begin(from), std::end(from), std::begin(to));
+      assert(to[0] == MoveOnly(1));
+      assert(to[1] == MoveOnly(2));
+      assert(to[2] == MoveOnly(3));
+    }
+    // When trivial
+    {
+      TrivialMoveOnly from[3] = {1, 2, 3};
+      TrivialMoveOnly to[3]   = {};
+      std::move(std::begin(from), std::end(from), std::begin(to));
+      assert(to[0] == TrivialMoveOnly(1));
+      assert(to[1] == TrivialMoveOnly(2));
+      assert(to[2] == TrivialMoveOnly(3));
+    }
+  }
 
   return true;
 }
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
index 2c64edb529f7bb..d166c854f30aaf 100644
--- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp
@@ -21,48 +21,24 @@
 #include <memory>
 
 #include "MoveOnly.h"
-#include "../alg.copy/common.h"
 #include "test_iterators.h"
 #include "test_macros.h"
 #include "type_algorithms.h"
 
-TEST_CONSTEXPR_CXX20 void test_padding() { // Make sure that padding bits aren't copied
-  Derived src(1, 2, 3);
-  Derived dst(4, 5, 6);
-  std::move_backward(
-      static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst) + 1);
-  assert(dst.a_ == 1);
-  assert(dst.b_ == 2);
-  assert(dst.c_ == 6);
-}
+class PaddedBase {
+public:
+  TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {}
 
-TEST_CONSTEXPR_CXX20 void test_overlapping() { // Make sure that overlapping ranges can be copied
-  int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-  std::move_backward(a, a + 7, a + 10);
-  int expected[] = {1, 2, 3, 1, 2, 3, 4, 5, 6, 7};
-  assert(std::equal(a, a + 10, expected));
-}
+  std::int16_t a_;
+  std::int8_t b_;
+};
 
-TEST_CONSTEXPR_CXX20 void test_moveonly() { // Make sure that the algorithm works with move-only types
-  // When non-trivial
-  {
-    MoveOnly from[3] = {1, 2, 3};
-    MoveOnly to[3]   = {};
-    std::move_backward(std::begin(from), std::end(from), std::end(to));
-    assert(to[0] == MoveOnly(1));
-    assert(to[1] == MoveOnly(2));
-    assert(to[2] == MoveOnly(3));
-  }
-  // When trivial
-  {
-    TrivialMoveOnly from[3] = {1, 2, 3};
-    TrivialMoveOnly to[3]   = {};
-    std::move_backward(std::begin(from), std::end(from), std::end(to));
-    assert(to[0] == TrivialMoveOnly(1));
-    assert(to[1] == TrivialMoveOnly(2));
-    assert(to[2] == TrivialMoveOnly(3));
-  }
-}
+class Derived : public PaddedBase {
+public:
+  TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {}
+
+  std::int8_t c_;
+};
 
 template <class InIter>
 struct Test {
@@ -117,9 +93,41 @@ TEST_CONSTEXPR_CXX20 bool test() {
   types::for_each(types::bidirectional_iterator_list<int*>(), TestOutIters());
   if (TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED)
     types::for_each(types::bidirectional_iterator_list<std::unique_ptr<int>*>(), Test1OutIters());
-  test_padding();
-  test_overlapping();
-  test_moveonly();
+  { // Make sure that padding bits aren't copied
+    Derived src(1, 2, 3);
+    Derived dst(4, 5, 6);
+    std::move_backward(
+        static_cast<PaddedBase*>(&src), static_cast<PaddedBase*>(&src) + 1, static_cast<PaddedBase*>(&dst) + 1);
+    assert(dst.a_ == 1);
+    assert(dst.b_ == 2);
+    assert(dst.c_ == 6);
+  }
+  { // Make sure that overlapping ranges can be copied
+    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    std::move_backward(a, a + 7, a + 10);
+    int expected[] = {1, 2, 3, 1, 2, 3, 4, 5, 6, 7};
+    assert(std::equal(a, a + 10, expected));
+  }
+  { // Make sure that the algorithm works with move-only types
+    // When non-trivial
+    {
+      MoveOnly from[3] = {1, 2, 3};
+      MoveOnly to[3]   = {};
+      std::move_backward(std::begin(from), std::end(from), std::end(to));
+      assert(to[0] == MoveOnly(1));
+      assert(to[1] == MoveOnly(2));
+      assert(to[2] == MoveOnly(3));
+    }
+    // When trivial
+    {
+      TrivialMoveOnly from[3] = {1, 2, 3};
+      TrivialMoveOnly to[3]   = {};
+      std::move_backward(std::begin(from), std::end(from), std::end(to));
+      assert(to[0] == TrivialMoveOnly(1));
+      assert(to[1] == TrivialMoveOnly(2));
+      assert(to[2] == TrivialMoveOnly(3));
+    }
+  }
 
   return true;
 }



More information about the libcxx-commits mailing list