diff options
author | Luc Grosheintz <luc.grosheintz@gmail.com> | 2025-09-04 14:20:29 +0200 |
---|---|---|
committer | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-09-08 09:40:15 +0200 |
commit | 71711f8ac3af615fec197e4eb71d0bee8ef44a23 (patch) | |
tree | 91b900b4bf77dea049d49935f5e67031888775b3 /libstdc++-v3 | |
parent | c440b585ba374b6348ef223e4891a717a1f6660c (diff) | |
download | gcc-71711f8ac3af615fec197e4eb71d0bee8ef44a23.zip gcc-71711f8ac3af615fec197e4eb71d0bee8ef44a23.tar.gz gcc-71711f8ac3af615fec197e4eb71d0bee8ef44a23.tar.bz2 |
libstdc++: Adjust span/mdspan CTAD for P2781R9.
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.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/include/std/span | 3 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc | 22 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc | 23 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/span/deduction.cc | 20 |
4 files changed, 53 insertions, 15 deletions
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index 44f9b36..f9aa3c7 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)>> && 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 8a43a68..9408665 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,23 @@ 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(std::true_type{}, 2), std::dextents<size_t, 2>{1, 2}); + verify(std::extents(std::false_type{}, 2), std::dextents<size_t, 2>{0, 2}); + +#if __glibcxx_constant_wrapper + constexpr auto c2 = std::constant_wrapper<2>{}; + verify(std::extents(c2), std::extents<size_t, 2>{}); + verify(std::extents(1, c2), std::extents<size_t, dyn, 2>{1}); 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<true>, c2), std::extents<size_t, 1, 2>{}); +#endif return true; } @@ -123,7 +133,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 bdfc6eb..ca100b4 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,21 @@ 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)); + verify(std::mdspan(ptr, std::true_type{}, i3), std::extents(1, 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)); + verify(std::mdspan(ptr, std::cw<true>, std::cw<3>), + std::extents(std::cw<1>, i3)); +#endif return true; } @@ -729,8 +738,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 c66db90..e958ad5 100644 --- a/libstdc++-v3/testsuite/23_containers/span/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/span/deduction.cc @@ -82,5 +82,23 @@ test01() static_assert( is_dynamic_span<int>(s12) ); std::span s13(a.data(), std::integral_constant<size_t, 3>{}); - static_assert( is_static_span<long, 3>(s13)); + static_assert( is_static_span<long, 3>(s13) ); + + std::span s14(a.data(), true); + static_assert( is_dynamic_span<long>(s14) ); + + std::span s15(a.data(), std::true_type{}); + static_assert( is_dynamic_span<long>(s15) ); + +#if __glibcxx_constant_wrapper + auto c5 = std::constant_wrapper<5>{}; + std::span s16(a.data(), c5); + static_assert( is_static_span<long, 5>(s16) ); + + std::span s17(a.data(), std::cw<4>); + static_assert( is_static_span<long, 4>(s17) ); + + std::span s18(a.data(), std::cw<true>); + static_assert( is_static_span<long, 1>(s18) ); +#endif } |