The second bug report in PR121061 is that the conversion of custom OtherIndexType to IndexType is incorrectly not done via r-value references.
This commit fixes the forwarding issue, adds a custom IndexType called RValueInt, which only allows conversion to int via r-value reference. PR libstdc++/121061 libstdc++-v3/ChangeLog: * include/std/mdspan (extents::extents): Perform conversion to index_type of an r-value reference. (layout_left::mapping::operator()): Ditto. (layout_right::mapping::operator()): Ditto. (layout_stride::mapping::operator()): Ditto. * testsuite/23_containers/mdspan/extents/custom_integer.cc: Add tests for RValueInt and MutatingInt. * testsuite/23_containers/mdspan/int_like.h (RValueInt): Add. * testsuite/23_containers/mdspan/layouts/mapping.cc: Test with RValueInt. * testsuite/23_containers/mdspan/mdspan.cc: Ditto. Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> --- libstdc++-v3/include/std/mdspan | 8 ++++---- .../23_containers/mdspan/extents/custom_integer.cc | 3 +++ libstdc++-v3/testsuite/23_containers/mdspan/int_like.h | 7 +++++++ .../testsuite/23_containers/mdspan/layouts/mapping.cc | 1 + libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc | 2 ++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index 930997e9536..271fdb5d8c7 100644 --- a/libstdc++-v3/include/std/mdspan +++ b/libstdc++-v3/include/std/mdspan @@ -285,7 +285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION || sizeof...(_OIndexTypes) == rank_dynamic()) constexpr explicit extents(_OIndexTypes... __exts) noexcept : _M_exts(span<const _IndexType, sizeof...(_OIndexTypes)>( - initializer_list{_S_storage::_S_int_cast(__exts)...})) + initializer_list{static_cast<_IndexType>(std::move(__exts))...})) { } template<typename _OIndexType, size_t _Nm> @@ -602,7 +602,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_Indices... __indices) const noexcept { return __mdspan::__linear_index_left(_M_extents, - static_cast<index_type>(__indices)...); + static_cast<index_type>(std::move(__indices))...); } static constexpr bool @@ -741,7 +741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_Indices... __indices) const noexcept { return __mdspan::__linear_index_right( - _M_extents, static_cast<index_type>(__indices)...); + _M_extents, static_cast<index_type>(std::move(__indices))...); } static constexpr bool @@ -963,7 +963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_Indices... __indices) const noexcept { return __mdspan::__linear_index_strides(*this, - static_cast<index_type>(__indices)...); + static_cast<index_type>(std::move(__indices))...); } static constexpr bool 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 92c2ebb46e1..99de4015ef3 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc @@ -85,9 +85,12 @@ main() test_shape_all<IntLike, true>(); test_shape_all<ThrowingInt, false>(); test_shape_all<MutatingInt, false>(); + test_shape_all<RValueInt, false>(); test_pack_all<int, true>(); test_pack_all<IntLike, true>(); test_pack_all<ThrowingInt, false>(); + test_pack_all<MutatingInt, true>(); + test_pack_all<RValueInt, true>(); return 0; } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h index f4f4a773193..310dd8ddf20 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h +++ b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h @@ -6,6 +6,7 @@ enum class CustomIndexKind Const, Throwing, Mutating, + RValue, }; template<CustomIndexKind Kind> @@ -42,6 +43,11 @@ template<CustomIndexKind Kind> requires (Kind == CustomIndexKind::Mutating) { return _M_i; } + constexpr + operator int() && noexcept + requires (Kind == CustomIndexKind::RValue) + { return _M_i; } + private: int _M_i; }; @@ -49,6 +55,7 @@ template<CustomIndexKind Kind> using IntLike = CustomIndexType<CustomIndexKind::Const>; using ThrowingInt = CustomIndexType<CustomIndexKind::Throwing>; using MutatingInt = CustomIndexType<CustomIndexKind::Mutating>; +using RValueInt = CustomIndexType<CustomIndexKind::RValue>; 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 6742fa11a51..58bce514435 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc @@ -527,6 +527,7 @@ template<typename Layout> { test_linear_index_all<Layout, IntLike>(); test_linear_index_all<Layout, MutatingInt>(); + test_linear_index_all<Layout, RValueInt>(); } test_required_span_size_all<Layout>(); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc index 22ec68ea2d1..be4a1b1c17e 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc @@ -694,6 +694,7 @@ main() test_from_int_like<IntLike, true, true>(); test_from_int_like<ThrowingInt, false, false>(); test_from_int_like<MutatingInt, true, false>(); + test_from_int_like<RValueInt, true, false>(); test_from_opaque_accessor(); test_from_base_class_accessor(); @@ -705,6 +706,7 @@ main() test_access<IntLike, true, true>(); test_access<ThrowingInt, false, false>(); test_access<MutatingInt, true, false>(); + test_access<RValueInt, true, false>(); test_swap(); static_assert(test_swap()); -- 2.50.0