[PATCH v1 1/3] libstdc++: Refactor mdspan tests [PR121061]
Jonathan Wakely
jwakely.gcc@gmail.com
Wed Jul 16 20:02:46 GMT 2025
On Wed, 16 Jul 2025, 14:48 Luc Grosheintz, <luc.grosheintz@gmail.com> wrote:
> PR121061 shows that the test coverage for custom integer types is
> insufficient. Custom IndexTypes are passed to mdspan related objects in
> one of two ways:
>
> * as a template parameter pack,
> * or as an array/span.
>
> These two cases have different requirements on the (constness of) custom
> IndexTypes. Therefore, the tests are restructured as follows:
>
> * allow testing with different custom integers,
> * separate code that tests the two cases described above,
> * use int_like.h for all tests with custom integers.
>
I like this approach, thanks.
OK for trunk.
> The affected tests are for:
>
> * creating extents, layout_stride::mapping and mdspan from
> custom integers,
>
> * mapping::operator() and mdspan::operator[].
>
> PR libstdc++/121061
>
> libstdc++-v3/ChangeLog:
>
> * testsuite/23_containers/mdspan/extents/custom_integer.cc:
> Enable checking with different custom integers. Improve
> checking non-existence of overloads for incompatible custom
> integers.
> * testsuite/23_containers/mdspan/layouts/mapping.cc: ditto. Also
> improve reuse of int_like.h.
> * testsuite/23_containers/mdspan/layouts/stride.cc: ditto.
> * testsuite/23_containers/mdspan/mdspan.cc: ditto.
> * testsuite/23_containers/mdspan/extents/int_like.h: Rename (old
> name).
> * testsuite/23_containers/mdspan/int_like.h: Rename (new name).
> (ThrowingInt): Add.
> (NotIntLike): Add.
>
> Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
> ---
> .../mdspan/extents/custom_integer.cc | 98 +++++++-----
> .../23_containers/mdspan/extents/int_like.h | 30 ----
> .../testsuite/23_containers/mdspan/int_like.h | 49 ++++++
> .../23_containers/mdspan/layouts/mapping.cc | 110 +++++++-------
> .../23_containers/mdspan/layouts/stride.cc | 20 +--
> .../testsuite/23_containers/mdspan/mdspan.cc | 143 ++++++++++++------
> 6 files changed, 264 insertions(+), 186 deletions(-)
> delete mode 100644
> libstdc++-v3/testsuite/23_containers/mdspan/extents/int_like.h
> create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
> b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
> index 404755bd5ac..4f631815b10 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
> @@ -2,7 +2,7 @@
> #include <mdspan>
>
> #include <testsuite_hooks.h>
> -#include "int_like.h"
> +#include "../int_like.h"
>
> // Test construction from a custom integer-like object, that has
> // no copy/move ctor or copy/move assignment operator.
> @@ -12,51 +12,81 @@ constexpr size_t dyn = std::dynamic_extent;
> static_assert(std::is_convertible_v<IntLike, int>);
> static_assert(std::is_nothrow_constructible_v<int, IntLike>);
>
> -void
> -test_shape(const auto& s2, const auto& s23)
> -{
> - std::extents<int, 2, 3> expected;
> +template<typename Extents, bool Valid>
> + void
> + test_shape(const auto& shape)
> + {
> + static_assert(std::is_constructible_v<Extents, decltype(shape)> ==
> Valid);
>
> - std::extents<int, 2, 3> e1(s23);
> - VERIFY(e1 == expected);
> + if constexpr (Valid)
> + {
> + std::extents<int, 2, 3> expected;
> + Extents actual(shape);
> + VERIFY(actual == expected);
> + }
> + }
>
> - std::extents<int, dyn, 3> e2(s2);
> - VERIFY(e2 == expected);
> +template<typename Int, bool Valid>
> + void
> + test_shape_all()
> + {
> + auto a2 = std::array<Int, 1>{Int(2)};
> + auto s2 = std::span<Int, 1>(a2);
>
> - std::extents<int, dyn, 3> e3(s23);
> - VERIFY(e3 == expected);
> + auto a23 = std::array<Int, 2>{Int(2), Int(3)};
> + auto s23 = std::span<Int, 2>(a23);
>
> - std::extents<int, dyn, dyn> e4(s23);
> - VERIFY(e4 == expected);
> -}
> + auto check = [](const auto& dyn_exts, const auto& full_exts)
> + {
> + test_shape<std::extents<int, 2, 3>, Valid>(full_exts);
> + test_shape<std::extents<int, dyn, 3>, Valid>(dyn_exts);
> + test_shape<std::extents<int, dyn, 3>, Valid>(full_exts);
> + test_shape<std::extents<int, dyn, dyn>, Valid>(full_exts);
> + };
>
> -void
> -test_pack()
> -{
> - std::extents<int, 2, 3> expected;
> + check(a2, a23);
> + check(s2, s23);
> + }
>
> - std::extents<int, dyn, 3> e1(IntLike(2));
> - VERIFY(e1 == expected);
> +// Needed because is_constructible requires that Ints are move
> constructible.
> +template<typename Extents, typename... Ints>
> + concept has_ctor = requires
> + {
> + { Extents(Ints(0)...) } -> std::same_as<Extents>;
> + };
>
> - std::extents<int, dyn, 3> e2(IntLike(2), IntLike(3));
> - VERIFY(e2 == expected);
> +template<typename Int, bool Valid>
> + void
> + test_pack_all()
> + {
> + static_assert(has_ctor<std::extents<int, dyn, 3>, Int> == Valid);
> + static_assert(has_ctor<std::extents<int, dyn, 3>, Int, Int> == Valid);
> + static_assert(has_ctor<std::extents<int, dyn, dyn>, Int, Int> ==
> Valid);
>
> - std::extents<int, dyn, dyn> e3(IntLike(2), IntLike(3));
> - VERIFY(e3 == expected);
> -}
> + if constexpr (Valid)
> + {
> + std::extents<int, 2, 3> expected;
> +
> + std::extents<int, dyn, 3> e1(Int(2));
> + VERIFY(e1 == expected);
> +
> + std::extents<int, dyn, 3> e2(Int(2), Int(3));
> + VERIFY(e2 == expected);
> +
> + std::extents<int, dyn, dyn> e3(Int(2), Int(3));
> + VERIFY(e3 == expected);
> + }
> + }
>
> int
> main()
> {
> - auto a2 = std::array<IntLike, 1>{IntLike(2)};
> - auto s2 = std::span<IntLike, 1>(a2);
> -
> - auto a23 = std::array<IntLike, 2>{IntLike(2), IntLike(3)};
> - auto s23 = std::span<IntLike, 2>(a23);
> -
> - test_shape(a2, a23);
> - test_shape(s2, s23);
> - test_pack();
> + test_shape_all<int, true>();
> + test_shape_all<IntLike, true>();
> + test_shape_all<ThrowingInt, false>();
>
> + test_pack_all<int, true>();
> + test_pack_all<IntLike, true>();
> + test_pack_all<ThrowingInt, false>();
> return 0;
> }
> diff --git
> a/libstdc++-v3/testsuite/23_containers/mdspan/extents/int_like.h
> b/libstdc++-v3/testsuite/23_containers/mdspan/extents/int_like.h
> deleted file mode 100644
> index f39f4cc9081..00000000000
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/int_like.h
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -#ifndef TEST_MDSPAN_INT_LIKE_H
> -#define TEST_MDSPAN_INT_LIKE_H
> -
> -class IntLike
> -{
> -public:
> - explicit
> - IntLike(int i)
> - : _M_i(i)
> - { }
> -
> - IntLike() = delete;
> - IntLike(const IntLike&) = delete;
> - IntLike(IntLike&&) = delete;
> -
> - const IntLike&
> - operator=(const IntLike&) = delete;
> -
> - const IntLike&
> - operator=(IntLike&&) = delete;
> -
> - constexpr
> - operator int() const noexcept
> - { return _M_i; }
> -
> -private:
> - int _M_i;
> -};
> -
> -#endif // TEST_MDSPAN_INT_LIKE_H
> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
> b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
> new file mode 100644
> index 00000000000..ed45375f986
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/int_like.h
> @@ -0,0 +1,49 @@
> +#ifndef TEST_MDSPAN_INT_LIKE_H
> +#define TEST_MDSPAN_INT_LIKE_H
> +
> +enum class CustomIndexKind
> +{
> + Const,
> + Throwing,
> +};
> +
> +template<CustomIndexKind Kind>
> + class CustomIndexType
> + {
> + public:
> + explicit
> + CustomIndexType(int i)
> + : _M_i(i)
> + { }
> +
> + CustomIndexType() = delete;
> + CustomIndexType(const CustomIndexType&) = delete;
> + CustomIndexType(CustomIndexType&&) = delete;
> +
> + const CustomIndexType&
> + operator=(const CustomIndexType&) = delete;
> +
> + const CustomIndexType&
> + operator=(CustomIndexType&&) = delete;
> +
> + constexpr
> + operator int() const noexcept
> + requires (Kind == CustomIndexKind::Const)
> + { return _M_i; }
> +
> + constexpr
> + operator int() const
> + requires (Kind == CustomIndexKind::Throwing)
> + { return _M_i; }
> +
> + private:
> + int _M_i;
> + };
> +
> +using IntLike = CustomIndexType<CustomIndexKind::Const>;
> +using ThrowingInt = CustomIndexType<CustomIndexKind::Throwing>;
> +
> +struct NotIntLike
> +{ };
> +
> +#endif // TEST_MDSPAN_INT_LIKE_H
> diff --git
> a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
> b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
> index 963c804a369..17f0c00acf2 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/mapping.cc
> @@ -1,6 +1,7 @@
> // { dg-do run { target c++23 } }
> #include <mdspan>
>
> +#include "../int_like.h"
> #include <cstdint>
> #include <testsuite_hooks.h>
>
> @@ -59,14 +60,13 @@ template<typename Mapping, size_t N>
> return ret;
> }
>
> -template<typename Mapping, typename... Indices>
> +template<typename Int, 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);
> + VERIFY(m(Int(i)...) == expected);
> }
>
> template<typename Layout>
> @@ -77,26 +77,26 @@ template<typename Layout>
> VERIFY(m() == 0);
> }
>
> -template<typename Layout>
> +template<typename Layout, typename Int>
> 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);
> + test_linear_index<Int>(m, 0);
> + test_linear_index<Int>(m, 1);
> + test_linear_index<Int>(m, 4);
> }
>
> -template<typename Layout>
> +template<typename Layout, typename Int>
> 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);
> + test_linear_index<Int>(m, 0, 0);
> + test_linear_index<Int>(m, 1, 0);
> + test_linear_index<Int>(m, 0, 1);
> + test_linear_index<Int>(m, 1, 1);
> + test_linear_index<Int>(m, 2, 4);
> }
>
> template<typename Layout>
> @@ -141,44 +141,34 @@ template<>
> }
> };
>
> -template<typename Layout>
> +template<typename Layout, typename Int>
> 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);
> + test_linear_index<Int>(m, 0, 0, 0);
> + test_linear_index<Int>(m, 1, 0, 0);
> + test_linear_index<Int>(m, 0, 1, 0);
> + test_linear_index<Int>(m, 0, 0, 1);
> + test_linear_index<Int>(m, 1, 1, 0);
> + test_linear_index<Int>(m, 2, 4, 6);
> }
>
> -struct IntLikeA
> -{
> - operator int()
> - { return 0; }
> -};
> -
> -struct IntLikeB
> -{
> - operator int() noexcept
> - { return 0; }
> -};
> -
> -struct NotIntLike
> -{ };
> +template<typename Mapping, typename... Ints>
> + concept has_linear_index = requires (Mapping m)
> + {
> + { m(Ints(0)...) } -> std::same_as<typename Mapping::index_type>;
> + };
>
> 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>);
> + static_assert(has_linear_index<Mapping>);
> + static_assert(!has_linear_index<Mapping, int>);
> + static_assert(!has_linear_index<Mapping, IntLike>);
> + static_assert(!has_linear_index<Mapping, NotIntLike>);
> }
>
> template<typename Layout>
> @@ -186,12 +176,13 @@ template<typename Layout>
> 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>);
> + static_assert(!has_linear_index<Mapping>);
> + static_assert(has_linear_index<Mapping, int>);
> + static_assert(has_linear_index<Mapping, double>);
> + static_assert(has_linear_index<Mapping, IntLike>);
> + static_assert(!has_linear_index<Mapping, ThrowingInt>);
> + static_assert(!has_linear_index<Mapping, NotIntLike>);
> + static_assert(!has_linear_index<Mapping, int, int>);
> }
>
> template<typename Layout>
> @@ -199,22 +190,23 @@ template<typename Layout>
> 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>);
> + static_assert(!has_linear_index<Mapping, int>);
> + static_assert(has_linear_index<Mapping, int, int>);
> + static_assert(has_linear_index<Mapping, double, double>);
> + static_assert(has_linear_index<Mapping, IntLike, int>);
> + static_assert(!has_linear_index<Mapping, ThrowingInt, int>);
> + static_assert(!has_linear_index<Mapping, NotIntLike, int>);
> + static_assert(!has_linear_index<Mapping, int, int, int>);
> }
>
> -template<typename Layout>
> +template<typename Layout, typename Int>
> 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_linear_index_1d<Layout, Int>();
> + test_linear_index_2d<Layout, Int>();
> + test_linear_index_3d<Layout, Int>();
> test_has_linear_index_0d<Layout>();
> test_has_linear_index_1d<Layout>();
> test_has_linear_index_2d<Layout>();
> @@ -527,7 +519,13 @@ template<typename Layout>
> constexpr bool
> test_mapping_all()
> {
> - test_linear_index_all<Layout>();
> + test_linear_index_all<Layout, uint8_t>();
> + test_linear_index_all<Layout, int>();
> + if !consteval
> + {
> + test_linear_index_all<Layout, IntLike>();
> + }
> +
> test_required_span_size_all<Layout>();
> test_stride_all<Layout>();
>
> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc
> b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc
> index c8af5c61254..1267306fb5c 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride.cc
> @@ -1,6 +1,7 @@
> // { dg-do run { target c++23 } }
> #include <mdspan>
>
> +#include "../int_like.h"
> #include <testsuite_hooks.h>
>
> constexpr size_t dyn = std::dynamic_extent;
> @@ -42,21 +43,6 @@ test_ctor_default_stride_all()
> return true;
> }
>
> -struct IntLikeA
> -{
> - operator int()
> - { return 0; }
> -};
> -
> -struct IntLikeB
> -{
> - operator int() noexcept
> - { return 0; }
> -};
> -
> -struct NotIntLike
> -{ };
> -
> template<typename E, typename E_arg, typename T, size_t N, bool Expected>
> constexpr void
> test_stride_constructible()
> @@ -77,8 +63,8 @@ test_stride_constructible_all()
> using E2 = std::extents<int, dyn>;
>
> test_stride_constructible<E0, E0, int, 0, true>();
> - test_stride_constructible<E0, E0, IntLikeA, 0, false>();
> - test_stride_constructible<E0, E0, IntLikeB, 0, true>();
> + test_stride_constructible<E0, E0, IntLike, 0, true>();
> + test_stride_constructible<E0, E0, ThrowingInt, 0, false>();
> test_stride_constructible<E0, E0, NotIntLike, 0, false>();
> test_stride_constructible<E1, E1, int, 1, true>();
> test_stride_constructible<E2, E1, int, 1, true>();
> diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> index a650fb19bdf..adabb0c6639 100644
> --- a/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> +++ b/libstdc++-v3/testsuite/23_containers/mdspan/mdspan.cc
> @@ -2,7 +2,7 @@
> #include <mdspan>
>
> #include <testsuite_hooks.h>
> -#include "extents/int_like.h"
> +#include "int_like.h"
> #include "layout_like.h"
>
> constexpr auto dyn = std::dynamic_extent;
> @@ -317,32 +317,50 @@ test_from_accessor()
> return true;
> }
>
> -void
> -test_from_int_like()
> -{
> - constexpr size_t n = 3*5*7;
> - std::array<double, n> storage{};
> +template<typename MDSpan, typename Pointer, typename... Ints>
> + concept has_pack_ctor = requires
> + {
> + { MDSpan(Pointer{}, Ints(0)...) } -> std::same_as<MDSpan>;
> + };
>
> - auto verify = [&](auto md)
> - {
> - VERIFY(md.data_handle() == storage.data());
> - VERIFY(md.extent(0) == 3);
> - VERIFY(md.extent(1) == 5);
> - VERIFY(md.extent(2) == 7);
> +template<typename CustomInt, bool ValidForPacks, bool ValidForArrays>
> + constexpr bool
> + test_from_int_like()
> + {
> + constexpr size_t n = 3*5*7;
> + std::array<double, n> storage{};
>
> - VERIFY((md[IntLike(0), 0, IntLike(0)]) == 0.0);
> - auto zero = std::array{IntLike(0), IntLike(0), IntLike(0)};
> - auto zero_view = std::span<IntLike, 3>{zero};
> - VERIFY((md[zero]) == 0.0);
> - VERIFY((md[zero_view]) == 0.0);
> - };
> + auto verify = [&](auto md)
> + {
> + VERIFY(md.data_handle() == storage.data());
> + VERIFY(md.extent(0) == 3);
> + VERIFY(md.extent(1) == 5);
> + VERIFY(md.extent(2) == 7);
> + };
>
> - auto shape = std::array{IntLike(3), IntLike(5), IntLike(7)};
> - auto shape_view = std::span<IntLike, 3>{shape};
> - verify(std::mdspan(storage.data(), IntLike(3), 5, IntLike(7)));
> - verify(std::mdspan(storage.data(), shape));
> - verify(std::mdspan(storage.data(), shape_view));
> -}
> + static_assert(has_pack_ctor<std::mdspan<float, std::dextents<int, 3>>,
> + float*, CustomInt, int, CustomInt> == ValidForPacks);
> +
> + static_assert(std::is_constructible_v<
> + std::mdspan<float, std::dextents<int, 3>>, float*,
> + std::span<CustomInt, 3>> == ValidForArrays);
> +
> + static_assert(std::is_constructible_v<
> + std::mdspan<float, std::dextents<int, 3>>, float*,
> + std::array<CustomInt, 3>> == ValidForArrays);
> +
> + if constexpr (ValidForPacks)
> + verify(std::mdspan(storage.data(), CustomInt(3), 5, CustomInt(7)));
> +
> + if constexpr (ValidForArrays)
> + {
> + auto shape = std::array{CustomInt(3), CustomInt(5), CustomInt(7)};
> + auto shape_view = std::span<CustomInt, 3>{shape};
> + verify(std::mdspan(storage.data(), shape));
> + verify(std::mdspan(storage.data(), shape_view));
> + }
> + return true;
> + }
>
> template<typename T, bool NothrowConstructible = true,
> bool NothrowAssignable = true>
> @@ -491,32 +509,53 @@ test_empty_all()
> return true;
> }
>
> -constexpr bool
> -test_access()
> +template<typename MDSpan, typename... Args>
> +concept indexable = requires (MDSpan md, Args... args)
> {
> - using Extents = std::extents<int, 3, 5, 7>;
> - auto exts = Extents{};
> + { md[args...] } -> std::same_as<typename MDSpan::reference>;
> +};
>
> - auto mapping = std::layout_left::mapping(exts);
> - constexpr size_t n = mapping.required_span_size();
> - std::array<double, n> storage{};
> +template<typename Int, bool ValidForPacks, bool ValidForArrays>
> + constexpr bool
> + test_access()
> + {
> + using Extents = std::extents<int, 3, 5, 7>;
> + auto exts = Extents{};
>
> - auto md = std::mdspan(storage.data(), mapping);
> - static_assert(std::__mdspan::__mapping_alike<decltype(md)>);
> + auto mapping = std::layout_left::mapping(exts);
> + constexpr size_t n = mapping.required_span_size();
> + std::array<double, n> storage{};
>
> - for(int i = 0; i < exts.extent(0); ++i)
> - for(int j = 0; j < exts.extent(1); ++j)
> - for(int k = 0; k < exts.extent(2); ++k)
> - {
> - std::array<int, 3> ijk{i, j, k};
> - storage[mapping(i, j, k)] = 1.0;
> - VERIFY((md[i, j, k]) == 1.0);
> - VERIFY((md[ijk]) == 1.0);
> - VERIFY((md[std::span(ijk)]) == 1.0);
> - storage[mapping(i, j, k)] = 0.0;
> - }
> - return true;
> -}
> + auto md = std::mdspan(storage.data(), mapping);
> + using MDSpan = decltype(md);
> +
> + for(int i = 0; i < exts.extent(0); ++i)
> + for(int j = 0; j < exts.extent(1); ++j)
> + for(int k = 0; k < exts.extent(2); ++k)
> + {
> + storage[mapping(i, j, k)] = 1.0;
> + if constexpr (ValidForPacks)
> + VERIFY((md[Int(i), Int(j), Int(k)]) == 1.0);
> +
> + if constexpr (ValidForArrays)
> + {
> + std::array<Int, 3> ijk{Int(i), Int(j), Int(k)};
> + VERIFY((md[ijk]) == 1.0);
> + VERIFY((md[std::span(ijk)]) == 1.0);
> + }
> + storage[mapping(i, j, k)] = 0.0;
> + }
> +
> + if constexpr (!ValidForPacks)
> + static_assert(!indexable<MDSpan, Int, int, Int>);
> +
> + if constexpr (!ValidForArrays)
> + {
> + static_assert(!indexable<MDSpan, std::array<Int, 3>>);
> + static_assert(!indexable<MDSpan, std::span<Int, 3>>);
> + }
> + return true;
> + }
>
> constexpr bool
> test_swap()
> @@ -650,14 +689,20 @@ main()
> test_from_accessor();
> static_assert(test_from_accessor());
>
> - test_from_int_like();
> + test_from_int_like<int, true, true>();
> + static_assert(test_from_int_like<int, true, true>());
> + test_from_int_like<IntLike, true, true>();
> + test_from_int_like<ThrowingInt, false, false>();
> +
> test_from_opaque_accessor();
> test_from_base_class_accessor();
> test_from_mapping_like();
> static_assert(test_from_mapping_like());
>
> - test_access();
> - static_assert(test_access());
> + test_access<int, true, true>();
> + static_assert(test_access<int, true, true>());
> + test_access<IntLike, true, true>();
> + test_access<ThrowingInt, false, false>();
>
> test_swap();
> static_assert(test_swap());
> --
> 2.50.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250716/93ae1855/attachment-0001.htm>
More information about the Libstdc++
mailing list