OK 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 > >