On Mon, Jul 21, 2025 at 2:40 PM Jonathan Wakely <jwakely....@gmail.com> wrote:
> OK > Merged to trunk. > > On Mon, 21 Jul 2025, 12:10 Luc Grosheintz, <luc.groshei...@gmail.com> > wrote: > >> 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. >> >> Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> >> --- >> 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 f71141f43a9..772ee32db06 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<data_handle_type> >> + && is_default_constructible_v<data_handle_type> >> && is_default_constructible_v<mapping_type> >> - && is_default_constructible_v<accessor_type> >> - : _M_accessor(), _M_mapping(), _M_handle() >> - { } >> + && is_default_constructible_v<accessor_type> = default; >> >> constexpr >> mdspan(const mdspan& __other) = default; >> @@ -1306,9 +1304,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<typename _CArray> >> 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 <testsuite_hooks.h> >> #include "int_like.h" >> #include "layout_like.h" >> +#include <stdexcept> >> >> constexpr auto dyn = std::dynamic_extent; >> >> @@ -114,6 +115,27 @@ test_class_properties_all() >> return true; >> } >> >> +template<typename T> >> + 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<template<typename T> typename Accessor, bool Expected> >> + constexpr void >> + test_nothrow_default_ctor() >> + { >> + using Extents = std::extents<int, dyn>; >> + using Layout = std::layout_left; >> + using MDSpan = std::mdspan<double, Extents, Layout, >> Accessor<double>>; >> + >> + static_assert(std::is_default_constructible_v<MDSpan>); >> + static_assert(std::is_nothrow_default_constructible_v<MDSpan> == >> Expected); >> + } >> + >> constexpr bool >> test_from_other() >> { >> @@ -683,6 +717,9 @@ main() >> test_default_ctor(); >> static_assert(test_default_ctor()); >> >> + test_nothrow_default_ctor<std::default_accessor, true>(); >> + test_nothrow_default_ctor<ThrowingDefaultAccessor, false>(); >> + >> test_from_other(); >> static_assert(test_from_other()); >> >> -- >> 2.50.0 >> >>