On Fri, 27 Jun 2025 at 10:39, Tomasz Kaminski <tkami...@redhat.com> wrote: > > Also, for single patch (not-patch series), you do not need to have [PATCH > 0/N], simple [PATCH] and then [PATCH v2] also works.
Yeah, sending a 0/N cover letter is only useful to describe what a multi-part patch series does. For a single patch, you should be describing what it does in that patch itself, and a cover letter just adds noise. > > On Fri, Jun 27, 2025 at 11:11 AM Tomasz Kaminski <tkami...@redhat.com> wrote: >> >> >> >> On Fri, Jun 27, 2025 at 11:06 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> >>> --- >>> libstdc++-v3/include/std/mdspan | 31 ++++++++ >>> libstdc++-v3/src/c++23/std.cc.in | 3 +- >>> .../23_containers/mdspan/accessors/default.cc | 72 +++++++++++++++++++ >>> .../mdspan/accessors/default_neg.cc | 23 ++++++ >>> 4 files changed, 128 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..ecccda2b68e >>> --- /dev/null >>> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/accessors/default.cc >>> @@ -0,0 +1,72 @@ >>> +// { 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() >>> +{ >>> + >>> static_assert(std::is_nothrow_constructible_v<std::default_accessor<double>, >>> + >>> std::default_accessor<double>>); >> >> Hi, sorry for being unclear before, and resulting in another patch. >> I would like to see a positive test case that cost-adjustment are allowed, >> i.e.: >> + static_assert(std::is_convertible_v<std::default_accessor<double>, >> + std::default_accessor<const double>>); >> And similar for Derived. This is important, as it allows passing mdspan<T> >> to function accepting mdspan<const T>. >>> >>> + 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>>); >>> + static_assert(!std::is_constructible_v<std::default_accessor<int>, >>> + std::default_accessor<unsigned >>> int>>); >>> + 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 >>>