On Mon, Jun 30, 2025 at 4:27 PM Jonathan Wakely <jwak...@redhat.com> wrote:
> On Mon, 30 Jun 2025 at 11:48, Tomasz Kaminski <tkami...@redhat.com> wrote: > > > > > > > > On Mon, Jun 30, 2025 at 9:58 AM Tomasz Kaminski <tkami...@redhat.com> > wrote: > >> > >> > >> > >> On Mon, Jun 30, 2025 at 9:25 AM Luc Grosheintz < > luc.groshei...@gmail.com> wrote: > >>> > >>> libstdc++-v3/ChangeLog: > >>> > >>> * include/std/mdspan (default_accessor): New class. > >>> * src/c++23/std.cc.in: Register default_accessor. > >>> * testsuite/23_containers/mdspan/accessors/default.cc: New > test. > >>> * testsuite/23_containers/mdspan/accessors/default_neg.cc: New > test. > >>> > >>> Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> > >>> --- > >>> > >>> Version of v5 with all local changes included. > >> > >> LGTM, tested locally and now running a full test suite. > >> Once it will get approval from Jonathan, I will handle merging it. > > > > All test passed. > > OK for trunk, thank you both. > Patch now merged to trunk. I hope to review mdspan itself this week. > > >> > >> > >>> > >>> > >>> libstdc++-v3/include/std/mdspan | 31 ++++++ > >>> libstdc++-v3/src/c++23/std.cc.in | 3 +- > >>> .../23_containers/mdspan/accessors/default.cc | 99 +++++++++++++++++++ > >>> .../mdspan/accessors/default_neg.cc | 23 +++++ > >>> 4 files changed, 155 insertions(+), 1 deletion(-) > >>> create mode 100644 > libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc > >>> create mode 100644 > libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc > >>> > >>> diff --git a/libstdc++-v3/include/std/mdspan > b/libstdc++-v3/include/std/mdspan > >>> index 6dc2441f80b..c72a64094b7 100644 > >>> --- a/libstdc++-v3/include/std/mdspan > >>> +++ b/libstdc++-v3/include/std/mdspan > >>> @@ -1004,6 +1004,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > >>> [[no_unique_address]] _S_strides_t _M_strides; > >>> }; > >>> > >>> + template<typename _ElementType> > >>> + struct default_accessor > >>> + { > >>> + static_assert(!is_array_v<_ElementType>, > >>> + "ElementType must not be an array type"); > >>> + static_assert(!is_abstract_v<_ElementType>, > >>> + "ElementType must not be an abstract class type"); > >>> + > >>> + using offset_policy = default_accessor; > >>> + using element_type = _ElementType; > >>> + using reference = element_type&; > >>> + using data_handle_type = element_type*; > >>> + > >>> + constexpr > >>> + default_accessor() noexcept = default; > >>> + > >>> + template<typename _OElementType> > >>> + requires is_convertible_v<_OElementType(*)[], > element_type(*)[]> > >>> + constexpr > >>> + default_accessor(default_accessor<_OElementType>) noexcept > >>> + { } > >>> + > >>> + constexpr reference > >>> + access(data_handle_type __p, size_t __i) const noexcept > >>> + { return __p[__i]; } > >>> + > >>> + constexpr data_handle_type > >>> + offset(data_handle_type __p, size_t __i) const noexcept > >>> + { return __p + __i; } > >>> + }; > >>> + > >>> _GLIBCXX_END_NAMESPACE_VERSION > >>> } > >>> #endif > >>> diff --git a/libstdc++-v3/src/c++23/std.cc.in > b/libstdc++-v3/src/c++23/std.cc.in > >>> index 9336118f5d9..e692caaa5f9 100644 > >>> --- a/libstdc++-v3/src/c++23/std.cc.in > >>> +++ b/libstdc++-v3/src/c++23/std.cc.in > >>> @@ -1850,7 +1850,8 @@ export namespace std > >>> using std::layout_left; > >>> using std::layout_right; > >>> using std::layout_stride; > >>> - // FIXME layout_left_padded, layout_right_padded, default_accessor > and mdspan > >>> + using std::default_accessor; > >>> + // FIXME layout_left_padded, layout_right_padded, aligned_accessor > and mdspan > >>> } > >>> #endif > >>> > >>> diff --git > a/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc > b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc > >>> new file mode 100644 > >>> index 00000000000..c036f8ad10f > >>> --- /dev/null > >>> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc > >>> @@ -0,0 +1,99 @@ > >>> +// { 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/default_neg.cc > b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc > >>> new file mode 100644 > >>> index 00000000000..f8da2b569ca > >>> --- /dev/null > >>> +++ > b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default_neg.cc > >>> @@ -0,0 +1,23 @@ > >>> +// { dg-do compile { target c++23 } } > >>> +#include<mdspan> > >>> + > >>> +std::default_accessor<int[3]> a; // { dg-error "required from here" } > >>> + > >>> +class AbstractBase > >>> +{ > >>> + virtual void > >>> + foo() const = 0; > >>> +}; > >>> + > >>> +class Derived : public AbstractBase > >>> +{ > >>> + void > >>> + foo() const override > >>> + { } > >>> +}; > >>> + > >>> +std::default_accessor<Derived> b_ok; > >>> +std::default_accessor<AbstractBase> b_err; // { dg-error "required > from here"} > >>> + > >>> +// { dg-prune-output "ElementType must not be an array type" } > >>> +// { dg-prune-output "ElementType must not be an abstract" } > >>> -- > >>> 2.49.0 > >>> > >