+ return true;
+ }
+
+ template<typename Layout>
+ constexpr void
+ test_all()
+ {
+ test_default_ctor_all<Layout>();
+ static_assert(test_default_ctor_all<Layout>());
+ }
+}
+
+// ctor: mapping(const extents&)
+namespace from_extents
+{
+ template<typename Layout, typename Extents, typename OExtents>
+ constexpr void
+ verify_nothrow_convertible(OExtents oexts)
+ {
+ using Mapping = typename Layout::mapping<Extents>;
+ ::verify_nothrow_convertible<Mapping>(oexts);
+ }
+
+ template<typename Layout, typename Extents, typename OExtents>
+ constexpr void
+ verify_nothrow_constructible(OExtents oexts)
+ {
+ using Mapping = typename Layout::mapping<Extents>;
+ ::verify_nothrow_constructible<Mapping>(oexts);
+ }
+
+ template<typename Layout, typename Extents, typename OExtents>
+ constexpr void
+ assert_not_constructible()
+ {
+ using Mapping = typename Layout::mapping<Extents>;
+ ::assert_not_constructible<Mapping, OExtents>();
+ }
+
+ template<typename Layout>
+ constexpr bool
+ test_ctor()
+ {
+ verify_nothrow_convertible<Layout, std::extents<int>>(
+ std::extents<int>{});
+
+ verify_nothrow_convertible<Layout, std::extents<int, 2>>(
+ std::extents<int, 2>{});
+
+ verify_nothrow_convertible<Layout, std::extents<int, dyn, 3>>(
+ std::extents<int, dyn, 3>{2});
+
+ verify_nothrow_constructible<Layout, std::extents<unsigned int>>(
+ std::extents<int>{});
+
+ verify_nothrow_constructible<Layout, std::extents<int, dyn>>(
+ std::extents<int, 2>{});
+
+ verify_nothrow_constructible<Layout, std::extents<int, dyn, 3>>(
+ std::extents<int, 2, 3>{});
+
+ assert_not_constructible<Layout, std::extents<int>,
+ std::extents<unsigned int>>();
+ assert_not_constructible<Layout, std::extents<int, 2>,
+ std::extents<int, dyn>>();
+ assert_not_constructible<Layout, std::extents<int, 2, 3>,
+ std::extents<int, dyn, 3>>();
+ return true;
+ }
+
+ template<typename Layout, typename Extents>
+ constexpr void
+ assert_deducible(Extents exts)
+ {
+ typename Layout::mapping m(exts);
+ static_assert(std::same_as<decltype(m),
+ typename Layout::mapping<Extents>>);
+ }
+
+ template<typename Layout>
+ constexpr void
+ test_deducible()
+ {
+ assert_deducible<Layout>(std::extents<int>());
+ assert_deducible<Layout>(std::extents<int, 1>());
+ assert_deducible<Layout>(std::extents<int, 1, 2, dyn>(3));
+ }
+
+ template<typename Layout>
+ constexpr void
+ test_all()
+ {
+ test_ctor<Layout>();
+ static_assert(test_ctor<Layout>());
+ test_deducible<Layout>();
+ }
+}
+
+// ctor: mapping(mapping<OExtents>)
+namespace from_same_layout
+{
+ template<typename Layout, typename Extents, typename OExtents>
+ constexpr void
+ verify_nothrow_convertible(OExtents exts)
+ {
+ using Mapping = typename Layout::mapping<Extents>;
+ using OMapping = typename Layout::mapping<OExtents>;
+
+ ::verify_nothrow_convertible<Mapping>(OMapping(exts));
+ }
+
+ template<typename Layout, typename Extents, typename OExtents>
+ constexpr void
+ verify_nothrow_constructible(OExtents exts)
+ {
+ using Mapping = typename Layout::mapping<Extents>;
+ using OMapping = typename Layout::mapping<OExtents>;
+
+ ::verify_nothrow_constructible<Mapping>(OMapping(exts));
+ }
+
+ template<typename Layout>
+ constexpr bool
+ test_ctor()
+ {
+ verify_nothrow_convertible<Layout, std::extents<unsigned int>>(
+ std::extents<int>{});
+
+ verify_nothrow_constructible<Layout, std::extents<int>>(
+ std::extents<unsigned int>{});
+
+ assert_not_constructible<
+ typename Layout::mapping<std::extents<int>>,
+ typename Layout::mapping<std::extents<int, 1>>>();
+
+ assert_not_constructible<
+ typename Layout::mapping<std::extents<int, 1>>,
+ typename Layout::mapping<std::extents<int>>>();
+
+ verify_nothrow_constructible<Layout, std::extents<int, 1>>(
+ std::extents<int, dyn>{1});
+
+ verify_nothrow_convertible<Layout, std::extents<int, dyn>>(
+ std::extents<int, 1>{});
+
+ assert_not_constructible<
+ typename Layout::mapping<std::extents<int, 1, 2>>,
+ typename Layout::mapping<std::extents<int, 1>>>();
+
+ verify_nothrow_constructible<Layout, std::extents<int, 1, 2>>(
+ std::extents<int, dyn, 2>{1});
+
+ verify_nothrow_convertible<Layout, std::extents<int, dyn, 2>>(
+ std::extents<int, 1, 2>{});
+ return true;
+ }
+
+ template<typename Layout>
+ constexpr void
+ test_all()
+ {
+ test_ctor<Layout>();
+ static_assert(test_ctor<Layout>());
+ }
+}
+
+template<typename Layout>
+ constexpr void
+ test_all()
+ {
+ default_ctor::test_all<Layout>();
+ from_extents::test_all<Layout>();
+ from_same_layout::test_all<Layout>();
+ }
+
+int
+main()
+{
+ test_all<std::layout_left>();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc
new file mode 100644
index 00000000000..8cca8171d12
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/empty.cc
@@ -0,0 +1,70 @@
+// { dg-do run { target c++23 } }
+#include <mdspan>
+
+#include <cstdint>
+#include <testsuite_hooks.h>
+
+constexpr size_t dyn = std::dynamic_extent;
+
+template<typename Mapping>
+ constexpr void
+ verify_stride(Mapping m)
+ {
+ using Layout = typename Mapping::layout_type;
+ constexpr size_t rank = Mapping::extents_type::rank();
+ for(size_t i = 0; i < rank; ++i)
+ {
+ m.stride(i);
+ }
+ }
+
+template<typename Mapping>
+ constexpr void
+ verify_required_span_size(Mapping m)
+ { VERIFY(m.required_span_size() == 0); }
+
+template<typename Mapping>
+ constexpr void
+ verify_all(Mapping m)
+ {
+ verify_required_span_size(m);
+ verify_stride(m);
+ }
+
+template<typename Layout, typename Int>
+constexpr void
+test_default_constructed()
+{
+ constexpr auto n = std::numeric_limits<Int>::max();
+ verify_all(typename Layout::mapping<std::extents<Int, n, n, 0, n,
n>>{});
+ verify_all(typename Layout::mapping<std::extents<Int, 0, n, n, n>>{});
+ verify_all(typename Layout::mapping<std::extents<Int, dyn, n, n, n>>{});
+ verify_all(typename Layout::mapping<std::extents<Int, n, n, n, 0>>{});
+ verify_all(typename Layout::mapping<std::extents<Int, n, n, n, dyn>>{});
+}
+
+template<typename Layout>
+constexpr bool
+test_all()
+{
+ test_default_constructed<Layout, signed char>();
+ test_default_constructed<Layout, short int>();
+ test_default_constructed<Layout, int>();
+ test_default_constructed<Layout, long int>();
+ test_default_constructed<Layout, long long int>();
+
+ test_default_constructed<Layout, unsigned char>();
+ test_default_constructed<Layout, unsigned short int>();
+ test_default_constructed<Layout, unsigned int>();
+ test_default_constructed<Layout, unsigned long int>();
+ test_default_constructed<Layout, unsigned long long int>();
+ test_default_constructed<Layout, size_t>();
+ return true;
+}
+
+int
+main()
+{
+ static_assert(test_all<std::layout_left>());
+ return 0;
+}
diff --git
a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
new file mode 100644
index 00000000000..a5be1166617
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
@@ -0,0 +1,437 @@
+// { dg-do run { target c++23 } }
+#include <mdspan>
+
+#include <cstdint>
+#include <testsuite_hooks.h>
+
+constexpr size_t dyn = std::dynamic_extent;
+
+template<typename Layout, typename Extents>
+ constexpr bool
+ test_mapping_properties()
+ {
+ using M = typename Layout::mapping<Extents>;
+ static_assert(std::__mdspan::__is_extents<typename M::extents_type>);
+ static_assert(std::copyable<M>);
+ static_assert(std::is_nothrow_move_constructible_v<M>);
+ static_assert(std::is_nothrow_move_assignable_v<M>);
+ static_assert(std::is_nothrow_swappable_v<M>);
+ static_assert(std::is_same_v<typename M::extents_type, Extents>);
+ static_assert(std::is_same_v<typename M::index_type,
+ typename M::extents_type::index_type>);
+ static_assert(std::is_same_v<typename M::size_type,
+ typename M::extents_type::size_type>);
+ static_assert(std::is_same_v<typename M::rank_type,
+ typename M::extents_type::rank_type>);
+ static_assert(std::is_same_v<typename M::layout_type, Layout>);
+
+ static_assert(std::is_trivially_copyable_v<M>);
+ static_assert(std::regular<M>);
+
+ static_assert(M::is_always_unique() && M::is_unique());
+ static_assert(M::is_always_strided() && M::is_strided());
+ return true;
+ }
+
+template<typename Layout>
+ constexpr bool
+ test_mapping_properties_all()
+ {
+ test_mapping_properties<Layout, std::extents<int>>();
+ test_mapping_properties<Layout, std::extents<int, 1>>();
+ test_mapping_properties<Layout, std::extents<int, dyn>>();
+ test_mapping_properties<Layout, std::extents<int, dyn, dyn>>();
+ return true;
+ }
+
+// Check operator()(Indices...)
+template<typename Mapping, size_t N>
+ constexpr typename Mapping::index_type
+ linear_index(const Mapping& mapping,
+ const std::array<typename Mapping::index_type, N>& indices)
+ {
+ typename Mapping::index_type ret = 0;
+ for(size_t r = 0; r < indices.size(); ++r)
+ ret += indices[r] * mapping.stride(r);
+ return ret;
+ }
+
+template<typename Mapping, typename... Indices>
+ constexpr void
+ test_linear_index(const Mapping& m, Indices... i)
+ {
+ using index_type = typename Mapping::index_type;
+ index_type expected = linear_index(m, std::array{index_type(i)...});
+ VERIFY(m(i...) == expected);
+ VERIFY(m(uint8_t(i)...) == expected);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_linear_index_0d()
+ {
+ constexpr typename Layout::mapping<std::extents<int>> m;
+ VERIFY(m() == 0);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_linear_index_1d()
+ {
+ typename Layout::mapping<std::extents<int, 5>> m;
+ test_linear_index(m, 0);
+ test_linear_index(m, 1);
+ test_linear_index(m, 4);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_linear_index_2d()
+ {
+ typename Layout::mapping<std::extents<int, 3, 256>> m;
+ test_linear_index(m, 0, 0);
+ test_linear_index(m, 1, 0);
+ test_linear_index(m, 0, 1);
+ test_linear_index(m, 1, 1);
+ test_linear_index(m, 2, 4);
+ }
+
+template<typename Layout>
+ struct MappingFactory
+ {
+ template<typename Extents>
+ static constexpr typename Layout::mapping<Extents>
+ create(Extents exts)
+ { return exts; }
+ };
+
+template<typename Layout>
+ constexpr void
+ test_linear_index_3d()
+ {
+ auto m = MappingFactory<Layout>::create(std::extents(3, 5, 7));
+ test_linear_index(m, 0, 0, 0);
+ test_linear_index(m, 1, 0, 0);
+ test_linear_index(m, 0, 1, 0);
+ test_linear_index(m, 0, 0, 1);
+ test_linear_index(m, 1, 1, 0);
+ test_linear_index(m, 2, 4, 6);
+ }
+
+struct IntLikeA
+{
+ operator int()
+ { return 0; }
+};
+
+struct IntLikeB
+{
+ operator int() noexcept
+ { return 0; }
+};
+
+struct NotIntLike
+{ };
+
+template<typename Layout>
+ constexpr void
+ test_has_linear_index_0d()
+ {
+ using Mapping = typename Layout::mapping<std::extents<int>>;
+ static_assert(std::invocable<Mapping>);
+ static_assert(!std::invocable<Mapping, int>);
+ static_assert(!std::invocable<Mapping, IntLikeA>);
+ static_assert(!std::invocable<Mapping, IntLikeB>);
+ static_assert(!std::invocable<Mapping, NotIntLike>);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_has_linear_index_1d()
+ {
+ using Mapping = typename Layout::mapping<std::extents<int, 3>>;
+ static_assert(std::invocable<Mapping, int>);
+ static_assert(!std::invocable<Mapping>);
+ static_assert(!std::invocable<Mapping, IntLikeA>);
+ static_assert(std::invocable<Mapping, IntLikeB>);
+ static_assert(!std::invocable<Mapping, NotIntLike>);
+ static_assert(std::invocable<Mapping, double>);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_has_linear_index_2d()
+ {
+ using Mapping = typename Layout::mapping<std::extents<int, 3, 5>>;
+ static_assert(std::invocable<Mapping, int, int>);
+ static_assert(!std::invocable<Mapping, int>);
+ static_assert(!std::invocable<Mapping, IntLikeA, int>);
+ static_assert(std::invocable<Mapping, IntLikeB, int>);
+ static_assert(!std::invocable<Mapping, NotIntLike, int>);
+ static_assert(std::invocable<Mapping, double, double>);
+ }
+
+template<typename Layout>
+ constexpr bool
+ test_linear_index_all()
+ {
+ test_linear_index_0d<Layout>();
+ test_linear_index_1d<Layout>();
+ test_linear_index_2d<Layout>();
+ test_linear_index_3d<Layout>();
+ test_has_linear_index_0d<Layout>();
+ test_has_linear_index_1d<Layout>();
+ test_has_linear_index_2d<Layout>();
+ return true;
+ }
+
+template<typename Mapping>
+ constexpr typename Mapping::index_type
+ linear_index_end(Mapping m)
+ {
+ using index_type = typename Mapping::index_type;
+ constexpr size_t rank = Mapping::extents_type::rank();
+
+ auto impl = [m]<index_type... Counts>(
+ std::integer_sequence<index_type, Counts...>) -> index_type
+ {
+ auto exts = m.extents();
+ if(((exts.extent(Counts) == 0) || ...))
+ return 0;
+ return m((exts.extent(Counts) - 1)...) + 1;
+ };
+
+ return impl(std::make_integer_sequence<index_type, rank>());
+ }
+
+// Check required_span_size
+template<typename Mapping>
+ constexpr void
+ test_required_span_size(Mapping m)
+ { VERIFY(m.required_span_size() == linear_index_end(m)); }
+
+template<typename Layout>
+ constexpr void
+ test_required_span_size_0d()
+ {
+ typename Layout::mapping<std::extents<int>> m;
+ test_required_span_size(m);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_required_span_size_1d()
+ {
+ auto m = MappingFactory<Layout>::create(std::extents(3));
+ test_required_span_size(m);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_required_span_size_2d()
+ {
+ auto m = MappingFactory<Layout>::create(std::extents(3, 5));
+ test_required_span_size(m);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_required_span_size_3d()
+ {
+ auto m = MappingFactory<Layout>::create(std::extents(3, 5, 7));
+ test_required_span_size(m);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_required_span_size_zero_1d()
+ {
+ auto m = MappingFactory<Layout>::create(std::extents(3, 0));
+ test_required_span_size(m);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_required_span_size_zero_3d()
+ {
+ auto m = MappingFactory<Layout>::create(std::extents(3, 0, 7));
+ test_required_span_size(m);
+ }
+
+template<typename Layout>
+ constexpr bool
+ test_required_span_size_all()
+ {
+ test_required_span_size_0d<Layout>();
+ test_required_span_size_1d<Layout>();
+ test_required_span_size_2d<Layout>();
+ test_required_span_size_3d<Layout>();
+ test_required_span_size_zero_1d<Layout>();
+ test_required_span_size_zero_3d<Layout>();
+ return true;
+ }
+
+// Check stride
+template<typename Layout>
+ constexpr void
+ test_stride_1d()
+ {
+ std::layout_left::mapping<std::extents<int, 3>> m;
+ VERIFY(m.stride(0) == 1);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_stride_2d();
+
+template<>
+ constexpr void
+ test_stride_2d<std::layout_left>()
+ {
+ std::layout_left::mapping<std::extents<int, 3, 5>> m;
+ VERIFY(m.stride(0) == 1);
+ VERIFY(m.stride(1) == 3);
+ }
+
+template<typename Layout>
+ constexpr void
+ test_stride_3d();
+
+template<>
+ constexpr void
+ test_stride_3d<std::layout_left>()
+ {
+ std::layout_left::mapping m(std::dextents<int, 3>(3, 5, 7));
+ VERIFY(m.stride(0) == 1);
+ VERIFY(m.stride(1) == 3);
+ VERIFY(m.stride(2) == 3*5);
+ }
+
+template<typename Layout>
+ constexpr bool
+ test_stride_all()
+ {
+ test_stride_1d<Layout>();
+ test_stride_2d<Layout>();
+ test_stride_3d<Layout>();
+ return true;
+ }
+
+template<typename Mapping>
+ concept has_stride = requires (Mapping m)
+ {
+ { m.stride(0) } -> std::same_as<typename Mapping::index_type>;
+ };
+
+template<typename Layout>
+ constexpr void
+ test_has_stride_0d()