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 Specializations of submdspan_mapping [mdspan.sub.map]


23.7.3.7.7.1 Sliceable layout mapping requirements [mdspan.sub.map.sliceable]

23.7.3.7.7.2 Common [mdspan.sub.map.common]

23.7.3.7.7.3 layout_left specialization of submdspan_mapping [mdspan.sub.map.left]

23.7.3.7.7.4 layout_right specialization of submdspan_mapping [mdspan.sub.map.right]

23.7.3.7.7.5 layout_stride specialization of submdspan_mapping [mdspan.sub.map.stride]

23.7.3.7.7.6 layout_left_padded specialization of submdspan_mapping [mdspan.sub.map.leftpad]

23.7.3.7.7.7 layout_right_padded specialization of submdspan_mapping [mdspan.sub.map.rightpad]


23.7.3.7.7.1 Sliceable layout mapping requirements [mdspan.sub.map.sliceable]

Let:
  • M denote a layout mapping class;
  • IT denote M​::​extent_type​::​index_type;
  • m denote a value of type (possibly const) M;
  • M_rank be equal to M​::​extent_type​::​rank();
  • valid_slices denote a pack of (possibly const) objects for which sizeof...(valid_slices) == M_rank is true and, for each rank index i of m.extents(), valid_slices...[i] is a valid submdspan slice for the extent of m.extents();
  • invalid_slices denote a pack of objects for which sizeof...(invalid_slices) == M_rank is true and there exists an integer k such that the cv-unqualified type of invalid_slices...[k] is none of the following:
For the purpose of this section, the meaning of submdspan_mapping is established as if by performing argument-dependent lookup only ([basic.lookup.argdep]).
A type M meets the sliceable layout mapping requirements if
  • M meets the layout mapping requirements ([mdspan.layout.policy.reqmts]),
  • the expression submdspan_mapping(m, invalid_slices...) is ill-formed, and
  • the following expression is well-formed and has the specified semantics: submdspan_mapping(m, valid_slices...)
Result: A type SMR that is a specialization of type submdspan_mapping_result<SM> for some type SM such that
  • SM meets the layout mapping requirements ([mdspan.layout.policy.reqmts]),
  • SM​::​extents_type is a specialization of extents,
  • SM​::​extents_type​::​rank() equals MAP_RANK(valid_slices, M_rank), and
  • SM​::​extents_type​::​index_type denotes IT.
Returns: An object smr of type SMR such that
  • smr.mapping.extents() == submdspan_extents(m.extents(), valid_slices...) is true;
    and
  • for each integer pack i which is a multidimensional index in smr.mapping.extents(),
    smr.mapping(i...) + smr.offset == m(j) is true, where j is an integer pack such that
    • sizeof...(j) is equal to M_rank; and
    • for each rank index ρ of m.extents(), j...[ρ] is equal to the sum of
      • the lower bound of the submdspan slice range of valid_slices...[ρ] for extent ρ of m.extents(), and
      • zero if the type of valid_slices...[ρ] is a collapsing slice type, i...[MAP_RANK(valid_slices,ρ)] otherwise.
template<class LayoutMapping> concept sliceable-mapping = see below;
Let lm be an object of type LayoutMapping and let fe denote a pack of objects of type full_extent_t for which sizeof...(fe) == LayoutMapping​::​extents_type​::​rank() is true.
A type LayoutMapping satisfies sliceable-mapping if
  • the expression submdspan_mapping(m, fe...) is well-formed when treated as an unevaluated operand, and
  • the type of that expression is a specialization of submdspan_mapping_result.
A type LayoutMapping models sliceable-mapping if LayoutMapping meets the sliceable layout mapping requirements.

23.7.3.7.7.2 Common [mdspan.sub.map.common]

The following elements apply to all functions in [mdspan.sub.map].
Constraints: sizeof...(SpliceSpecifiers) equals extents_type​::​rank().
Mandates: For each rank index k of extents(), SliceSpecifiers...[k] is a valid submdspan slice type for the extent of Extents.
Preconditions: For each rank index k of extents(), slices...[k] is a valid slice for the extent of extents().
Let sub_ext be the result of submdspan_extents(extents(), slices...) and let SubExtents be decltype(sub_ext).
Let sub_strides be an array<SubExtents​::​index_type, SubExtents​::​rank()> such that for each rank index k of extents() for which the type of slices...[k] is not a collapsing slice type, sub_strides[MAP_RANK(slices,k)] equals:
  • stride(k) * s.stride if the type of s is a specialization of strided_slice and s.stride < s.extent is true, where s is slices...[k];
  • otherwise, stride(k).
