libstdc++: Implement submdspan_mapping for layout_stride. [PR110352]

Add submdspan_mapping for layout_stride as in P3663.

	PR libstdc++/110352

libstdc++-v3/ChangeLog:

	* include/std/mdspan (layout_stride::mapping::submdspan_mapping): New
	friend function.
	* testsuite/23_containers/mdspan/submdspan/selections/stride.cc:
	Instantiate tests for layout_stride.
	* testsuite/23_containers/mdspan/submdspan/submdspan_neg.cc:
	Ditto.
	* testsuite/23_containers/mdspan/submdspan/submdspan_mapping.cc:
	Add tests for layout_stride.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
This commit is contained in:
Luc Grosheintz 2025-12-08 21:23:43 +01:00 committed by Tomasz Kamiński
parent c1c5ada671
commit 57d53be024
4 changed files with 56 additions and 0 deletions

View File

@ -1928,6 +1928,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
private:
#if __glibcxx_submdspan
template<typename... _Slices>
requires (extents_type::rank() == sizeof...(_Slices))
friend constexpr auto
submdspan_mapping(const mapping& __mapping, _Slices... __slices)
{
if constexpr (sizeof...(_Slices) == 0)
return submdspan_mapping_result{__mapping, 0};
else
{
auto __offset = __mdspan::__suboffset(__mapping, __slices...);
auto __sub_exts = __mdspan::__subextents(__mapping.extents(), __slices...);
auto __sub_strides
= __mdspan::__substrides<decltype(__sub_exts)>(__mapping, __slices...);
return submdspan_mapping_result{
layout_stride::mapping(__sub_exts, __sub_strides), __offset};
}
}
#endif
using _Strides = typename __array_traits<index_type,
extents_type::rank()>::_Type;
[[no_unique_address]] extents_type _M_extents;

View File

@ -0,0 +1,9 @@
// { dg-do run { target c++26 } }
#include "testcases.h"
int
main()
{
test_all<std::layout_stride>();
return 0;
}

View File

@ -123,6 +123,21 @@ template<typename Layout>
return true;
}
constexpr bool
test_layout_stride_return_types()
{
auto exts = std::extents(3, 5);
auto m = std::layout_stride::mapping(exts, std::array{2, 12});
using index_type = decltype(exts)::index_type;
auto s1 = std::strided_slice{index_type(2), index_type(2),
std::cw<index_type(2)>};
auto result = submdspan_mapping(m, index_type(1), s1);
using layout_type = decltype(result.mapping)::layout_type;
static_assert(std::same_as<layout_type, std::layout_stride>);
return true;
}
int
main()
{
@ -132,6 +147,9 @@ main()
test_layout_unpadded_return_types<std::layout_right>();
static_assert(test_layout_unpadded_return_types<std::layout_right>());
test_layout_stride_return_types();
static_assert(test_layout_stride_return_types());
test_layout_unpadded_padding_value<std::layout_left>();
static_assert(test_layout_unpadded_padding_value<std::layout_left>());

View File

@ -25,6 +25,7 @@ template<typename Layout>
}
static_assert(test_int_under<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_int_under<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_int_under<std::layout_stride>()); // { dg-error "expansion of" }
template<typename Layout>
constexpr bool
@ -35,6 +36,7 @@ template<typename Layout>
}
static_assert(test_int_over<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_int_over<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_int_over<std::layout_stride>()); // { dg-error "expansion of" }
template<typename Layout>
constexpr bool
@ -45,6 +47,7 @@ template<typename Layout>
}
static_assert(test_tuple_under<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_tuple_under<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_tuple_under<std::layout_stride>()); // { dg-error "expansion of" }
template<typename Layout>
constexpr bool
@ -55,6 +58,7 @@ template<typename Layout>
}
static_assert(test_tuple_reversed<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_tuple_reversed<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_tuple_reversed<std::layout_stride>()); // { dg-error "expansion of" }
template<typename Layout>
constexpr bool
@ -65,6 +69,7 @@ template<typename Layout>
}
static_assert(test_tuple_over<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_tuple_over<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_tuple_over<std::layout_stride>()); // { dg-error "expansion of" }
template<typename Layout>
constexpr bool
@ -75,6 +80,7 @@ template<typename Layout>
}
static_assert(test_strided_slice_zero<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_strided_slice_zero<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_strided_slice_zero<std::layout_stride>()); // { dg-error "expansion of" }
template<typename Layout>
constexpr bool
@ -85,6 +91,7 @@ template<typename Layout>
}
static_assert(test_strided_slice_offset_under<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_strided_slice_offset_under<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_strided_slice_offset_under<std::layout_stride>()); // { dg-error "expansion of" }
template<typename Layout>
constexpr bool
@ -95,6 +102,7 @@ template<typename Layout>
}
static_assert(test_strided_slice_offset_over<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_strided_slice_offset_over<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_strided_slice_offset_over<std::layout_stride>()); // { dg-error "expansion of" }
template<typename Layout>
constexpr bool
@ -105,6 +113,7 @@ template<typename Layout>
}
static_assert(test_strided_slice_extent_over<std::layout_left>()); // { dg-error "expansion of" }
static_assert(test_strided_slice_extent_over<std::layout_right>()); // { dg-error "expansion of" }
static_assert(test_strided_slice_extent_over<std::layout_stride>()); // { dg-error "expansion of" }
// { dg-prune-output "static assertion failed" }
// { dg-prune-output "__glibcxx_assert_fail" }