mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
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>
This commit is contained in:
committed by
Tomasz Kamiński
parent
c440b585ba
commit
71711f8ac3
@@ -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)>
|
||||
|
||||
@@ -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(c1, 2), std::extents<size_t, 1, dyn>{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(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user