On Thu, Jul 3, 2025 at 12:36 PM Luc Grosheintz <luc.groshei...@gmail.com> wrote:
> 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. > --- > LGTM. > .../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 > >