On Wed, Sep 3, 2025 at 6:11 PM Luc Grosheintz <[email protected]> wrote:
> > > On 9/2/25 10:21, Tomasz Kaminski wrote: > > On Tue, Sep 2, 2025 at 10:15 AM Luc Grosheintz <[email protected] > > > > 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 <[email protected]> > >> --- > >> 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 > >> > >> > > > >
