aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Grosheintz <luc.grosheintz@gmail.com>2025-07-16 15:45:44 +0200
committerTomasz Kamiński <tkaminsk@redhat.com>2025-07-17 16:08:58 +0200
commit1eee8430794f790b6d364603685e70d83d8d42f5 (patch)
tree888068bf5403502b9780ca3b50143e395d8b83be
parentb38382e36410a9a649b904a2d0a0abcb90f9c418 (diff)
downloadgcc-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>
-rw-r--r--libstdc++-v3/include/std/mdspan34
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/int_like.h7
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc2
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());