All test code of default_accessor can be reused. This commit moves
the reuseable code into a file generic.cc and prepares the tests for
reuse with aligned_accessor.

The AllocatorTrait creates a unified interface for creating both
default_accessor<T> and aligned_accessor<T, N> typenames.

libstdc++-v3/ChangeLog:

        * testsuite/23_containers/mdspan/accessors/default.cc: Delete.
        * testsuite/23_containers/mdspan/accessors/generic.cc: Slightly
        generalize the test code previously in default.cc.

Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com>
---
 .../23_containers/mdspan/accessors/default.cc |  99 ------------
 .../23_containers/mdspan/accessors/generic.cc | 141 ++++++++++++++++++
 2 files changed, 141 insertions(+), 99 deletions(-)
 delete mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc

diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
deleted file mode 100644
index c036f8ad10f..00000000000
--- a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// { dg-do run { target c++23 } }
-#include <mdspan>
-
-#include <testsuite_hooks.h>
-
-constexpr size_t dyn = std::dynamic_extent;
-
-template<typename Accessor>
-  constexpr void
-  test_accessor_policy()
-  {
-    static_assert(std::copyable<Accessor>);
-    static_assert(std::is_nothrow_move_constructible_v<Accessor>);
-    static_assert(std::is_nothrow_move_assignable_v<Accessor>);
-    static_assert(std::is_nothrow_swappable_v<Accessor>);
-  }
-
-constexpr bool
-test_access()
-{
-  std::default_accessor<double> accessor;
-  std::array<double, 5> a{10, 11, 12, 13, 14};
-  VERIFY(accessor.access(a.data(), 0) == 10);
-  VERIFY(accessor.access(a.data(), 4) == 14);
-  return true;
-}
-
-constexpr bool
-test_offset()
-{
-  std::default_accessor<double> accessor;
-  std::array<double, 5> a{10, 11, 12, 13, 14};
-  VERIFY(accessor.offset(a.data(), 0) == a.data());
-  VERIFY(accessor.offset(a.data(), 4) == a.data() + 4);
-  return true;
-}
-
-class Base
-{ };
-
-class Derived : public Base
-{ };
-
-constexpr void
-test_ctor()
-{
-  // T -> T
-  static_assert(std::is_nothrow_constructible_v<std::default_accessor<double>,
-                                               std::default_accessor<double>>);
-  static_assert(std::is_convertible_v<std::default_accessor<double>,
-                                     std::default_accessor<double>>);
-
-  // T -> const T
-  static_assert(std::is_convertible_v<std::default_accessor<double>,
-                                     std::default_accessor<const double>>);
-  static_assert(std::is_convertible_v<std::default_accessor<Derived>,
-                                     std::default_accessor<const Derived>>);
-
-  // const T -> T
-  static_assert(!std::is_constructible_v<std::default_accessor<double>,
-                                        std::default_accessor<const double>>);
-  static_assert(!std::is_constructible_v<std::default_accessor<Derived>,
-                                        std::default_accessor<const Derived>>);
-
-  // T <-> volatile T
-  static_assert(std::is_convertible_v<std::default_accessor<int>,
-                                     std::default_accessor<volatile int>>);
-  static_assert(!std::is_constructible_v<std::default_accessor<int>,
-                                        std::default_accessor<volatile int>>);
-
-  // size difference
-  static_assert(!std::is_constructible_v<std::default_accessor<char>,
-                                        std::default_accessor<int>>);
-
-  // signedness
-  static_assert(!std::is_constructible_v<std::default_accessor<int>,
-                                        std::default_accessor<unsigned int>>);
-  static_assert(!std::is_constructible_v<std::default_accessor<unsigned int>,
-                                        std::default_accessor<int>>);
-
-  // Derived <-> Base
-  static_assert(!std::is_constructible_v<std::default_accessor<Base>,
-                                        std::default_accessor<Derived>>);
-  static_assert(!std::is_constructible_v<std::default_accessor<Derived>,
-                                        std::default_accessor<Base>>);
-
-}
-
-int
-main()
-{
-  test_accessor_policy<std::default_accessor<double>>();
-  test_access();
-  static_assert(test_access());
-  test_offset();
-  static_assert(test_offset());
-  test_ctor();
-  return 0;
-}
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc
new file mode 100644
index 00000000000..600d152b690
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc
@@ -0,0 +1,141 @@
+// { dg-do run { target c++23 } }
+#include <mdspan>
+
+#include <testsuite_hooks.h>
+
+template<typename Accessor>
+  constexpr bool
+  test_class_properties()
+  {
+    static_assert(std::is_trivially_copyable_v<Accessor>);
+    static_assert(std::semiregular<Accessor>);
+    return true;
+  }
+
+template<typename Accessor>
+  constexpr bool
+  test_accessor_policy()
+  {
+    static_assert(std::copyable<Accessor>);
+    static_assert(std::is_nothrow_move_constructible_v<Accessor>);
+    static_assert(std::is_nothrow_move_assignable_v<Accessor>);
+    static_assert(std::is_nothrow_swappable_v<Accessor>);
+    return true;
+  }
+
+class Base
+{ };
+
+class Derived : public Base
+{ };
+
+template<typename AccessorTrait>
+  constexpr bool
+  test_ctor()
+  {
+    // T -> T
+    static_assert(std::is_nothrow_constructible_v<
+       typename AccessorTrait::type<double>,
+       typename AccessorTrait::type<double>>);
+    static_assert(std::is_convertible_v<
+       typename AccessorTrait::type<double>,
+       typename AccessorTrait::type<double>>);
+
+    // T -> const T
+    static_assert(std::is_convertible_v<
+       typename AccessorTrait::type<double>,
+       typename AccessorTrait::type<const double>>);
+    static_assert(std::is_convertible_v<
+       typename AccessorTrait::type<Derived>,
+       typename AccessorTrait::type<const Derived>>);
+
+    // const T -> T
+    static_assert(!std::is_constructible_v<
+       typename AccessorTrait::type<double>,
+       typename AccessorTrait::type<const double>>);
+    static_assert(!std::is_constructible_v<
+       typename AccessorTrait::type<Derived>,
+       typename AccessorTrait::type<const Derived>>);
+
+    // T <-> volatile T
+    static_assert(std::is_convertible_v<
+       typename AccessorTrait::type<int>,
+       typename AccessorTrait::type<volatile int>>);
+    static_assert(!std::is_constructible_v<
+       typename AccessorTrait::type<int>,
+       typename AccessorTrait::type<volatile int>>);
+
+    // size difference
+    static_assert(!std::is_constructible_v<
+       typename AccessorTrait::type<char>,
+       typename AccessorTrait::type<int>>);
+
+    // signedness
+    static_assert(!std::is_constructible_v<
+       typename AccessorTrait::type<int>,
+       typename AccessorTrait::type<unsigned int>>);
+    static_assert(!std::is_constructible_v<
+       typename AccessorTrait::type<unsigned int>,
+       typename AccessorTrait::type<int>>);
+
+    // Derived <-> Base
+    static_assert(!std::is_constructible_v<
+       typename AccessorTrait::type<Base>,
+       typename AccessorTrait::type<Derived>>);
+    static_assert(!std::is_constructible_v<
+       typename AccessorTrait::type<Derived>,
+       typename AccessorTrait::type<Base>>);
+    return true;
+  }
+
+struct DefaultAccessorTrait
+{
+  template<typename T>
+    using type = std::default_accessor<T>;
+};
+
+static_assert(test_class_properties<std::default_accessor<double>>());
+static_assert(test_accessor_policy<std::default_accessor<double>>());
+static_assert(test_ctor<DefaultAccessorTrait>());
+
+template<typename A>
+  constexpr size_t
+  accessor_alignment = sizeof(typename A::element_type);
+
+template<typename Accessor>
+  constexpr void
+  test_access(Accessor accessor)
+  {
+    constexpr size_t N = accessor_alignment<Accessor>;
+    alignas(N) std::array<double, 5> a{10, 11, 12, 13, 14};
+    VERIFY(accessor.access(a.data(), 0) == 10);
+    VERIFY(accessor.access(a.data(), 4) == 14);
+  }
+
+template<typename Accessor>
+  constexpr void
+  test_offset(Accessor accessor)
+  {
+    constexpr size_t N = accessor_alignment<Accessor>;
+    alignas(N) std::array<double, 5> a{10, 11, 12, 13, 14};
+    VERIFY(accessor.offset(a.data(), 0) == a.data());
+    VERIFY(accessor.offset(a.data(), 4) == a.data() + 4);
+  }
+
+template<typename Accessor>
+  constexpr bool
+  test_all()
+  {
+    auto accessor = Accessor{};
+    test_offset(accessor);
+    test_access(accessor);
+    return true;
+  }
+
+int
+main()
+{
+  test_all<std::default_accessor<double>>();
+  static_assert(test_all<std::default_accessor<double>>());
+  return 0;
+}
-- 
2.50.0

Reply via email to