[PATCH v1 2/2] libstdc++: Make the default ctor of mdspan conditionally noexcept.
Luc Grosheintz
luc.grosheintz@gmail.com
Mon Jul 21 11:07:37 GMT 2025
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.grosheintz@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
More information about the Libstdc++
mailing list