[PATCH v1 1/1] libstdc++: Convertibility of rank == 0 layouts, LWG4272.
Luc Grosheintz
luc.grosheintz@gmail.com
Tue Jun 10 19:18:50 GMT 2025
LWG4272 proposes to add the condition that convertibility
from layout_stride::mapping to other mappings requires
convertibility of the extents_types.
libstdc++-v3/ChangeLog:
* include/std/mdspan (layout_left): Apply LWG4272.
(layout_right): ditto.
* testsuite/23_containers/mdspan/layouts/ctors.cc: Add
test to check ctor uniformity at rank == 0. Update test
for old behavior.
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
---
libstdc++-v3/include/std/mdspan | 6 +-
.../23_containers/mdspan/layouts/ctors.cc | 60 ++++++++++++++++++-
2 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index 4a3e863bed5..19ed65161fd 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -564,7 +564,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// noexcept for consistency with other layouts.
template<typename _OExtents>
requires is_constructible_v<extents_type, _OExtents>
- constexpr explicit(extents_type::rank() > 0)
+ constexpr explicit(!(extents_type::rank() == 0
+ && is_convertible_v<_OExtents, extents_type>))
mapping(const layout_stride::mapping<_OExtents>& __other) noexcept
: mapping(__other.extents(), __mdspan::__internal_ctor{})
{ __glibcxx_assert(*this == __other); }
@@ -701,7 +702,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<class _OExtents>
requires is_constructible_v<extents_type, _OExtents>
- constexpr explicit(extents_type::rank() > 0)
+ constexpr explicit(!(extents_type::rank() == 0
+ && is_convertible_v<_OExtents, extents_type>))
mapping(const layout_stride::mapping<_OExtents>& __other) noexcept
: mapping(__other.extents(), __mdspan::__internal_ctor{})
{ __glibcxx_assert(*this == __other); }
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
index 23c0a55dae1..4f36715cfab 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
@@ -321,6 +321,61 @@ namespace from_left_or_right
}
}
+// checks: convertibility of rank == 0 mappings.
+namespace from_rank0
+{
+ template<typename SLayout, typename OLayout, typename SExtents,
+ typename OExtents>
+ constexpr void
+ verify_ctor()
+ {
+ using SMapping = typename SLayout::mapping<SExtents>;
+ using OMapping = typename OLayout::mapping<OExtents>;
+
+ constexpr bool expected = std::is_convertible_v<OExtents, SExtents>;
+ if constexpr (expected)
+ verify_nothrow_convertible<SMapping>(OMapping{});
+ else
+ verify_nothrow_constructible<SMapping>(OMapping{});
+ }
+
+ template<typename Layout, typename OLayout>
+ constexpr void
+ test_rank0_convertibility()
+ {
+ using E1 = std::extents<int>;
+ using E2 = std::extents<unsigned int>;
+
+ verify_ctor<Layout, OLayout, E1, E2>();
+ verify_ctor<Layout, OLayout, E2, E1>();
+
+ verify_ctor<Layout, OLayout, E2, E2>();
+ verify_ctor<Layout, OLayout, E1, E1>();
+ }
+
+ constexpr void
+ test_all()
+ {
+ auto run = []<typename Layout>(Layout)
+ {
+ test_rank0_convertibility<Layout, std::layout_left>();
+ test_rank0_convertibility<Layout, std::layout_right>();
+ test_rank0_convertibility<Layout, std::layout_stride>();
+ };
+
+ auto run_all = [run]()
+ {
+ run(std::layout_left{});
+ run(std::layout_right{});
+ run(std::layout_stride{});
+ return true;
+ };
+
+ run_all();
+ static_assert(run_all());
+ }
+}
+
// ctor: mapping(layout_stride::mapping<OExtents>)
namespace from_stride
{
@@ -381,8 +436,7 @@ namespace from_stride
verify_nothrow_convertible<Layout, std::extents<unsigned int>>(
std::extents<int>{});
- // Rank == 0 doesn't check IndexType for convertibility.
- verify_nothrow_convertible<Layout, std::extents<int>>(
+ verify_nothrow_constructible<Layout, std::extents<int>>(
std::extents<unsigned int>{});
verify_nothrow_constructible<Layout, std::extents<int, 3>>(
@@ -432,5 +486,7 @@ main()
from_left_or_right::test_all<std::layout_left, std::layout_right>();
from_left_or_right::test_all<std::layout_right, std::layout_left>();
+
+ from_rank0::test_all();
return 0;
}
--
2.49.0
More information about the Libstdc++
mailing list