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. --- .../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.49.0