mirror of
https://github.com/gcc-mirror/gcc.git
synced 2025-07-25 16:46:41 +00:00
libstdc++: Fix forwarding of custom IndexType in mdspan [PR121061]
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 <jwakely@redhat.com> Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
This commit is contained in:

committed by
Tomasz Kamiński

parent
1eee843079
commit
29d53f6213
@ -285,7 +285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|| sizeof...(_OIndexTypes) == rank_dynamic())
|
|| sizeof...(_OIndexTypes) == rank_dynamic())
|
||||||
constexpr explicit extents(_OIndexTypes... __exts) noexcept
|
constexpr explicit extents(_OIndexTypes... __exts) noexcept
|
||||||
: _M_exts(span<const _IndexType, sizeof...(_OIndexTypes)>(
|
: _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>
|
template<typename _OIndexType, size_t _Nm>
|
||||||
@ -602,7 +602,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
operator()(_Indices... __indices) const noexcept
|
operator()(_Indices... __indices) const noexcept
|
||||||
{
|
{
|
||||||
return __mdspan::__linear_index_left(_M_extents,
|
return __mdspan::__linear_index_left(_M_extents,
|
||||||
static_cast<index_type>(__indices)...);
|
static_cast<index_type>(std::move(__indices))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool
|
static constexpr bool
|
||||||
@ -741,7 +741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
operator()(_Indices... __indices) const noexcept
|
operator()(_Indices... __indices) const noexcept
|
||||||
{
|
{
|
||||||
return __mdspan::__linear_index_right(
|
return __mdspan::__linear_index_right(
|
||||||
_M_extents, static_cast<index_type>(__indices)...);
|
_M_extents, static_cast<index_type>(std::move(__indices))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool
|
static constexpr bool
|
||||||
@ -963,7 +963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
operator()(_Indices... __indices) const noexcept
|
operator()(_Indices... __indices) const noexcept
|
||||||
{
|
{
|
||||||
return __mdspan::__linear_index_strides(*this,
|
return __mdspan::__linear_index_strides(*this,
|
||||||
static_cast<index_type>(__indices)...);
|
static_cast<index_type>(std::move(__indices))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool
|
static constexpr bool
|
||||||
|
@ -85,9 +85,12 @@ main()
|
|||||||
test_shape_all<IntLike, true>();
|
test_shape_all<IntLike, true>();
|
||||||
test_shape_all<ThrowingInt, false>();
|
test_shape_all<ThrowingInt, false>();
|
||||||
test_shape_all<MutatingInt, false>();
|
test_shape_all<MutatingInt, false>();
|
||||||
|
test_shape_all<RValueInt, false>();
|
||||||
|
|
||||||
test_pack_all<int, true>();
|
test_pack_all<int, true>();
|
||||||
test_pack_all<IntLike, true>();
|
test_pack_all<IntLike, true>();
|
||||||
test_pack_all<ThrowingInt, false>();
|
test_pack_all<ThrowingInt, false>();
|
||||||
|
test_pack_all<MutatingInt, true>();
|
||||||
|
test_pack_all<RValueInt, true>();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ enum class CustomIndexKind
|
|||||||
Const,
|
Const,
|
||||||
Throwing,
|
Throwing,
|
||||||
Mutating,
|
Mutating,
|
||||||
|
RValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
template<CustomIndexKind Kind>
|
template<CustomIndexKind Kind>
|
||||||
@ -42,6 +43,11 @@ template<CustomIndexKind Kind>
|
|||||||
requires (Kind == CustomIndexKind::Mutating)
|
requires (Kind == CustomIndexKind::Mutating)
|
||||||
{ return _M_i; }
|
{ return _M_i; }
|
||||||
|
|
||||||
|
constexpr
|
||||||
|
operator int() && noexcept
|
||||||
|
requires (Kind == CustomIndexKind::RValue)
|
||||||
|
{ return _M_i; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _M_i;
|
int _M_i;
|
||||||
};
|
};
|
||||||
@ -49,6 +55,7 @@ template<CustomIndexKind Kind>
|
|||||||
using IntLike = CustomIndexType<CustomIndexKind::Const>;
|
using IntLike = CustomIndexType<CustomIndexKind::Const>;
|
||||||
using ThrowingInt = CustomIndexType<CustomIndexKind::Throwing>;
|
using ThrowingInt = CustomIndexType<CustomIndexKind::Throwing>;
|
||||||
using MutatingInt = CustomIndexType<CustomIndexKind::Mutating>;
|
using MutatingInt = CustomIndexType<CustomIndexKind::Mutating>;
|
||||||
|
using RValueInt = CustomIndexType<CustomIndexKind::RValue>;
|
||||||
|
|
||||||
struct NotIntLike
|
struct NotIntLike
|
||||||
{ };
|
{ };
|
||||||
|
@ -527,6 +527,7 @@ template<typename Layout>
|
|||||||
{
|
{
|
||||||
test_linear_index_all<Layout, IntLike>();
|
test_linear_index_all<Layout, IntLike>();
|
||||||
test_linear_index_all<Layout, MutatingInt>();
|
test_linear_index_all<Layout, MutatingInt>();
|
||||||
|
test_linear_index_all<Layout, RValueInt>();
|
||||||
}
|
}
|
||||||
|
|
||||||
test_required_span_size_all<Layout>();
|
test_required_span_size_all<Layout>();
|
||||||
|
@ -694,6 +694,7 @@ main()
|
|||||||
test_from_int_like<IntLike, true, true>();
|
test_from_int_like<IntLike, true, true>();
|
||||||
test_from_int_like<ThrowingInt, false, false>();
|
test_from_int_like<ThrowingInt, false, false>();
|
||||||
test_from_int_like<MutatingInt, true, false>();
|
test_from_int_like<MutatingInt, true, false>();
|
||||||
|
test_from_int_like<RValueInt, true, false>();
|
||||||
|
|
||||||
test_from_opaque_accessor();
|
test_from_opaque_accessor();
|
||||||
test_from_base_class_accessor();
|
test_from_base_class_accessor();
|
||||||
@ -705,6 +706,7 @@ main()
|
|||||||
test_access<IntLike, true, true>();
|
test_access<IntLike, true, true>();
|
||||||
test_access<ThrowingInt, false, false>();
|
test_access<ThrowingInt, false, false>();
|
||||||
test_access<MutatingInt, true, false>();
|
test_access<MutatingInt, true, false>();
|
||||||
|
test_access<RValueInt, true, false>();
|
||||||
|
|
||||||
test_swap();
|
test_swap();
|
||||||
static_assert(test_swap());
|
static_assert(test_swap());
|
||||||
|
Reference in New Issue
Block a user