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

Reply via email to