From dfab6593b05a65b5a475e0572e101bd56e3a2282 Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Mon, 21 Jul 2025 13:07:37 +0200 Subject: [PATCH] libstdc++: Make the default ctor of mdspan conditionally noexcept. Previously, the default ctor of mdspan was never noexcept, even if all members of mdspan were nothrow default constructible. This commit makes mdspan conditionally nothrow default constructible. A similar strengthening happens in libc++. libstdc++-v3/ChangeLog: * include/std/mdspan (mdspan::mdspan): Make default ctor conditionally noexcept. * testsuite/23_containers/mdspan/mdspan.cc: Add tests. Reviewed-by: Jonathan Wakely Signed-off-by: Luc Grosheintz --- libstdc++-v3/include/std/mdspan | 12 +++--- .../testsuite/23_containers/mdspan/mdspan.cc | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index 89b9f3c8aba..055778d2968 100644 --- a/libstdc++-v3/include/std/mdspan +++ b/libstdc++-v3/include/std/mdspan @@ -1114,11 +1114,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr mdspan() requires (rank_dynamic() > 0) - && is_default_constructible_v + && is_default_constructible_v && is_default_constructible_v - && is_default_constructible_v - : _M_accessor(), _M_mapping(), _M_handle() - { } + && is_default_constructible_v = default; constexpr mdspan(const mdspan& __other) = default; @@ -1307,9 +1305,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION stride(rank_type __r) const { return _M_mapping.stride(__r); } private: - [[no_unique_address]] accessor_type _M_accessor; - [[no_unique_address]] mapping_type _M_mapping; - [[no_unique_address]] data_handle_type _M_handle; + [[no_unique_address]] accessor_type _M_accessor = accessor_type(); + [[no_unique_address]] mapping_type _M_mapping = mapping_type(); + [[no_unique_address]] data_handle_type _M_handle = data_handle_type(); }; template diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc index 942f6d96dca..6ffddd11e95 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc @@ -4,6 +4,7 @@ #include #include "int_like.h" #include "layout_like.h" +#include constexpr auto dyn = std::dynamic_extent; @@ -114,6 +115,27 @@ test_class_properties_all() return true; } +template + class ThrowingDefaultAccessor + { + public: + using element_type = T; + using reference = element_type&; + using data_handle_type = element_type*; + using offset_policy = ThrowingDefaultAccessor; + + ThrowingDefaultAccessor() noexcept(false) + { } + + reference + access(data_handle_type p, size_t i) const + { return p[i]; } + + typename offset_policy::data_handle_type + offset(data_handle_type p, size_t i) const + { return p + i; } + }; + constexpr bool test_default_ctor() { @@ -130,6 +152,18 @@ test_default_ctor() return true; } +template typename Accessor, bool Expected> + constexpr void + test_nothrow_default_ctor() + { + using Extents = std::extents; + using Layout = std::layout_left; + using MDSpan = std::mdspan>; + + static_assert(std::is_default_constructible_v); + static_assert(std::is_nothrow_default_constructible_v == Expected); + } + constexpr bool test_from_other() { @@ -683,6 +717,9 @@ main() test_default_ctor(); static_assert(test_default_ctor()); + test_nothrow_default_ctor(); + test_nothrow_default_ctor(); + test_from_other(); static_assert(test_from_other()); -- 2.47.2