I plan to merge this to trunk with one change to message, as mentioned
below,
to reduce the number of commits that will be piling up to get approved.

On Wed, Jul 23, 2025 at 11:30 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.
>
I will remove that sentence as we just pass Acesssor.

>
> 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 | 125 ++++++++++++++++++
>  2 files changed, 125 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..c3350353aae
> --- /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;
> +}
> --
> 2.50.0
>
>

Reply via email to