[PATCH v2 1/1] libstdc++: Implement default_accessor from mdspan.

Luc Grosheintz luc.grosheintz@gmail.com
Fri Jun 27 07:51:43 GMT 2025



On 6/27/25 08:53, Tomasz Kaminski wrote:
> On Thu, Jun 26, 2025 at 3:40 PM Luc Grosheintz <luc.grosheintz@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.grosheintz@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.

Done: https://gcc.gnu.org/pipermail/libstdc++/2025-June/062197.html

> 
>>
>>
>>> +      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;
>>> +}
>>
>>
> 



More information about the Libstdc++ mailing list