On Wed, 18 Mar 2026 at 14:06, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> On Tue, Mar 10, 2026 at 4:48 PM Tomasz Kamiński <[email protected]> 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 <[email protected]>
>> ---
>> 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
OK, thanks
>>
>> + 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
>>