[PATCH v2 3/3] libstdc++: Adjust span/mdspan CTAD for P2781R9.
Tomasz Kaminski
tkaminsk@redhat.com
Thu Sep 4 07:39:39 GMT 2025
On Wed, Sep 3, 2025 at 6:11 PM Luc Grosheintz <luc.grosheintz@gmail.com>
wrote:
>
>
> On 9/2/25 10:21, Tomasz Kaminski wrote:
> > On Tue, Sep 2, 2025 at 10:15 AM Luc Grosheintz <luc.grosheintz@gmail.com
> >
> > wrote:
> >
> >> A usecase for P2781R9 is more ergonomic creation of span and mdspan with
> >> mixed static and dynamic extents, e.g.:
> >>
> >> span(ptr, cw<3>)
> >> extents(cw<3>, 5, cw<7>)
> >> mdspan(ptr, cw<3>, 5, cw<7>)
> >>
> >> should be deduced as:
> >> span<..., 3>
> >> extents<..., 3, dyn, 7>
> >> mdspan<..., extents<..., 3, dyn, 7>>
> >>
> >> The change required is to strip cv-qualifiers and references from
> >> `_Tp::value`, because of:
> >>
> >> template<_CwFixedValue _X, typename>
> >> struct constant_wrapper : _CwOperators
> >> {
> >> static constexpr const auto& value = _X._M_data;
> >>
> >> libstdc++-v3/ChangeLog:
> >>
> >> * include/std/span (__integral_constant_like): Allow the member
> >> `value` of a constant wrapping type to be a const reference of
> >> an integer.
> >> * testsuite/23_containers/mdspan/extents/misc.cc: Add test for
> >> cw and constant_wrapper.
> >> * testsuite/23_containers/mdspan/mdspan.cc: Ditto.
> >> * testsuite/23_containers/span/deduction.cc: Ditto.
> >>
> >> Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
> >> ---
> >> libstdc++-v3/include/std/span | 3 ++-
> >> .../23_containers/mdspan/extents/misc.cc | 20 +++++++++++++------
> >> .../testsuite/23_containers/mdspan/mdspan.cc | 20 ++++++++++++-------
> >> .../testsuite/23_containers/span/deduction.cc | 10 ++++++++++
> >> 4 files changed, 39 insertions(+), 14 deletions(-)
> >>
> >> diff --git a/libstdc++-v3/include/std/span
> b/libstdc++-v3/include/std/span
> >> index 44f9b36a7ef..f9aa3c77e8e 100644
> >> --- a/libstdc++-v3/include/std/span
> >> +++ b/libstdc++-v3/include/std/span
> >> @@ -480,7 +480,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >> namespace __detail
> >> {
> >> template<typename _Tp>
> >> - concept __integral_constant_like =
> >> is_integral_v<decltype(_Tp::value)>
> >> + concept __integral_constant_like =
> >> + is_integral_v<remove_cvref_t<decltype(_Tp::value)>>
> >> && !is_same_v<bool, remove_const_t<decltype(_Tp::value)>>
> >>
> > On the last LWG telecon we have noticed, that this was not updated to
> > remove_cvref_t above,
> > and in consequence I believe, that:
> > span(ptr, true_type{}); // does not work, it is not integral constant
> like
> > span(ptr, cw<true>); // works,
> >
> > Could you add test like above, and let me know what are the result, so I
> > can report back?
> > Do not send an v3 yet, until I will finish review.
>
> I believe the resolution is to include the change you mention. Previously,
> we've marked deviations with _GLIBCXX_RESOLVE_LIB_DEFECTS. Do we have a
> number?
>
Hi,
The issue was only raised on mailing discussion, it does not have issue
number yet,
so for the moment let's implement what is in the standard. I just wanted to
check if my
head compiler agrees with GCC.
>
> >
> >> && convertible_to<_Tp, decltype(_Tp::value)>
> >> && equality_comparable_with<_Tp, decltype(_Tp::value)>
> >> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
> >> b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
> >> index 8a43a682004..018c4f95930 100644
> >> --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
> >> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
> >> @@ -98,7 +98,7 @@ test_deduction(Extents... exts)
> >> }
> >>
> >> constexpr bool
> >> -test_integral_constant_deduction()
> >> +test_deduction_from_constant()
> >> {
> >> auto verify = [](auto actual, auto expected)
> >> {
> >> @@ -106,13 +106,21 @@ test_integral_constant_deduction()
> >> VERIFY(actual == expected);
> >> };
> >>
> >> - constexpr auto c1 = std::integral_constant<size_t, 1>{};
> >> - constexpr auto c2 = std::integral_constant<int, 2>{};
> >> + constexpr auto i1 = std::integral_constant<size_t, 1>{};
> >> + constexpr auto i2 = std::integral_constant<int, 2>{};
> >>
> >> verify(std::extents(1), std::extents<size_t, dyn>{1});
> >> - verify(std::extents(c1), std::extents<size_t, 1>{});
> >> + verify(std::extents(i1), std::extents<size_t, 1>{});
> >> + verify(std::extents(i2), std::extents<size_t, 2>{});
> >> + verify(std::extents(i1, 2), std::extents<size_t, 1, dyn>{2});
> >> +
> >> +#if __glibcxx_constant_wrapper
> >> + constexpr auto c2 = std::constant_wrapper<2>{};
> >> verify(std::extents(c2), std::extents<size_t, 2>{});
> >> - verify(std::extents(c1, 2), std::extents<size_t, 1, dyn>{2});
> >> + verify(std::extents(1, c2), std::extents<size_t, dyn, 2>{1});
> >> + verify(std::extents(std::cw<2>), std::extents<size_t, 2>{});
> >> + verify(std::extents(1, std::cw<2>), std::extents<size_t, dyn, 2>{1});
> >> +#endif
> >> return true;
> >> }
> >>
> >> @@ -123,7 +131,7 @@ test_deduction_all()
> >> test_deduction<1>(1);
> >> test_deduction<2>(1.0, 2.0f);
> >> test_deduction<3>(int(1), short(2), size_t(3));
> >> - test_integral_constant_deduction();
> >> + test_deduction_from_constant();
> >> return true;
> >> }
> >>
> >> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> >> b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> >> index bdfc6ebcf56..2583047413c 100644
> >> --- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> >> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> >> @@ -280,7 +280,7 @@ test_from_pointer_and_shape()
> >> }
> >>
> >> constexpr bool
> >> -test_from_pointer_and_integral_constant()
> >> +test_from_pointer_and_constant()
> >> {
> >> std::array<double, 6> buffer{};
> >> double * ptr = buffer.data();
> >> @@ -292,12 +292,18 @@ test_from_pointer_and_integral_constant()
> >> VERIFY(actual.extents() == expected.extents());
> >> };
> >>
> >> - auto c3 = std::integral_constant<int, 3>{};
> >> - auto c6 = std::integral_constant<int, 6>{};
> >> + auto i3 = std::integral_constant<int, 3>{};
> >> + auto i6 = std::integral_constant<int, 6>{};
> >>
> >> verify(std::mdspan(ptr, 6), std::extents(6));
> >> - verify(std::mdspan(ptr, c6), std::extents(c6));
> >> - verify(std::mdspan(ptr, 2, c3), std::extents(2, c3));
> >> + verify(std::mdspan(ptr, i6), std::extents(i6));
> >> + verify(std::mdspan(ptr, 2, i3), std::extents(2, i3));
> >> +
> >> +#if __glibcxx_constant_wrapper
> >> + auto c3 = std::constant_wrapper<3>{};
> >> + verify(std::mdspan(ptr, 2, c3), std::extents(2, i3));
> >> + verify(std::mdspan(ptr, 2, std::cw<3>), std::extents(2, i3));
> >> +#endif
> >> return true;
> >> }
> >>
> >> @@ -729,8 +735,8 @@ main()
> >> test_from_pointer_and_shape();
> >> static_assert(test_from_pointer_and_shape());
> >>
> >> - test_from_pointer_and_integral_constant();
> >> - static_assert(test_from_pointer_and_integral_constant());
> >> + test_from_pointer_and_constant();
> >> + static_assert(test_from_pointer_and_constant());
> >>
> >> test_from_extents();
> >> static_assert(test_from_extents());
> >> diff --git a/libstdc++-v3/testsuite/23_containers/span/deduction.cc
> >> b/libstdc++-v3/testsuite/23_containers/span/deduction.cc
> >> index c66db90222e..0d045505bed 100644
> >> --- a/libstdc++-v3/testsuite/23_containers/span/deduction.cc
> >> +++ b/libstdc++-v3/testsuite/23_containers/span/deduction.cc
> >> @@ -83,4 +83,14 @@ test01()
> >>
> >> std::span s13(a.data(), std::integral_constant<size_t, 3>{});
> >> static_assert( is_static_span<long, 3>(s13));
> >> +
> >> +#if __glibcxx_constant_wrapper
> >> + auto c5 = std::constant_wrapper<5>{};
> >> +
> >> + std::span s14(a.data(), std::cw<4>);
> >> + static_assert( is_static_span<long, 4>(s14));
> >> +
> >> + std::span s15(a.data(), c5);
> >> + static_assert( is_static_span<long, 5>(s15));
> >> +#endif
> >> }
> >> --
> >> 2.51.0
> >>
> >>
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250904/0be7da7c/attachment.htm>
More information about the Libstdc++
mailing list