https://gcc.gnu.org/g:10aa8833b04b52bb1ba3084bc59de604d7c38229

commit r17-564-g10aa8833b04b52bb1ba3084bc59de604d7c38229
Author: Tomasz Kamiński <[email protected]>
Date:   Mon May 18 09:45:46 2026 +0200

    libstdc++: Make is_exhaustive const for layout_(left/right)_padded
    
    This is specified as const in the standard, and required to be 
const-callable
    per layout mapping requirement. This made calls to is_exhaustive on mdspan
    with such layout ill-formed.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/mdspan (layout_left_padded::is_exhaustive)
            (layout_righ_padded::is_exhaustive): Mark as const.
            * testsuite/23_containers/mdspan/layouts/mapping.cc: Test noexcept 
and
            const-invocability for is_exhaustive, is_strided, and is_unique.
            * testsuite/23_containers/mdspan/layouts/padded.cc: Test 
is_exhaustive on
            const mapping..
            * testsuite/23_containers/mdspan/layouts/stride.cc: Likewise.
            * testsuite/23_containers/mdspan/mdspan.cc: Checks 
const-invocability
            for is_exhaustive, is_strided, is_unique.
    
    Reviewed-by: Jonathan Wakely <[email protected]>
    Signed-off-by: Tomasz Kamiński <[email protected]>

Diff:
---
 libstdc++-v3/include/std/mdspan                                | 4 ++--
 libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc | 8 ++++++++
 libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc  | 6 +++---
 libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc  | 2 +-
 libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc          | 6 +++---
 5 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index 5938bf09a940..adc1c0c64219 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -2621,7 +2621,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        { return _PaddedStorage::_M_is_always_exhaustive(); }
 
        constexpr bool
-       is_exhaustive() noexcept
+       is_exhaustive() const noexcept
        { return _M_storage._M_is_exhaustive(); }
 
        static constexpr bool
@@ -2794,7 +2794,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        { return _PaddedStorage::_M_is_always_exhaustive(); }
 
        constexpr bool
-       is_exhaustive() noexcept
+       is_exhaustive() const noexcept
        { return _M_storage._M_is_exhaustive(); }
 
        static constexpr bool
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
index 17cfac54113b..28aa69eca779 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
@@ -44,6 +44,14 @@ template<typename Layout, typename Extents>
     static_assert(M::is_always_strided() && M::is_strided());
     if constexpr (has_static_is_exhaustive<M>)
       static_assert(M::is_always_exhaustive() && M::is_exhaustive());
+
+    static_assert(noexcept(M::is_always_unique()));
+    static_assert(noexcept(M::is_always_strided()));
+    static_assert(noexcept(M::is_always_exhaustive()));
+    static_assert(noexcept(std::declval<const M>().is_unique()));
+    static_assert(noexcept(std::declval<const M>().is_strided()));
+    static_assert(noexcept(std::declval<const M>().is_exhaustive()));
+
     return true;
   }
 
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc
index 1b6e063d12de..18821795355f 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc
@@ -509,7 +509,7 @@ template<template<size_t> typename Layout>
   {
     auto exts = std::extents<int>{};
 
-    auto check = [](auto m)
+    auto check = [](const auto m)
     {
       static_assert(m.is_always_exhaustive());
       VERIFY(m.is_exhaustive());
@@ -529,7 +529,7 @@ constexpr void
     {
       auto check = [](auto exts)
       {
-       auto m = typename PaddedLayout::mapping(exts);
+       const auto m = typename PaddedLayout::mapping(exts);
        static_assert(m.is_always_exhaustive());
        VERIFY(m.is_exhaustive());
       };
@@ -554,7 +554,7 @@ template<template<size_t> typename Layout>
     auto ctrue = std::cw<true>;
     auto cfalse= std::cw<false>;
 
-    auto check = [](auto m, auto static_expected, auto runtime_expected)
+    auto check = [](const auto m, auto static_expected, auto runtime_expected)
     {
       static_assert(m.is_always_exhaustive() == static_expected);
       VERIFY(m.is_exhaustive() == runtime_expected);
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc
index 8d2fad2936f6..94deea33e1cf 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc
@@ -278,7 +278,7 @@ template<typename Extents, typename Strides>
   constexpr void
   test_is_exhaustive(Extents extents, Strides strides, bool expected)
   {
-    std::layout_stride::mapping<Extents> m(extents, strides);
+    const std::layout_stride::mapping<Extents> m(extents, strides);
     VERIFY(m.is_exhaustive() == expected);
 
     bool always_exhaustive = extents.rank() == 0 || m.required_span_size() == 
0;
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
index 62ff7201cce9..a2e244df3c56 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
@@ -720,9 +720,9 @@ template<typename Layout, bool Expected>
     static_assert(noexcept(MDSpan::is_always_exhaustive()) == Expected);
     static_assert(noexcept(MDSpan::is_always_strided()) == Expected);
 
-    static_assert(noexcept(std::declval<MDSpan>().is_unique()) == Expected);
-    static_assert(noexcept(std::declval<MDSpan>().is_exhaustive()) == 
Expected);
-    static_assert(noexcept(std::declval<MDSpan>().is_strided()) == Expected);
+    static_assert(noexcept(std::declval<const MDSpan>().is_unique()) == 
Expected);
+    static_assert(noexcept(std::declval<const MDSpan>().is_exhaustive()) == 
Expected);
+    static_assert(noexcept(std::declval<const MDSpan>().is_strided()) == 
Expected);
   }
 
 int

Reply via email to