Let ls be a pack of values of index_type, where the element equals the lower bound of the submdspan slice range of slices...[ρ] for extent ρ of extents().
If ls...[k] equals extents().extent(k) for any rank index k of extents(), then let offset be a value of type size_t equal to required_span_size().
Otherwise, let offset be a value of type size_t equal to operator()(ls...).

23.7.3.7.7.3 layout_left specialization of submdspan_mapping [mdspan.sub.map.left]

template<class Extents> template<class... SliceSpecifiers> constexpr auto layout_left::mapping<Extents>::submdspan-mapping-impl( SliceSpecifiers... slices) const -> see below;
Returns:
  • submdspan_mapping_result{*this, 0}, if Extents​::​rank() == 0 is true;
  • otherwise, submdspan_mapping_result{layout_left​::​mapping(sub_ext), offset},
    if SubExtents​::​rank() == 0 is true;
  • otherwise, submdspan_mapping_result{layout_left​::​mapping(sub_ext), offset}, if
    • for each k in the range [0, SubExtents​::​rank() - 1), SpliceSpecifiers...[k] denotes full_extent_t; and
    • for k equal to SubExtents​::​rank() - 1, SpliceSpecifiers...[k] is a unit-stride slice type;
    [Note 1: 
    If the above conditions are true, all SpliceSpecifiers...[k] with k larger than SubExtents​​::​rank​() - 1 are convertible to index_type.
    — end note]
  • otherwise, submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)), offset} if for a value u for which is the smallest value p larger than zero for which SliceSpecifiers...[​p] is a unit-stride slice type, the following conditions are met:
    • SliceSpecifiers...[0] is a unit-stride slice type; and
    • for each k in the range [u + 1, u + SubExtents​::​rank() - 1), SliceSpecifiers...[k] denotes full_extent_t; and
    • for k equal to u + SubExtents​::​rank() - 1, SliceSpecifiers...[k] is a unit-stride slice type;
    and where S_static is:
    • dynamic_extent, if static_extent(k) is dynamic_extent for any k in the range [0, u + 1),
    • otherwise, the product of all values static_extent(k) for k in the range [0, u + 1);
  • otherwise, submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
template<class Extents> template<class... SliceSpecifiers> constexpr auto layout_right::mapping<Extents>::submdspan-mapping-impl( SliceSpecifiers... slices) const -> see below;
Returns:
  • submdspan_mapping_result{*this, 0}, if Extents​::​rank() == 0 is true;
  • otherwise, submdspan_mapping_result{layout_right​::​mapping(sub_ext), offset},
    if SubExtents​::​rank() == 0 is true;
  • otherwise, submdspan_mapping_result{layout_right​::​mapping(sub_ext), offset}, if
    • for each k in the range [rank_ - SubExtents​::​rank() + 1, rank_),
      SliceSpecifiers...[k] denotes full_extent_t; and
    • for k equal to rank_ - SubExtents​::​rank(), SliceSpecifiers...[k] is a unit-stride slice type;
    [Note 1: 
    If the above conditions are true, all SliceSpecifiers...[k] with
    are convertible to index_type.
    — end note]
  • otherwise, submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext, stride(rank_ - u - 2)), offset} if for a value u for which is the largest value p smaller than rank_ - 1 for which SliceSpecifiers...[p] is a unit-stride slice type, the following conditions are met:
    • for k equal to rank_ - 1, SliceSpecifiers...[k] is a unit-stride slice type; and
    • for each k in the range [rank_ - SubExtents​::​rank() - u + 1, rank_ - u - 1),
      SliceSpecifiers...[p] denotes full_extent_t; and
    • for k equal to rank_ - SubExtents​::​rank() - u, SliceSpecifiers...[k] is a unit-stride slice type;
    and where S_static is:
    • dynamic_extent, if static_extent(k) is dynamic_extent for any k in the range [rank_ - u - 1, rank_),
    • otherwise, the product of all values static_extent(k) for k in the range [rank_ - u - 1, rank_);
  • otherwise, submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}

