5.4 KiB
[mdspan.sub.sub]
23 Containers library [containers]
23.7 Views [views]
23.7.3 Multidimensional access [views.multidim]
23.7.3.7 submdspan [mdspan.sub]
23.7.3.7.7 submdspan function template [mdspan.sub.sub]
template<class ElementType, class Extents, class LayoutPolicy, class AccessorPolicy, class... SliceSpecifiers> constexpr auto submdspan( const mdspan<ElementType, Extents, LayoutPolicy, AccessorPolicy>& src, SliceSpecifiers... slices) -> see below;
Let index_type be typename Extents::index_type.
Let sub_map_offset be the result ofsubmdspan_mapping(src.mapping(), slices...).
[Note 1:
This invocation of submdspan_mapping selects a function call via overload resolution on a candidate set that includes the lookup set found by argument-dependent lookup ([basic.lookup.argdep]).
â end note]
Constraints:
sizeof...(slices) equals Extents::rank(), and
the expression submdspan_mapping(src.mapping(), slices...) is well-formed when treated as an unevaluated operand.
Mandates:
-
decltype(submdspan_mapping(src.mapping(), slices...)) is a specialization of submdspan_mapping_result.
-
is_same_v<remove_cvref_t<decltype(sub_map_offset.mapping.extents())>,decltype(submdspan_extents(src.mapping(), slices...))> is true.
-
For each rank index k of src.extents(), exactly one of the following is true:
Sk models convertible_to<index_type>,
Sk models index-pair-like<index_type>,
is_convertible_v<Sk, full_extent_t> is true, or
Sk is a specialization of strided_slice.
Preconditions:
For each rank index k of src.extents(), all of the following are true:
if Sk is a specialization of strided_slice + (5.1.1.1) sk.extent=0, or
+
[(5.1.1.2)](#5.1.1.2)
sk.stride>0
0 ⤠first_<index_type, k>(slices...) ⤠last_(src.extents(), slices...) ⤠src.extent(k)
sub_map_offset.mapping.extents() == submdspan_extents(src.mapping(), slices...) is true; and
for each integer pack I which is a multidimensional index in sub_map_offset.mapping.extents(),sub_map_offset.mapping(I...) + sub_map_offset.offset == src.mapping()(src-indices(array{I...}, slices...)) is true.
[Note 2:
These conditions ensure that the mapping returned by submdspan_mapping matches the algorithmically expected index-mapping given the slice specifiers.
â end note]
Effects: Equivalent to:auto sub_map_result = submdspan_mapping(src.mapping(), slices...);return mdspan(src.accessor().offset(src.data_handle(), sub_map_result.offset), sub_map_result.mapping, typename AccessorPolicy::offset_policy(src.accessor()));
[Example 1:
Given a rank-3 mdspan grid3d representing a three-dimensional grid of regularly spaced points in a rectangular prism, the function zero_surface sets all elements on the surface of the 3-dimensional shape to zero.
It does so by reusing a function zero_2d that takes a rank-2 mdspan.
// zero out all elements in an mdspantemplate<class T, class E, class L, class A>void zero_2d(mdspan<T, E, L, A> a) {static_assert(a.rank() == 2); for (int i = 0; i < a.extent(0); i++)for (int j = 0; j < a.extent(1); j++) a[i, j] = 0;}// zero out just the surfacetemplate<class T, class E, class L, class A>void zero_surface(mdspan<T, E, L, A> grid3d) {static_assert(grid3d.rank() == 3); zero_2d(submdspan(grid3d, 0, full_extent, full_extent)); zero_2d(submdspan(grid3d, full_extent, 0, full_extent)); zero_2d(submdspan(grid3d, full_extent, full_extent, 0)); zero_2d(submdspan(grid3d, grid3d.extent(0) - 1, full_extent, full_extent)); zero_2d(submdspan(grid3d, full_extent, grid3d.extent(1) - 1, full_extent)); zero_2d(submdspan(grid3d, full_extent, full_extent, grid3d.extent(2) - 1));} â end example]