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

Reply via email to