On Wed, 4 Jun 2025 at 16:22, Luc Grosheintz <[email protected]> wrote:
>
> [mdspan.layout.left.cons] of N4950 states that this ctor is not
> noexcept. Since, all other ctors of layout_left, layout_right or
> layout_stride are noexcept, the choice was made, based on
> [res.on.exception.handling], to make this ctor noexcept.
>
> Two other major standard library implementations make the same choice.
>
> libstdc++-v3/ChangeLog:
>
> * include/std/mdspan (layout_left): Strengthen the exception
> guarantees of layout_left::mapping(layout_stride::mapping).
> * testsuite/23_containers/mdspan/layouts/ctors.cc:
> Simplify tests to reflect the change.
>
> Signed-off-by: Luc Grosheintz <[email protected]>
OK for trunk
> ---
> libstdc++-v3/include/std/mdspan | 3 +-
> .../23_containers/mdspan/layouts/ctors.cc | 33 ++++++++-----------
> 2 files changed, 16 insertions(+), 20 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
> index fe182c35a55..4a3e863bed5 100644
> --- a/libstdc++-v3/include/std/mdspan
> +++ b/libstdc++-v3/include/std/mdspan
> @@ -561,10 +561,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> : mapping(__other.extents(), __mdspan::__internal_ctor{})
> { }
>
> + // noexcept for consistency with other layouts.
> template<typename _OExtents>
> requires is_constructible_v<extents_type, _OExtents>
> constexpr explicit(extents_type::rank() > 0)
> - mapping(const layout_stride::mapping<_OExtents>& __other)
> + 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 92507a8e769..23c0a55dae1 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
> @@ -339,30 +339,24 @@ namespace from_stride
>
> template<typename Layout, typename Extents, typename OExtents>
> constexpr void
> - verify_convertible(OExtents oexts)
> + verify_nothrow_convertible(OExtents oexts)
> {
> using Mapping = typename Layout::mapping<Extents>;
> using OMapping = std::layout_stride::mapping<OExtents>;
>
> constexpr auto other = OMapping(oexts,
> strides(Mapping(Extents(oexts))));
> - if constexpr (std::is_same_v<Layout, std::layout_right>)
> - ::verify_nothrow_convertible<Mapping>(other);
> - else
> - ::verify_convertible<Mapping>(other);
> + ::verify_nothrow_convertible<Mapping>(other);
> }
>
> template<typename Layout, typename Extents, typename OExtents>
> constexpr void
> - verify_constructible(OExtents oexts)
> + verify_nothrow_constructible(OExtents oexts)
> {
> using Mapping = typename Layout::mapping<Extents>;
> using OMapping = std::layout_stride::mapping<OExtents>;
>
> constexpr auto other = OMapping(oexts,
> strides(Mapping(Extents(oexts))));
> - if constexpr (std::is_same_v<Layout, std::layout_right>)
> - ::verify_nothrow_constructible<Mapping>(other);
> - else
> - ::verify_constructible<Mapping>(other);
> + ::verify_nothrow_constructible<Mapping>(other);
> }
>
> template<typename Layout>
> @@ -381,31 +375,32 @@ namespace from_stride
> typename Layout::mapping<std::extents<int, 2>>,
> std::layout_stride::mapping<std::extents<int, 1>>>();
>
> - verify_convertible<Layout, std::extents<int>>(std::extents<int>{});
> + verify_nothrow_convertible<Layout, std::extents<int>>(
> + std::extents<int>{});
>
> - verify_convertible<Layout, std::extents<unsigned int>>(
> + verify_nothrow_convertible<Layout, std::extents<unsigned int>>(
> std::extents<int>{});
>
> // Rank == 0 doesn't check IndexType for convertibility.
> - verify_convertible<Layout, std::extents<int>>(
> + verify_nothrow_convertible<Layout, std::extents<int>>(
> std::extents<unsigned int>{});
>
> - verify_constructible<Layout, std::extents<int, 3>>(
> + verify_nothrow_constructible<Layout, std::extents<int, 3>>(
> std::extents<int, 3>{});
>
> - verify_constructible<Layout, std::extents<unsigned int, 3>>(
> + verify_nothrow_constructible<Layout, std::extents<unsigned int, 3>>(
> std::extents<int, 3>{});
>
> - verify_constructible<Layout, std::extents<int, 3>>(
> + verify_nothrow_constructible<Layout, std::extents<int, 3>>(
> std::extents<unsigned int, 3>{});
>
> - verify_constructible<Layout, std::extents<int, 3, 5>>(
> + verify_nothrow_constructible<Layout, std::extents<int, 3, 5>>(
> std::extents<int, 3, 5>{});
>
> - verify_constructible<Layout, std::extents<unsigned int, 3, 5>>(
> + verify_nothrow_constructible<Layout, std::extents<unsigned int, 3, 5>>(
> std::extents<int, 3, 5>{});
>
> - verify_constructible<Layout, std::extents<int, 3, 5>>(
> + verify_nothrow_constructible<Layout, std::extents<int, 3, 5>>(
> std::extents<unsigned int, 3, 5>{});
> return true;
> }
> --
> 2.49.0
>