https://gcc.gnu.org/g:dfab6593b05a65b5a475e0572e101bd56e3a2282

commit r16-2391-gdfab6593b05a65b5a475e0572e101bd56e3a2282
Author: Luc Grosheintz <luc.groshei...@gmail.com>
Date:   Mon Jul 21 13:07:37 2025 +0200

    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 <jwak...@redhat.com>
    Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com>

Diff:
---
 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 89b9f3c8aba7..055778d29688 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;
@@ -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<typename _CArray>
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
index 942f6d96dca7..6ffddd11e951 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());

Reply via email to