On Wed, 16 Jul 2025, 14:53 Luc Grosheintz, <luc.groshei...@gmail.com> wrote:

> 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.
>

OK for trunk



>         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
>
>

Reply via email to