https://gcc.gnu.org/g:9acdbf81eef6db74502a9b704ba08e5a84dfb5fa
commit r16-2445-g9acdbf81eef6db74502a9b704ba08e5a84dfb5fa Author: Luc Grosheintz <luc.groshei...@gmail.com> Date: Wed Jul 23 11:25:52 2025 +0200 libstdc++: Prepare test code for default_accessor for reuse. 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. 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. Reviewed-by: Tomasz KamiĆski <tkami...@redhat.com> Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> Diff: --- .../23_containers/mdspan/accessors/default.cc | 99 ---------------- .../23_containers/mdspan/accessors/generic.cc | 125 +++++++++++++++++++++ 2 files changed, 125 insertions(+), 99 deletions(-) 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 c036f8ad10ff..000000000000 --- 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 000000000000..c3350353aae9 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/generic.cc @@ -0,0 +1,125 @@ +// { 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<template<typename T> typename Accessor> + constexpr bool + test_ctor() + { + // T -> T + static_assert(std::is_nothrow_constructible_v<Accessor<double>, + Accessor<double>>); + static_assert(std::is_convertible_v<Accessor<double>, Accessor<double>>); + + // T -> const T + static_assert(std::is_convertible_v<Accessor<double>, + Accessor<const double>>); + static_assert(std::is_convertible_v<Accessor<Derived>, + Accessor<const Derived>>); + + // const T -> T + static_assert(!std::is_constructible_v<Accessor<double>, + Accessor<const double>>); + static_assert(!std::is_constructible_v<Accessor<Derived>, + Accessor<const Derived>>); + + // T <-> volatile T + static_assert(std::is_convertible_v<Accessor<int>, Accessor<volatile int>>); + static_assert(!std::is_constructible_v<Accessor<int>, + Accessor<volatile int>>); + + // size difference + static_assert(!std::is_constructible_v<Accessor<char>, Accessor<int>>); + + // signedness + static_assert(!std::is_constructible_v<Accessor<int>, + Accessor<unsigned int>>); + static_assert(!std::is_constructible_v<Accessor<unsigned int>, + Accessor<int>>); + + // Derived <-> Base + static_assert(!std::is_constructible_v<Accessor<Base>, Accessor<Derived>>); + static_assert(!std::is_constructible_v<Accessor<Derived>, Accessor<Base>>); + return true; + } + +template<template<typename T> typename Accessor> + constexpr bool + test_properties() + { + test_class_properties<Accessor<double>>(); + test_accessor_policy<Accessor<double>>(); + test_ctor<Accessor>(); + return true; + } + +static_assert(test_properties<std::default_accessor>()); + +template<typename A> + constexpr size_t + accessor_alignment = alignof(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}; + for (size_t i = 0; i < a.size(); ++i) + VERIFY(accessor.access(a.data(), i) == 10 + i); + } + +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}; + for (size_t i = 0; i < a.size(); ++i) + VERIFY(accessor.offset(a.data(), i) == a.data() + i); + } + +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; +}