23.7.3.7.7.5 layout_stride specialization of submdspan_mapping [mdspan.sub.map.stride]

template<class Extents> template<class... SliceSpecifiers> constexpr auto layout_stride::mapping<Extents>::submdspan-mapping-impl( SliceSpecifiers... slices) const -> see below;
Returns:
  • submdspan_mapping_result{*this, 0}, if Extents​::​rank() == 0 is true;
  • otherwise, submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}

23.7.3.7.7.6 layout_left_padded specialization of submdspan_mapping [mdspan.sub.map.leftpad]

template<class Extents> template<class... SliceSpecifiers> constexpr auto layout_left_padded::mapping<Extents>::submdspan-mapping-impl( SliceSpecifiers... slices) const -> see below;
Returns:
  • submdspan_mapping_result{*this, 0}, if Extents​::​rank() == 0 is true;
  • otherwise, submdspan_mapping_result{layout_left​::​mapping(sub_ext), offset}, if rank_ == 1 is true or SubExtents​::​rank() == 0 is true;
  • otherwise, submdspan_mapping_result{layout_left​::​mapping(sub_ext), offset}, if
    • SubExtents​::​rank() == 1 is true and
    • SliceSpecifiers...[0] is a unit-stride slice type;
  • otherwise, submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)), offset} if for a value u for which u + 1 is the smallest value p larger than zero for which SliceSpecifiers​...[p] is a unit-stride slice type, the following conditions are met:
    • SliceSpecifiers...[0] is a unit-stride slice type; and
    • for each k in the range [u + 1, u + SubExtents​::​rank() - 1), SliceSpecifiers...[k] denotes full_extent_t; and
    • for k equal to u + SubExtents​::​rank() - 1, SliceSpecifiers...[k] is a unit-stride slice type;
    where S_static is:
    • dynamic_extent, if static-padding-stride is dynamic_extent or static_extent(k) is dynamic_extent for any k in the range [1, u + 1),
    • otherwise, the product of static-padding-stride and all values static_extent(k) for k in the range [1, u + 1);
  • otherwise, submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}

23.7.3.7.7.7 layout_right_padded specialization of submdspan_mapping [mdspan.sub.map.rightpad]

template<class Extents> template<class... SliceSpecifiers> constexpr auto layout_right_padded::mapping<Extents>::submdspan-mapping-impl( SliceSpecifiers... slices) const -> see below;
Returns:
  • submdspan_mapping_result{*this, 0}, if rank_ == 0 is true;
  • otherwise, submdspan_mapping_result{layout_right​::​mapping(sub_ext), offset},
    if rank_ == 1 is true or SubExtents​::​rank() == 0 is true;
  • otherwise, submdspan_mapping_result{layout_right​::​mapping(sub_ext), offset}, if
    • SubExtents​::​rank() == 1 is true and
    • for k equal to rank_ - 1, SliceSpecifiers...[k] is a unit-stride slice type;
  • otherwise, submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext, stride(rank_ - u - 2)), offset} if for a value u for which rank_ - u - 2 is the largest value p smaller than rank_ - 1 for which SliceSpecifiers...[p] is a unit-stride slice type, the following conditions are met:
    • for k equal to rank_ - 1, SliceSpecifiers...[k] is a unit-stride slice type; and
    • for each k in the range [rank_ - SubExtents​::​rank() - u + 1, rank_ - u - 1),
      SliceSpecifiers...[k] denotes full_extent_t; and
    • for k equal to rank_ - SubExtents​::​rank() - u, SliceSpecifiers...[k] is a unit-stride slice type;
    and where S_static is:
    • dynamic_extent if static-padding-stride is dynamic_extent or for any k in the range [rank_ - u - 1, rank_ - 1) static_extent(k) is dynamic_extent,
    • otherwise, the product of static-padding-stride and all values static_extent(k) with k in the range [rank_ - u - 1, rank_ - 1);
  • otherwise, submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}