libstdc++-v3/ChangeLog: * include/std/mdspan (default_accessor): New class. * src/c++23/std.cc.in: Register default_accessor. * testsuite/23_containers/mdspan/default_accessor.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/default_accessor.cc | 59 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/default_accessor.cc diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index 4a3e863bed5..8c6b7f49155 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 + { + 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 9a52a7e7728..51111627d7d 100644 --- a/libstdc++-v3/src/c++23/std.cc.in +++ b/libstdc++-v3/src/c++23/std.cc.in @@ -1847,7 +1847,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/default_accessor.cc b/libstdc++-v3/testsuite/23_containers/mdspan/default_accessor.cc new file mode 100644 index 00000000000..303833d4857 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/default_accessor.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; +} -- 2.49.0