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

Reply via email to