On Thu, Jun 26, 2025 at 3:40 PM Luc Grosheintz <luc.groshei...@gmail.com> wrote:
> > > On 6/13/25 12:40, Luc Grosheintz 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. > > > > Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> > > --- > > libstdc++-v3/include/std/mdspan | 26 ++++++++ > > libstdc++-v3/src/c++23/std.cc.in | 3 +- > > .../23_containers/mdspan/accessors/default.cc | 59 +++++++++++++++++++ > > 3 files changed, 87 insertions(+), 1 deletion(-) > > create mode 100644 > libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc > > > > diff --git a/libstdc++-v3/include/std/mdspan > b/libstdc++-v3/include/std/mdspan > > index 6dc2441f80b..2e85ba8e6cb 100644 > > --- a/libstdc++-v3/include/std/mdspan > > +++ b/libstdc++-v3/include/std/mdspan > > @@ -1004,6 +1004,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > [[no_unique_address]] _S_strides_t _M_strides; > > }; > > > > + template<typename _ElementType> > > + struct default_accessor > > + { > > It would be easy to check the two mandates: not abstract, not array > here. Would you like a v3, with the change? > > https://eel.is/c++draft/views.multidim#mdspan.accessor.default.overview-2 Yes, I think that makes sense. Thanks. > > > > + 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 109f590f1d1..e671aff68f8 100644 > > --- a/libstdc++-v3/src/c++23/std.cc.in > > +++ b/libstdc++-v3/src/c++23/std.cc.in > > @@ -1843,7 +1843,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 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..303833d4857 > > --- /dev/null > > +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc > > @@ -0,0 +1,59 @@ > > +// { 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; > > +} > > + > > +constexpr void > > +test_ctor() > > +{ > > + > 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>>); > > + static_assert(!std::is_constructible_v<std::default_accessor<char>, > > + std::default_accessor<int>>); > > +} > > + > > +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; > > +} > >