[PATCH] libstdc++: Properly handle forwarding references in __mdspan::__index_type_cast.
Tomasz Kaminski
tkaminsk@redhat.com
Wed Mar 18 14:04:24 GMT 2026
On Tue, Mar 10, 2026 at 4:48 PM Tomasz Kamiński <tkaminsk@redhat.com> wrote:
> The _OIndexType template parameter will maybe deduced to reference, when
> invoked from constructor and operator[]/at (after r16-7645-g66e60479e97640)
> accepting array or span. We need to use forward for class-type and
> remove_cvref_t for is_integral checks.
>
> This resolves LWG4020: extents::index-cast weirdness.
>
> libstdc++-v3/ChangeLog:
>
> * include/std/mdspan (__mdspan::__index_type_cast): Handle
> forwarding referene and use forward for class types.
> * testsuite/23_containers/mdspan/int_like.h (ConstLValueInt)
> (CustomIndexKind::ConstLValue): Define.
> (CustomIndexType): Handle CustomIndexKind::ConstLValue.
> * testsuite/23_containers/mdspan/at.cc: Test with ConstLValueInt.
> * testsuite/23_containers/mdspan/extents/custom_integer.cc:
> Likewise.
> * testsuite/23_containers/mdspan/mdspan.cc: Likewise.
>
> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
> ---
> Tested *mdspan* for all standard mode. Testing on x86_64-linux.
> OK for trunk when all tests passes?
>
> libstdc++-v3/include/std/mdspan | 7 ++++---
> libstdc++-v3/testsuite/23_containers/mdspan/at.cc | 1 +
> .../23_containers/mdspan/extents/custom_integer.cc | 2 ++
> .../testsuite/23_containers/mdspan/int_like.h | 11 +++++++++++
> libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc | 2 ++
> 5 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/mdspan
> b/libstdc++-v3/include/std/mdspan
> index f8847642c80..5e0d52ff695 100644
> --- a/libstdc++-v3/include/std/mdspan
> +++ b/libstdc++-v3/include/std/mdspan
> @@ -80,10 +80,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> return true;
> }
>
> - template<typename _IndexType, typename _OIndexType>
> + template<typename _IndexType, typename _OIndexTypeRef>
> constexpr _IndexType
> - __index_type_cast(_OIndexType&& __other)
> + __index_type_cast(_OIndexTypeRef&& __other)
> {
>
Locally I have added:
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 4020. extents::index-cast weirdnes
> + using _OIndexType = std::remove_cvref_t<_OIndexTypeRef>;
> if constexpr (std::is_integral_v<_OIndexType>)
> {
> constexpr _IndexType __index_type_max
> @@ -100,7 +101,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> }
> else
> {
> - auto __ret = static_cast<_IndexType>(std::move(__other));
> + auto __ret =
> static_cast<_IndexType>(std::forward<_OIndexTypeRef>(__other));
> if constexpr (std::is_signed_v<_IndexType>)
> __glibcxx_assert(__ret >= 0);
> return __ret;
> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/at.cc
> b/libstdc++-v3/testsuite/23_containers/mdspan/at.cc
> index c5a12d12ccc..367398dd078 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/at.cc
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/at.cc
> @@ -116,4 +116,5 @@ main()
> test_at<ThrowingInt, false, false>();
> test_at<MutatingInt, true, false>();
> test_at<RValueInt, true, false>();
> + test_at<ConstLValueInt, false, true>();
> }
> 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 99de4015ef3..4e9669c98d8 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
> @@ -86,11 +86,13 @@ main()
> test_shape_all<ThrowingInt, false>();
> test_shape_all<MutatingInt, false>();
> test_shape_all<RValueInt, false>();
> + test_shape_all<ConstLValueInt, true>();
>
> 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>();
> + test_pack_all<ConstLValueInt, false>();
> 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 b839be73ae9..99ecd155ca4 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
> @@ -7,6 +7,7 @@ enum class CustomIndexKind
> Throwing,
> Mutating,
> RValue,
> + ConstLValue,
> };
>
> template<CustomIndexKind Kind, bool Copyable = false>
> @@ -57,6 +58,15 @@ template<CustomIndexKind Kind, bool Copyable = false>
> requires (Kind == CustomIndexKind::RValue)
> { return value; }
>
> + constexpr
> + operator int() const& noexcept
> + requires (Kind == CustomIndexKind::ConstLValue)
> + { return value; }
> +
> + operator int() const&&
> + requires (Kind == CustomIndexKind::ConstLValue)
> + = delete;
> +
> private:
> int value;
> };
> @@ -65,6 +75,7 @@ using IntLike = CustomIndexType<CustomIndexKind::Const>;
> using ThrowingInt = CustomIndexType<CustomIndexKind::Throwing>;
> using MutatingInt = CustomIndexType<CustomIndexKind::Mutating>;
> using RValueInt = CustomIndexType<CustomIndexKind::RValue>;
> +using ConstLValueInt = CustomIndexType<CustomIndexKind::ConstLValue>;
>
> struct NotIntLike
> { };
> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> index a92a0554417..270b3f18daa 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> @@ -755,6 +755,7 @@ main()
> test_from_int_like<ThrowingInt, false, false>();
> test_from_int_like<MutatingInt, true, false>();
> test_from_int_like<RValueInt, true, false>();
> + test_from_int_like<ConstLValueInt, false, true>();
>
> test_from_opaque_accessor();
> test_from_base_class_accessor();
> @@ -767,6 +768,7 @@ main()
> test_access<ThrowingInt, false, false>();
> test_access<MutatingInt, true, false>();
> test_access<RValueInt, true, false>();
> + test_access<ConstLValueInt, false, true>();
>
> test_swap();
> static_assert(test_swap());
> --
> 2.53.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260318/dc4be9e1/attachment.htm>
More information about the Libstdc++
mailing list