+ };
#endif
template<typename _ElementType>
diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/
std.cc.in
index f10bab59e2c..c1b4e4c88b7 100644
--- a/libstdc++-v3/src/c++23/std.cc.in
+++ b/libstdc++-v3/src/c++23/std.cc.in
@@ -1871,9 +1871,10 @@ export namespace std
using std::mdspan;
#if __glibcxx_padded_layouts
using std::layout_left_padded;
+ using std::layout_right_padded;
#endif
- // FIXME layout_right_padded, strided_slice, submdspan_mapping_result,
- // full_extent_t, full_extent, submdspan_extents, mdsubspan
+ // FIXME strided_slice, submdspan_mapping_result, full_extent_t,
full_extent,
+ // submdspan_extents, mdsubspan
}
#endif
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
index 891471467e1..73b161f5979 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/ctors.cc
@@ -10,7 +10,7 @@ constexpr size_t dyn = std::dynamic_extent;
#if __glibcxx_padded_layouts
template<typename Layout>
constexpr bool
- is_padded_layout = is_left_padded<Layout>;
+ is_padded_layout = is_left_padded<Layout> || is_right_padded<Layout>;
#else
template<typename>
constexpr bool
@@ -479,6 +479,7 @@ main()
test_all<std::layout_right>();
#ifdef __glibcxx_padded_layouts
test_padded_all<std::layout_left_padded>();
+ test_padded_all<std::layout_right_padded>();
#endif
from_left_or_right::test_all<std::layout_left, std::layout_right>();
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc
index 236aca8bc2b..c5519afe34f 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc
@@ -142,6 +142,7 @@ main()
static_assert(test_all<std::layout_stride>());
#ifdef __glibcxx_padded_layouts
static_assert(test_padded_all<std::layout_left_padded>());
+ static_assert(test_padded_all<std::layout_right_padded>());
#endif
return 0;
}
diff --git
a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
index 5bf6bf65d3a..57560a6aae7 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
@@ -374,7 +374,7 @@ template<>
#if __glibcxx_padded_layouts
template<typename Layout>
- requires is_left_padded<Layout>
+ requires is_left_padded<Layout> || is_right_padded<Layout>
struct TestStride2D<Layout>
{
static constexpr void
@@ -458,7 +458,7 @@ template<>
#if __glibcxx_padded_layouts
template<typename Layout>
- requires is_left_padded<Layout>
+ requires is_left_padded<Layout> || is_right_padded<Layout>
struct TestStride3D<Layout>
{
static constexpr void
@@ -702,6 +702,7 @@ main()
test_all<std::layout_stride>();
#ifdef __glibcxx_padded_layouts
test_padded_all<std::layout_left_padded>();
+ test_padded_all<std::layout_right_padded>();
#endif
test_has_op_eq<std::layout_right, std::layout_left, false>();
@@ -709,6 +710,7 @@ main()
test_has_op_eq<std::layout_left, std::layout_stride, true>();
#ifdef __glibcxx_padded_layouts
test_padded_has_op_eq<std::layout_left_padded>();
+ test_padded_has_op_eq<std::layout_right_padded>();
#endif
test_has_op_eq_peculiar();
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc
index ea9a8ef3f4b..a607d1ddd02 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded.cc
@@ -670,6 +670,10 @@ main()
test_all<std::layout_left_padded>();
static_assert(test_all<std::layout_left_padded>());
+ test_all<std::layout_right_padded>();
+ static_assert(test_all<std::layout_right_padded>());
+
test_from_pad_all<std::layout_left_padded>();
+ test_from_pad_all<std::layout_right_padded>();
return 0;
}
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 29f12aa4de2..d0ac31c2810 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_neg.cc
@@ -15,6 +15,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_extens_representable_sta<std::layout_left_padded>());
// { dg-error "from here" }
+static_assert(test_from_extens_representable_sta<std::layout_right_padded>());
// { dg-error "from here" }
template<template<size_t> typename Layout>
constexpr bool
@@ -28,6 +29,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_extents_representable_padded_size<std::layout_left_padded>());
// { dg-error "expansion of" }
+static_assert(test_from_extents_representable_padded_size<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -40,6 +42,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_extents_representable_stride<std::layout_left_padded>());
// { dg-error "expansion of" }
+static_assert(test_from_extents_representable_stride<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -51,6 +54,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_pad_representable_stride<std::layout_left_padded>());
// { dg-error "expansion of" }
+static_assert(test_from_pad_representable_stride<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -62,6 +66,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_pad_representable_padded_size<std::layout_left_padded>());
// { dg-error "expansion of" }
+static_assert(test_from_pad_representable_padded_size<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -76,6 +81,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_left<std::layout_left_padded>()); // { dg-error
"required from here" }
+static_assert(test_from_left<std::layout_right_padded>()); // { dg-error
"required from here" }
template<template<size_t> typename Layout>
constexpr bool
@@ -90,6 +96,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_left_bad_runtime_stride<std::layout_left_padded>());
// { dg-error "expansion of" }
+static_assert(test_from_left_bad_runtime_stride<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -103,6 +110,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_left_representable_extents<std::layout_left_padded>());
// { dg-error "expansion of" }
+static_assert(test_from_left_representable_extents<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout, size_t PaddingValue>
constexpr bool
@@ -116,6 +124,8 @@ template<template<size_t> typename Layout, size_t
PaddingValue>
}
static_assert(test_pad_overflow<std::layout_left_padded, 1>()); // {
dg-error "expansion of" }
static_assert(test_pad_overflow<std::layout_left_padded, dyn>()); // {
dg-error "expansion of" }
+static_assert(test_pad_overflow<std::layout_right_padded, 1>()); // {
dg-error "expansion of" }
+static_assert(test_pad_overflow<std::layout_right_padded, dyn>()); // {
dg-error "expansion of" }
template<template<size_t> typename Layout, size_t PaddingValue>
constexpr bool
@@ -128,6 +138,8 @@ template<template<size_t> typename Layout, size_t
PaddingValue>
}
static_assert(test_from_pad_negative<std::layout_left_padded, 1>()); //
{ dg-error "expansion of" }
static_assert(test_from_pad_negative<std::layout_left_padded, dyn>()); //
{ dg-error "expansion of" }
+static_assert(test_from_pad_negative<std::layout_right_padded, 1>());
// { dg-error "expansion of" }
+static_assert(test_from_pad_negative<std::layout_right_padded, dyn>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout, size_t Pad>
constexpr bool
@@ -142,6 +154,8 @@ template<template<size_t> typename Layout, size_t Pad>
}
static_assert(test_static_pad_same<std::layout_left_padded, 1>()); // {
dg-error "expansion of" }
static_assert(test_static_pad_same<std::layout_left_padded, 3>()); // {
dg-error "expansion of" }
+static_assert(test_static_pad_same<std::layout_right_padded, 1>()); // {
dg-error "expansion of" }
+static_assert(test_static_pad_same<std::layout_right_padded, 3>()); // {
dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -156,6 +170,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_stride_wrong_stride0<std::layout_left_padded>());
// { dg-error "expansion of" }
+static_assert(test_from_stride_wrong_stride0<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -170,6 +185,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_stride_wrong_stride1<std::layout_left_padded>());
// { dg-error "expansion of" }
+static_assert(test_from_stride_wrong_stride1<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -184,6 +200,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_stride_wrong_stride2<std::layout_left_padded>());
+static_assert(test_from_stride_wrong_stride2<std::layout_right_padded>());
template<template<size_t> typename Layout>
constexpr bool
@@ -200,6 +217,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_stride_oversized<std::layout_left_padded>()); //
{ dg-error "expansion of" }
+static_assert(test_from_stride_oversized<std::layout_right_padded>()); //
{ dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -213,6 +231,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_samepad_dyn<std::layout_left_padded>()); // {
dg-error "expansion of" }
+static_assert(test_from_samepad_dyn<std::layout_right_padded>()); // {
dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -226,6 +245,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_samepad_sta<std::layout_left_padded>()); // {
dg-error "expansion of" }
+static_assert(test_from_samepad_sta<std::layout_right_padded>()); // {
dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -240,6 +260,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_from_samepad_oversized<std::layout_left_padded>()); //
{ dg-error "expansion of" }
+static_assert(test_from_samepad_oversized<std::layout_right_padded>());
// { dg-error "expansion of" }
template<template<size_t> typename Layout, size_t RunId>
constexpr bool
@@ -278,6 +299,10 @@
static_assert(test_to_same_not_exhaustive<std::layout_left_padded, 0>());
// { d
static_assert(test_to_same_not_exhaustive<std::layout_left_padded, 1>());
// { dg-error "expansion of" }
static_assert(test_to_same_not_exhaustive<std::layout_left_padded, 2>());
// { dg-error "expansion of" }
static_assert(test_to_same_not_exhaustive<std::layout_left_padded, 3>());
// { dg-error "expansion of" }
+static_assert(test_to_same_not_exhaustive<std::layout_right_padded,
0>()); // { dg-error "expansion of" }
+static_assert(test_to_same_not_exhaustive<std::layout_right_padded,
1>()); // { dg-error "expansion of" }
+static_assert(test_to_same_not_exhaustive<std::layout_right_padded,
2>()); // { dg-error "expansion of" }
+static_assert(test_to_same_not_exhaustive<std::layout_right_padded,
3>()); // { dg-error "expansion of" }
template<template<size_t> typename Layout>
constexpr bool
@@ -290,6 +315,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_statically_bad_padding_value1<std::layout_left_padded>());
// { dg-error "required from" }
+static_assert(test_statically_bad_padding_value1<std::layout_right_padded>());
// { dg-error "required from" }
template<template<size_t> typename Layout>
constexpr bool
@@ -301,6 +327,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_statically_bad_padding_value2<std::layout_left_padded>());
// { dg-error "required from" }
+static_assert(test_statically_bad_padding_value2<std::layout_right_padded>());
// { dg-error "required from" }
template<template<size_t> typename Layout>
constexpr bool
@@ -312,6 +339,7 @@ template<template<size_t> typename Layout>
return true;
}
static_assert(test_statically_oversized<std::layout_left_padded>()); // {
dg-error "from here" }
+static_assert(test_statically_oversized<std::layout_right_padded>()); //
{ dg-error "from here" }
// { dg-prune-output "padding_value must be representable as index_type" }
// { dg-prune-output "non-constant condition for static assertion" }
diff --git
a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_traits.h
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_traits.h
index 1f0169d7c02..c267454f467 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_traits.h
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/padded_traits.h
@@ -2,9 +2,86 @@
#define TEST_MDSPAN_PADDED_TRAITS_H
#if __glibcxx_padded_layouts
+template<typename Rev, typename Fwd>
+ struct reverse_impl;
+
+template<size_t... Ir, size_t I0, size_t... I>
+ struct reverse_impl<std::integer_sequence<size_t, Ir...>,
+ std::integer_sequence<size_t, I0, I...>>
+ {
+ using type = typename reverse_impl<std::index_sequence<I0, Ir...>,
+ std::index_sequence<I...>>::type;
+ };
+
+template<size_t... Ir>
+ struct reverse_impl<std::integer_sequence<size_t, Ir...>,
+ std::integer_sequence<size_t>>
+ {
+ using type = std::index_sequence<Ir...>;
+ };
+
+template<typename I>
+ struct reverse;
+
+template<size_t... Ir>
+ struct reverse<std::index_sequence<Ir...>>
+ {
+ using type = typename reverse_impl<std::integer_sequence<size_t>,
+ std::integer_sequence<size_t,
Ir...>>::type;
+ };
+
+template<typename, typename>
+ struct sequence_to_extents;
+
+template<typename IndexType, size_t... I>
+ struct sequence_to_extents<IndexType, std::index_sequence<I...>>
+ {
+ using type = std::extents<IndexType, I...>;
+ };
+
+template<typename IndexType, size_t... I>
+ struct reverse<std::extents<IndexType, I...>>
+ {
+ using type = typename sequence_to_extents<
+ IndexType,
+ typename reverse<std::index_sequence<I...>>::type
+ >::type;
+ };
+
+template<typename Extents>
+ constexpr auto
+ dynamic_extents_array(const Extents& exts)
+ {
+ std::array<typename Extents::index_type, Extents::rank()> ret;
+ for(size_t i = 0; i < Extents::rank(); ++i)
+ ret[i] = exts.extent(i);
+ return ret;
+ }
+
+template<typename T, size_t N>
+ constexpr std::array<T, N>
+ reversed(const std::array<T, N>& fwd)
+ {
+ std::array<T, N> rev;
+ for(size_t i = 0; i < N; ++i)
+ rev[(N-1) - i] = fwd[i];
+ return rev;
+ }
+
+template<typename IndexType, size_t... I>
+ constexpr auto
+ reversed(const std::extents<IndexType, I...>& exts)
+ {
+ using rev_type = typename reverse<std::extents<IndexType,
I...>>::type;
+ return rev_type(reversed(dynamic_extents_array(exts)));
+ }
+
+static_assert(std::array{3, 2, 1} == reversed(std::array{1, 2, 3}));
+
enum class PaddingSide
{
- Left
+ Left,
+ Right
};
template<typename Layout>
@@ -13,17 +90,33 @@ template<typename Layout>
template<size_t PaddingValue>
constexpr static bool
is_left_padded<std::layout_left_padded<PaddingValue>> = true;
+template<typename Layout>
+ constexpr static bool is_right_padded = false;
+
+template<size_t PaddingValue>
+ constexpr static bool
is_right_padded<std::layout_right_padded<PaddingValue>> = true;
+
struct DeducePaddingSide
{
template<template<size_t> typename Layout>
constexpr static PaddingSide
from_template()
- { return PaddingSide::Left; }
+ {
+ if constexpr (std::same_as<Layout<0>, std::layout_left_padded<0>>)
+ return PaddingSide::Left;
+ else
+ return PaddingSide::Right;
+ }
template<typename Layout>
constexpr static PaddingSide
from_typename()
- { return PaddingSide::Left; }
+ {
+ if constexpr (is_left_padded<Layout>)
+ return PaddingSide::Left;
+ else
+ return PaddingSide::Right;
+ }
};
template<PaddingSide Side>
@@ -59,5 +152,41 @@ template<>
{ return exts.extent(0); }
};
+template<>
+ struct LayoutTraits<PaddingSide::Right>
+ {
+ using layout_same = std::layout_right;
+ using layout_other = std::layout_left;
+
+ template<typename Extents>
+ using extents_type = typename reverse<Extents>::type;
+
+ template<typename Extents>
+ constexpr static extents_type<Extents>
+ make_extents(const Extents& exts)
+ { return reversed(exts); }
+
+ template<typename T, size_t N>
+ constexpr static std::array<T, N>
+ make_expected(const std::array<T, N>& expected)
+ { return reversed(expected); }
+
+ template<typename Mapping>
+ constexpr static auto
+ padded_stride(const Mapping& m)
+ {
+ auto rank = Mapping::extents_type::rank();
+ return m.stride(rank - 2);
+ }
+
+ template<typename Extents>
+ constexpr static auto
+ padded_extent(const Extents& exts)
+ {
+ auto rank = Extents::rank();
+ return exts.extent(rank - 1);
+ }
+ };
+
#endif
#endif
--
2.50.1