From 29d53f6213e0a1569aa8ca9db613b48df642986c Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Wed, 16 Jul 2025 15:45:45 +0200 Subject: [PATCH] libstdc++: Fix forwarding of custom IndexType in mdspan [PR121061] MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. Reviewed-by: Jonathan Wakely Reviewed-by: Tomasz Kamiński Signed-off-by: Luc Grosheintz --- 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( - initializer_list{_S_storage::_S_int_cast(__exts)...})) + initializer_list{static_cast<_IndexType>(std::move(__exts))...})) { } template @@ -602,7 +602,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_Indices... __indices) const noexcept { return __mdspan::__linear_index_left(_M_extents, - static_cast(__indices)...); + static_cast(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(__indices)...); + _M_extents, static_cast(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(__indices)...); + static_cast(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(); test_shape_all(); test_shape_all(); + test_shape_all(); test_pack_all(); test_pack_all(); test_pack_all(); + test_pack_all(); + test_pack_all(); 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 @@ -42,6 +43,11 @@ template 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 using IntLike = CustomIndexType; using ThrowingInt = CustomIndexType; using MutatingInt = CustomIndexType; +using RValueInt = CustomIndexType; 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 { test_linear_index_all(); test_linear_index_all(); + test_linear_index_all(); } test_required_span_size_all(); 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(); test_from_int_like(); test_from_int_like(); + test_from_int_like(); test_from_opaque_accessor(); test_from_base_class_accessor(); @@ -705,6 +706,7 @@ main() test_access(); test_access(); test_access(); + test_access(); test_swap(); static_assert(test_swap()); -- 2.47.2