On Tue, Jul 22, 2025 at 11:58 AM Tomasz Kaminski <tkami...@redhat.com>
wrote:

>
>
> On Mon, Jul 21, 2025 at 10:19 AM 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.
>>
>> 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>
>>
> I would make this a template template parameter in form:
> template<template<typename> typename Accessor>
> This way you could pass default_accessor directly, and for aligned accessor
> pass an alias template.
>
Given next commit, we could make a test_properities() with accessor
parameter,
that will call test_class_properties, test_accessor_policy and test_ctor.

> +  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