diff options
author | Luc Grosheintz <luc.grosheintz@gmail.com> | 2025-07-16 15:45:44 +0200 |
---|---|---|
committer | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-07-17 16:08:58 +0200 |
commit | 1eee8430794f790b6d364603685e70d83d8d42f5 (patch) | |
tree | 888068bf5403502b9780ca3b50143e395d8b83be | |
parent | b38382e36410a9a649b904a2d0a0abcb90f9c418 (diff) | |
download | gcc-1eee8430794f790b6d364603685e70d83d8d42f5.zip gcc-1eee8430794f790b6d364603685e70d83d8d42f5.tar.gz gcc-1eee8430794f790b6d364603685e70d83d8d42f5.tar.bz2 |
libstdc++: Fix constraint for custom integer types in mdspan [PR121061]
PR121061 consists of two bugs for mdspan related code. This commit fixes
the first one. Namely, when passing custom IndexType as an array or
span, the conversion to int must be const. Prior to this commit the
constraint incorrectly also allowed non-const conversion. This commit
updates all related constraints to check
__valid_index_type<const OtherIndexType&, index_type>
in those cases. Also adds a MutatingInt to int_like.h which only
supports non-const conversion to int and updates the tests.
PR libstdc++/121061
libstdc++-v3/ChangeLog:
* include/std/mdspan (extents::extents): Fix constraint to
prevent non-const conversion to index_type.
(layout_stride::mapping::mapping): Ditto.
(mdspan::mdspan): Ditto.
(mdspan::operator[]): Ditto.
* testsuite/23_containers/mdspan/extents/custom_integer.cc: Add
test for MutatingInt.
* testsuite/23_containers/mdspan/int_like.h (MutatingInt): Add.
* testsuite/23_containers/mdspan/layouts/mapping.cc: Add test for
MutatingInt.
* testsuite/23_containers/mdspan/layouts/stride.cc: Ditto.
* testsuite/23_containers/mdspan/mdspan.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>
6 files changed, 34 insertions, 14 deletions
diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index b34116a..930997e 100644 --- a/libstdc++-v3/include/std/mdspan +++ b/libstdc++-v3/include/std/mdspan @@ -288,15 +288,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION initializer_list{_S_storage::_S_int_cast(__exts)...})) { } - template<__mdspan::__valid_index_type<index_type> _OIndexType, size_t _Nm> - requires (_Nm == rank() || _Nm == rank_dynamic()) + template<typename _OIndexType, size_t _Nm> + requires __mdspan::__valid_index_type<const _OIndexType&, index_type> + && (_Nm == rank() || _Nm == rank_dynamic()) constexpr explicit(_Nm != rank_dynamic()) extents(span<_OIndexType, _Nm> __exts) noexcept : _M_exts(span<const _OIndexType, _Nm>(__exts)) { } - template<__mdspan::__valid_index_type<index_type> _OIndexType, size_t _Nm> - requires (_Nm == rank() || _Nm == rank_dynamic()) + template<typename _OIndexType, size_t _Nm> + requires __mdspan::__valid_index_type<const _OIndexType&, index_type> + && (_Nm == rank() || _Nm == rank_dynamic()) constexpr explicit(_Nm != rank_dynamic()) extents(const array<_OIndexType, _Nm>& __exts) noexcept : _M_exts(span<const _OIndexType, _Nm>(__exts)) @@ -878,7 +880,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr mapping(const mapping&) noexcept = default; - template<__mdspan::__valid_index_type<index_type> _OIndexType> + template<typename _OIndexType> + requires __mdspan::__valid_index_type<const _OIndexType&, index_type> constexpr mapping(const extents_type& __exts, span<_OIndexType, extents_type::rank()> __strides) noexcept @@ -888,7 +891,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_strides[__i] = index_type(as_const(__strides[__i])); } - template<__mdspan::__valid_index_type<index_type> _OIndexType> + template<typename _OIndexType> + requires __mdspan::__valid_index_type<const _OIndexType&, index_type> constexpr mapping(const extents_type& __exts, const array<_OIndexType, extents_type::rank()>& __strides) @@ -1134,9 +1138,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_handle(std::move(__handle)) { } - template<__mdspan::__valid_index_type<index_type> _OIndexType, - size_t _Nm> - requires (_Nm == rank() || _Nm == rank_dynamic()) + template<typename _OIndexType, size_t _Nm> + requires __mdspan::__valid_index_type<const _OIndexType&, index_type> + && (_Nm == rank() || _Nm == rank_dynamic()) && is_constructible_v<mapping_type, extents_type> && is_default_constructible_v<accessor_type> constexpr explicit(_Nm != rank_dynamic()) @@ -1145,9 +1149,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_handle(std::move(__handle)) { } - template<__mdspan::__valid_index_type<index_type> _OIndexType, - size_t _Nm> - requires (_Nm == rank() || _Nm == rank_dynamic()) + template<typename _OIndexType, size_t _Nm> + requires __mdspan::__valid_index_type<const _OIndexType&, index_type> + && (_Nm == rank() || _Nm == rank_dynamic()) && is_constructible_v<mapping_type, extents_type> && is_default_constructible_v<accessor_type> constexpr explicit(_Nm != rank_dynamic()) @@ -1218,7 +1222,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _M_accessor.access(_M_handle, __index); } - template<__mdspan::__valid_index_type<index_type> _OIndexType> + template<typename _OIndexType> + requires __mdspan::__valid_index_type<const _OIndexType&, index_type> constexpr reference operator[](span<_OIndexType, rank()> __indices) const { @@ -1228,7 +1233,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __call(make_index_sequence<rank()>()); } - template<__mdspan::__valid_index_type<index_type> _OIndexType> + template<typename _OIndexType> + requires __mdspan::__valid_index_type<const _OIndexType&, index_type> constexpr reference operator[](const array<_OIndexType, rank()>& __indices) const { return (*this)[span<const _OIndexType, rank()>(__indices)]; } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc index 4f63181..92c2ebb 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc @@ -84,6 +84,7 @@ main() test_shape_all<int, true>(); test_shape_all<IntLike, true>(); test_shape_all<ThrowingInt, false>(); + test_shape_all<MutatingInt, false>(); test_pack_all<int, true>(); test_pack_all<IntLike, true>(); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h index ed45375..f4f4a77 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h +++ b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h @@ -5,6 +5,7 @@ enum class CustomIndexKind { Const, Throwing, + Mutating, }; template<CustomIndexKind Kind> @@ -36,12 +37,18 @@ template<CustomIndexKind Kind> requires (Kind == CustomIndexKind::Throwing) { return _M_i; } + constexpr + operator int() noexcept + requires (Kind == CustomIndexKind::Mutating) + { return _M_i; } + private: int _M_i; }; using IntLike = CustomIndexType<CustomIndexKind::Const>; using ThrowingInt = CustomIndexType<CustomIndexKind::Throwing>; +using MutatingInt = CustomIndexType<CustomIndexKind::Mutating>; struct NotIntLike { }; diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc index 17f0c00..6742fa1 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc @@ -180,6 +180,7 @@ template<typename Layout> static_assert(has_linear_index<Mapping, int>); static_assert(has_linear_index<Mapping, double>); static_assert(has_linear_index<Mapping, IntLike>); + static_assert(has_linear_index<Mapping, MutatingInt>); static_assert(!has_linear_index<Mapping, ThrowingInt>); static_assert(!has_linear_index<Mapping, NotIntLike>); static_assert(!has_linear_index<Mapping, int, int>); @@ -194,6 +195,7 @@ template<typename Layout> static_assert(has_linear_index<Mapping, int, int>); static_assert(has_linear_index<Mapping, double, double>); static_assert(has_linear_index<Mapping, IntLike, int>); + static_assert(has_linear_index<Mapping, MutatingInt, int>); static_assert(!has_linear_index<Mapping, ThrowingInt, int>); static_assert(!has_linear_index<Mapping, NotIntLike, int>); static_assert(!has_linear_index<Mapping, int, int, int>); @@ -524,6 +526,7 @@ template<typename Layout> if !consteval { test_linear_index_all<Layout, IntLike>(); + test_linear_index_all<Layout, MutatingInt>(); } test_required_span_size_all<Layout>(); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc index 1267306..8d2fad2 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc @@ -65,6 +65,7 @@ test_stride_constructible_all() test_stride_constructible<E0, E0, int, 0, true>(); test_stride_constructible<E0, E0, IntLike, 0, true>(); test_stride_constructible<E0, E0, ThrowingInt, 0, false>(); + test_stride_constructible<E0, E0, MutatingInt, 0, false>(); test_stride_constructible<E0, E0, NotIntLike, 0, false>(); test_stride_constructible<E1, E1, int, 1, true>(); test_stride_constructible<E2, E1, int, 1, true>(); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc index adabb0c..22ec68ea 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc @@ -693,6 +693,7 @@ main() static_assert(test_from_int_like<int, true, true>()); test_from_int_like<IntLike, true, true>(); test_from_int_like<ThrowingInt, false, false>(); + test_from_int_like<MutatingInt, true, false>(); test_from_opaque_accessor(); test_from_base_class_accessor(); @@ -703,6 +704,7 @@ main() static_assert(test_access<int, true, true>()); test_access<IntLike, true, true>(); test_access<ThrowingInt, false, false>(); + test_access<MutatingInt, true, false>(); test_swap(); static_assert(test_swap()); |