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
