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.1 Overview [mdspan.sub.overview]

The submdspan facilities create a new mdspan viewing a subset of elements of an existing input mdspan.
The subset viewed by the created mdspan is determined by the SliceSpecifier arguments.
Given a signed or unsigned integer type IndexType, a type S is a submdspan slice type for IndexType if at least one of the following holds:
  • is_convertible_v<S, full_extent_t> is true;
  • is_convertible_v<S, IndexType> is true;
  • S is a specialization of strided_slice and is_convertible_v<X, IndexType> is true for X denoting S​::​offset_type, S​::​extent_type, and S​::​stride_type; or
  • all of the following hold:
    • the declaration auto [...ls] = std​::​move(s); is well-formed for some object s of type S,
    • sizeof...(ls) is equal to 2, and
    • (is_convertible_v<decltype(std​::​move(ls)), IndexType> && ...) is true.
Given a signed or unsigned integer type IndexType, a type S is a canonical submdspan index type for IndexType if S is either IndexType or constant_wrapper<v> for some value v of type IndexType, such that v is greater than or equal to zero.
Given a signed or unsigned integer type IndexType, a type S is a canonical submdspan slice type for IndexType if exactly one of the following is true:
  • S is full_extent_t;
  • S is a canonical submdspan index type for IndexType; or
  • S is a specialization of strided_slice where all of the following hold:
    • S​::​offset_type, S​::​extent_type, and S​::​stride_type are all canonical submdspan index types for IndexType; and
    • if S​::​stride_type and S​::​extent_type are both specializations of constant_wrapper, then S​::​stride_type​::​value is greater than zero.
A type S is a collapsing slice type if it is neither full_extent_t nor a specialization of strided_slice.
[Note 1: 
Each collapsing slice type in submdspan_mapping's parameter pack of slice specifier types reduces the rank of the result of submdspan_mapping by one.
— end note]
A type S is a unit-stride slice type if
  • S is a specialization of strided_slice where S​::​stride_type is a specialization of constant_wrapper and S​::​stride_type​::​value is equal to 1, or
  • S denotes full_extent_t.
Given an object e of type E that is a specialization of extents, and an object s of type S that is a canonical submdspan slice type for E​::​index_type, the submdspan slice range of s for the extent of e is:
  • [0, e.extent(k)), if S is full_extent_t;
  • [E​::​index_type(s.offset), E​::​index_type(s.offset + s.extent)), if S is a specialization of strided_slice; otherwise
  • [E​::​index_type(s), )
Given a type E that is a specialization of extents, a type S is a valid submdspan slice type for the extent of E if S is a canonical slice type for E​::​index_type, and for x equal to E​::​static_extent(k), either x is equal to dynamic_extent; or
  • if S is a specialization of strided_slice:
    • if S​::​offset_type is a specialization of constant_wrapper, then S​::​offset_type​::​value is less than or equal to x;
    • if S​::​offset_type is a specialization of constant_wrapper, then S​::​extent_type​::​value is less than or equal to x; and
    • if both S​::​offset_type and S​::​extent_type are specializations of constant_wrapper, then S​::​offset_type​::​value + S​::​extent_type​::​value is less than or equal to x; or
  • if S is a specialization of constant_wrapper, then S​::​value is less than x.
Given an object e of type E that is a specialization of extents and an object s of type S, s is a valid submdspan slice for the extent of e if
  • S is a valid submdspan slice type for the extent of E;
  • the interval of e contains the submdspan slice range of s for the extent of e; and
  • if S is a specialization of strided_slice, then:
    • s.extent is greater than or equal to zero, and
    • either s.extent equals zero or s.stride is greater than zero.