[PATCH v2 2/3] libstdc++: Prepare test code for default_accessor for reuse.
Tomasz Kaminski
tkaminsk@redhat.com
Tue Jul 22 09:58:20 GMT 2025
On Mon, Jul 21, 2025 at 10:19 AM Luc Grosheintz <luc.grosheintz@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.grosheintz@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.
> + 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250722/941a7cbc/attachment-0001.htm>
More information about the Libstdc++
mailing list