https://gcc.gnu.org/g:828ac566b7c6356ff94dc6153b278b8e0fa26981
commit r16-5458-g828ac566b7c6356ff94dc6153b278b8e0fa26981 Author: Luc Grosheintz <[email protected]> Date: Tue Nov 18 15:24:52 2025 +0100 libstdc++: Prepare mdspan-related code for submdspan. The changes needed for submdspan are: * In submdspan related code the user-defined integer-like types need to be copy- and move-constructable. * The traits for writing tests that work with both left- and right, possibly padded, layouts will also be useful for submdspan. Therefore, this code is moved up and generalized. * Move __offset further up in <mdspan> and fix some formatting mistakes. libstdc++-v3/ChangeLog: * include/std/mdspan: Improve formatting and placement. * testsuite/23_containers/mdspan/int_like.h: Optionally, add move- and copy-ctors. * testsuite/23_containers/mdspan/layouts/padded_traits.h: Move to... * testsuite/23_containers/mdspan/layout_traits.h: ...here. * testsuite/23_containers/mdspan/layouts/ctors.cc: Fix include. * testsuite/23_containers/mdspan/layouts/mapping.cc: Ditto. * testsuite/23_containers/mdspan/layouts/padded.cc: Ditto. * testsuite/23_containers/mdspan/layouts/padded_neg.cc: Ditto. Reviewed-by: Jonathan Wakely <[email protected]> Reviewed-by: Tomasz KamiĆski <[email protected]> Signed-off-by: Luc Grosheintz <[email protected]> Diff: --- libstdc++-v3/include/std/mdspan | 49 ++++++++-------- .../testsuite/23_containers/mdspan/int_like.h | 25 ++++++--- .../{layouts/padded_traits.h => layout_traits.h} | 65 ++++++++++++++++++---- .../23_containers/mdspan/layouts/ctors.cc | 2 +- .../23_containers/mdspan/layouts/mapping.cc | 2 +- .../23_containers/mdspan/layouts/padded.cc | 2 +- .../23_containers/mdspan/layouts/padded_neg.cc | 2 +- 7 files changed, 101 insertions(+), 46 deletions(-) diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan index bd7a2a201a74..f02a9defad3a 100644 --- a/libstdc++-v3/include/std/mdspan +++ b/libstdc++-v3/include/std/mdspan @@ -345,7 +345,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline constexpr full_extent_t full_extent{}; template<typename _OffsetType, typename _ExtentType, typename _StrideType> - struct strided_slice { + struct strided_slice + { static_assert(__is_standard_integer<_OffsetType>::value || __detail::__integral_constant_like<_OffsetType>); static_assert(__is_standard_integer<_ExtentType>::value @@ -368,7 +369,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [[no_unique_address]] _Mapping mapping = _Mapping(); size_t offset{}; }; -#endif +#endif // __glibcxx_submdspan template<typename _IndexType, size_t... _Extents> class extents @@ -553,7 +554,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __fwd_prod(const _Extents& __exts, size_t __begin, size_t __end) noexcept { size_t __sta_prod = [__begin, __end] { - span<const size_t> __sta_exts = __static_extents<_Extents>(__begin, __end); + span<const size_t> __sta_exts + = __static_extents<_Extents>(__begin, __end); size_t __ret = 1; for(auto __ext : __sta_exts) if (__ext != dynamic_extent) @@ -769,7 +771,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Layout, typename _Mapping> concept __mapping_of = - is_same_v<typename _Layout::template mapping<typename _Mapping::extents_type>, + is_same_v<typename _Layout::template mapping< + typename _Mapping::extents_type>, _Mapping>; template<template<size_t> typename _Layout, typename _Mapping> @@ -804,6 +807,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // A tag type to create internal ctors. class __internal_ctor { }; + + template<typename _Mapping> + constexpr typename _Mapping::index_type + __offset(const _Mapping& __m) noexcept + { + using _IndexType = typename _Mapping::index_type; + constexpr auto __rank = _Mapping::extents_type::rank(); + + if constexpr (__standardized_mapping<_Mapping>) + return 0; + else if (__empty(__m.extents())) + return 0; + else + { + auto __impl = [&__m]<size_t... _Counts>(index_sequence<_Counts...>) + { return __m(((void) _Counts, _IndexType(0))...); }; + return __impl(make_index_sequence<__rank>()); + } + } } template<typename _Extents> @@ -1136,25 +1158,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool_constant<_Mp::is_always_unique()>::value; }; - template<typename _Mapping> - constexpr typename _Mapping::index_type - __offset(const _Mapping& __m) noexcept - { - using _IndexType = typename _Mapping::index_type; - constexpr auto __rank = _Mapping::extents_type::rank(); - - if constexpr (__standardized_mapping<_Mapping>) - return 0; - else if (__empty(__m.extents())) - return 0; - else - { - auto __impl = [&__m]<size_t... _Counts>(index_sequence<_Counts...>) - { return __m(((void) _Counts, _IndexType(0))...); }; - return __impl(make_index_sequence<__rank>()); - } - } - template<typename _Mapping, typename... _Indices> constexpr typename _Mapping::index_type __linear_index_strides(const _Mapping& __m, _Indices... __indices) diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h index e9172c134559..2f79b9dd3b55 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h +++ b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h @@ -9,7 +9,7 @@ enum class CustomIndexKind RValue, }; -template<CustomIndexKind Kind> +template<CustomIndexKind Kind, bool Copyable = false> class CustomIndexType { public: @@ -18,15 +18,24 @@ template<CustomIndexKind Kind> : value(i) { } - CustomIndexType() = delete; - CustomIndexType(const CustomIndexType&) = delete; - CustomIndexType(CustomIndexType&&) = delete; + CustomIndexType() requires(Copyable) = default; + CustomIndexType() requires(!Copyable) = delete; - const CustomIndexType& - operator=(const CustomIndexType&) = delete; + CustomIndexType(const CustomIndexType&) requires(Copyable) = default; + CustomIndexType(const CustomIndexType&) requires(!Copyable) = delete; - const CustomIndexType& - operator=(CustomIndexType&&) = delete; + CustomIndexType(CustomIndexType&&) requires(Copyable) = default; + CustomIndexType(CustomIndexType&&) requires(!Copyable) = delete; + + CustomIndexType& + operator=(const CustomIndexType&) requires(Copyable) = default; + CustomIndexType& + operator=(const CustomIndexType&) requires(!Copyable) = delete; + + CustomIndexType& + operator=(CustomIndexType&&) requires(Copyable) = default; + CustomIndexType& + operator=(CustomIndexType&&) requires(!Copyable) = delete; constexpr operator int() const noexcept diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_traits.h b/libstdc++-v3/testsuite/23_containers/mdspan/layout_traits.h similarity index 70% rename from libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_traits.h rename to libstdc++-v3/testsuite/23_containers/mdspan/layout_traits.h index 788ae82fcc49..619cab53b9e7 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_traits.h +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layout_traits.h @@ -1,8 +1,14 @@ -#ifndef TEST_MDSPAN_PADDED_TRAITS_H -#define TEST_MDSPAN_PADDED_TRAITS_H +#ifndef TEST_MDSPAN_LAYOUT_TRAITS_H +#define TEST_MDSPAN_LAYOUT_TRAITS_H #include <algorithm> +enum class PaddingSide +{ + Left, + Right +}; + template<typename Layout> constexpr static bool is_left_padded = false; @@ -26,6 +32,18 @@ template<typename Layout> is_padded_layout = is_left_padded<Layout> || is_right_padded<Layout>; #if __cplusplus > 202302L +template<PaddingSide Side, typename Layout> + constexpr bool + is_same_padded; + +template<typename Layout> + constexpr bool + is_same_padded<PaddingSide::Left, Layout> = is_left_padded<Layout>; + +template<typename Layout> + constexpr bool + is_same_padded<PaddingSide::Right, Layout> = is_right_padded<Layout>; + template<typename Extents> constexpr auto dynamic_extents_array(const Extents& exts) @@ -36,12 +54,6 @@ template<typename Extents> return ret; } -enum class PaddingSide -{ - Left, - Right -}; - struct DeducePaddingSide { template<template<size_t> typename Layout> @@ -58,7 +70,9 @@ struct DeducePaddingSide constexpr static PaddingSide from_typename() { - if constexpr (is_left_padded<Layout>) + if constexpr (std::same_as<Layout, std::layout_left>) + return PaddingSide::Left; + else if constexpr (is_left_padded<Layout>) return PaddingSide::Left; else return PaddingSide::Right; @@ -84,8 +98,18 @@ template<> template<typename T, size_t N> constexpr static std::array<T, N> - make_array(const std::array<T, N>& expected) - { return expected; } + make_array(const std::array<T, N>& a) + { return a; } + + template<typename... Indices> + constexpr static auto + make_indices(Indices... indices) + { return std::array{indices...}; } + + template<typename... Ts> + constexpr static std::tuple<Ts...> + make_tuple(const std::tuple<Ts...>& tup) + { return tup; } template<typename Mapping> constexpr static auto @@ -128,6 +152,25 @@ template<> return a; } + template<typename... Indices> + constexpr static auto + make_indices(Indices... indices) + { return make_array(std::array{indices...}); } + + template<typename... Ts> + constexpr static auto + make_tuple(const std::tuple<Ts...>& tup) + { + constexpr size_t rank = sizeof...(Ts); + auto impl = [&]<size_t... I>(std::index_sequence<I...>) + { + auto idx = [rank](size_t i) consteval + { return rank - 1 - i; }; + return std::tuple<Ts...[idx(I)]...>{get<idx(I)>(tup)...}; + }; + return impl(std::make_index_sequence<rank>()); + } + template<typename Mapping> constexpr static auto padded_stride(const Mapping& m) diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc index 27065a0dfc6e..80ae5d8d56a6 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc @@ -1,7 +1,7 @@ // { dg-do run { target c++23 } } #include <mdspan> -#include "padded_traits.h" +#include "../layout_traits.h" #include <cstdint> #include <testsuite_hooks.h> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc index d1486e4e11c8..17cfac54113b 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc @@ -2,7 +2,7 @@ #include <mdspan> #include "../int_like.h" -#include "padded_traits.h" +#include "../layout_traits.h" #include <cstdint> #include <testsuite_hooks.h> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc index cf4821a3c74f..19fdf93ce0df 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc @@ -3,7 +3,7 @@ #include <cstdint> #include "../int_like.h" -#include "padded_traits.h" +#include "../layout_traits.h" #include <testsuite_hooks.h> constexpr size_t dyn = std::dynamic_extent; diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_neg.cc index a758f74287f2..4073f6838225 100644 --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_neg.cc @@ -1,7 +1,7 @@ // { dg-do compile { target c++26 } } #include <mdspan> -#include "padded_traits.h" +#include "../layout_traits.h" #include <cstdint> constexpr size_t dyn = std::dynamic_extent;
