On 6/6/25 14:12, Tomasz Kaminski wrote:
On Thu, Jun 5, 2025 at 4:31 PM 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/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 +++++++++++++++++++

LGTM. I would only change a bit layout of test directories, to have
23_containers/mdspan/accessors/default.cc
as we already have over aligned one, and few more were proposed.

Makes sense, I'll move the file and send v2 after layouts are
merged, that way I can be sure it'll apply cleanly.


  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




Reply via email to