[mdspan.layout]

# 23 Containers library [[containers]](./#containers)

## 23.7 Views [[views]](views#mdspan.layout)

### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout)

#### 23.7.3.4 Layout mapping [mdspan.layout]

#### [23.7.3.4.1](#general) General [[mdspan.layout.general]](mdspan.layout.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21522)

In [[mdspan.layout.reqmts]](#reqmts "23.7.3.4.2 Requirements") and [[mdspan.layout.policy.reqmts]](#policy.reqmts "23.7.3.4.3 Layout mapping policy requirements"):

- [(1.1)](#general-1.1)

  M denotes a layout mapping class[.](#general-1.1.sentence-1)

- [(1.2)](#general-1.2)

  m denotes a (possibly const) value of type M[.](#general-1.2.sentence-1)

- [(1.3)](#general-1.3)

  i and j are packs of (possibly const) integers
that are multidimensional indices in m.extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#general-1.3.sentence-1)
  [*Note [1](#general-note-1)*:
  The type of each element of the packs can be a different integer type[.](#general-1.3.sentence-2)
 â *end note*]

- [(1.4)](#general-1.4)

  r is a (possibly const) rank index of typename M​::​extents_type[.](#general-1.4.sentence-1)

- [(1.5)](#general-1.5)

  dr is a pack of (possibly const) integers
for which sizeof...(dr) == M​::​extents_type​::​rank() is true,
the rth element is equal to 1, and
all other elements are equal to 0[.](#general-1.5.sentence-1)

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21549)

In [[mdspan.layout.reqmts]](#reqmts "23.7.3.4.2 Requirements") through [[mdspan.layout.stride]](#stride "23.7.3.4.7 Class template layout_­stride​::​mapping"):

- [(2.1)](#general-2.1)

Let *is-mapping-of* be the exposition-only variable template defined as follows:template<class Layout, class Mapping>constexpr bool *is-mapping-of* = // *exposition only* is_same_v<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>;

- [(2.2)](#general-2.2)

Let *is-layout-left-padded-mapping-of* be
the exposition-only variable template defined as follows:template<class Mapping>constexpr bool *is-layout-left-padded-mapping-of* = *see below*; // *exposition only* where *is-layout-left-padded-mapping-of*<Mapping> is true if and only if Mapping denotes
a specialization of layout_left_padded<S>​::​mapping for some value S of type size_t.

- [(2.3)](#general-2.3)

Let *is-layout-right-padded-mapping-of* be
the exposition-only variable template defined as follows:template<class Mapping>constexpr bool *is-layout-right-padded-mapping-of* = *see below*; // *exposition only* where *is-layout-right-padded-mapping-of*<Mapping> is true if and only if Mapping denotes
a specialization of layout_right_padded<S>​::​mapping for some value S of type size_t.

- [(2.4)](#general-2.4)

For nonnegative integers x and y,
let LEAST-MULTIPLE-AT-LEAST(x,y) denote
  * [(2.4.1)](#general-2.4.1)

y if x is zero,

  * [(2.4.2)](#general-2.4.2)

otherwise, the least multiple of x that is greater than or equal to y.

#### [23.7.3.4.2](#reqmts) Requirements [[mdspan.layout.reqmts]](mdspan.layout.reqmts)

[1](#reqmts-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21594)

A type M meets the [*layout mapping*](#def:layout_mapping "23.7.3.4.2 Requirements [mdspan.layout.reqmts]") requirements if

- [(1.1)](#reqmts-1.1)

M models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]") and [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_­comparable [concept.equalitycomparable]"),

- [(1.2)](#reqmts-1.2)

is_nothrow_move_constructible_v<M> is true,

- [(1.3)](#reqmts-1.3)

is_nothrow_move_assignable_v<M> is true,

- [(1.4)](#reqmts-1.4)

is_nothrow_swappable_v<M> is true, and

- [(1.5)](#reqmts-1.5)

the following types and expressions are well-formed and
have the specified semantics.

[ð](#reqmts-itemdecl:1)

`typename M::extents_type
`

[2](#reqmts-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21616)

*Result*: A type that is a specialization of extents[.](#reqmts-2.sentence-1)

[ð](#reqmts-itemdecl:2)

`typename M::index_type
`

[3](#reqmts-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21626)

*Result*: typename M​::​extents_type​::​index_type[.](#reqmts-3.sentence-1)

[ð](#reqmts-itemdecl:3)

`typename M::rank_type
`

[4](#reqmts-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21636)

*Result*: typename M​::​extents_type​::​rank_type[.](#reqmts-4.sentence-1)

[ð](#reqmts-itemdecl:4)

`typename M::layout_type
`

[5](#reqmts-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21646)

*Result*: A type MP that meets
the layout mapping policy requirements ([[mdspan.layout.policy.reqmts]](#policy.reqmts "23.7.3.4.3 Layout mapping policy requirements")) and
for which *is-mapping-of*<MP, M> is true[.](#reqmts-5.sentence-1)

[ð](#reqmts-itemdecl:5)

`m.extents()
`

[6](#reqmts-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21658)

*Result*: const typename M​::​extents_type&

[ð](#reqmts-itemdecl:6)

`m(i...)
`

[7](#reqmts-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21668)

*Result*: typename M​::​index_type

[8](#reqmts-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21672)

*Returns*: A nonnegative integer
less than numeric_limits<typename M​::​index_type>​::​max() and
less than or equal to numeric_limits<size_t>​::​max()[.](#reqmts-8.sentence-1)

[ð](#reqmts-itemdecl:7)

`m(i...) == m(static_cast<typename M::index_type>(i)...)
`

[9](#reqmts-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21684)

*Result*: bool

[10](#reqmts-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21688)

*Returns*: true

[ð](#reqmts-itemdecl:8)

`m.required_span_size()
`

[11](#reqmts-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21698)

*Result*: typename M​::​index_type

[12](#reqmts-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21702)

*Returns*: If the size of the multidimensional index space m.extents() is 0,
then 0,
else 1 plus the maximum value of m(i...) for all i[.](#reqmts-12.sentence-1)

[ð](#reqmts-itemdecl:9)

`m.is_unique()
`

[13](#reqmts-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21714)

*Result*: bool

[14](#reqmts-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21718)

*Returns*: true only if
for every i and j where (i != j || ...) is true,m(i...) != m(j...) is true[.](#reqmts-14.sentence-1)

[*Note [1](#reqmts-note-1)*:

A mapping can return false even if the condition is met[.](#reqmts-14.sentence-2)

For certain layouts, it is possibly not feasible to determine efficiently
whether the layout is unique[.](#reqmts-14.sentence-3)

â *end note*]

[ð](#reqmts-itemdecl:10)

`m.is_exhaustive()
`

[15](#reqmts-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21735)

*Result*: bool

[16](#reqmts-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21739)

*Returns*: true only if
for all k in the range [0, m.required_span_size()) there exists an i such that m(i...) equals k[.](#reqmts-16.sentence-1)

[*Note [2](#reqmts-note-2)*:

A mapping can return false even if the condition is met[.](#reqmts-16.sentence-2)

For certain layouts, it is possibly not feasible to determine efficiently
whether the layout is exhaustive[.](#reqmts-16.sentence-3)

â *end note*]

[ð](#reqmts-itemdecl:11)

`m.is_strided()
`

[17](#reqmts-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21756)

*Result*: bool

[18](#reqmts-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21760)

*Returns*: true only if
for every rank index r of m.extents() there exists an integer sr such that,
for all i where (i+dr) is
a multidimensional index in m.extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview")),m((i + dr)...) - m(i...) equals sr[.](#reqmts-18.sentence-1)

[*Note [3](#reqmts-note-3)*:

This implies that for a strided layoutm(i0,â¦,ik)=m(0,â¦,0)+i0Ãs0+â¯+ikÃsk[.](#reqmts-18.sentence-2)

â *end note*]

[*Note [4](#reqmts-note-4)*:

A mapping can return false even if the condition is met[.](#reqmts-18.sentence-3)

For certain layouts, it is possibly not feasible to determine efficiently
whether the layout is strided[.](#reqmts-18.sentence-4)

â *end note*]

[ð](#reqmts-itemdecl:12)

`m.stride(r)
`

[19](#reqmts-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21784)

*Preconditions*: m.is_strided() is true[.](#reqmts-19.sentence-1)

[20](#reqmts-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21788)

*Result*: typename M​::​index_type

[21](#reqmts-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21792)

*Returns*: sr as defined in m.is_strided() above[.](#reqmts-21.sentence-1)

[22](#reqmts-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21796)

[*Note [5](#reqmts-note-5)*:

It is not required for m.stride(r) to be well-formed
if m.extents().rank() is zero,
even if m.is_always_strided() is true[.](#reqmts-22.sentence-1)

â *end note*]

[ð](#reqmts-itemdecl:13)

`M::is_always_unique()
`

[23](#reqmts-23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21809)

*Result*: A constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) of type bool[.](#reqmts-23.sentence-1)

[24](#reqmts-24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21813)

*Returns*: true only if m.is_unique() is true for all possible objects m of type M[.](#reqmts-24.sentence-1)

[*Note [6](#reqmts-note-6)*:

A mapping can return false even if the above condition is met[.](#reqmts-24.sentence-2)

For certain layout mappings, it is possibly not feasible to determine
whether every instance is unique[.](#reqmts-24.sentence-3)

â *end note*]

[ð](#reqmts-itemdecl:14)

`M::is_always_exhaustive()
`

[25](#reqmts-25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21829)

*Result*: A constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) of type bool[.](#reqmts-25.sentence-1)

[26](#reqmts-26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21833)

*Returns*: true only if m.is_exhaustive() is true for all possible objects m of type M[.](#reqmts-26.sentence-1)

[*Note [7](#reqmts-note-7)*:

A mapping can return false even if the above condition is met[.](#reqmts-26.sentence-2)

For certain layout mappings, it is possibly not feasible to determine
whether every instance is exhaustive[.](#reqmts-26.sentence-3)

â *end note*]

[ð](#reqmts-itemdecl:15)

`M::is_always_strided()
`

[27](#reqmts-27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21849)

*Result*: A constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) of type bool[.](#reqmts-27.sentence-1)

[28](#reqmts-28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21853)

*Returns*: true only if m.is_strided() is true for all possible objects m of type M[.](#reqmts-28.sentence-1)

[*Note [8](#reqmts-note-8)*:

A mapping can return false even if the above condition is met[.](#reqmts-28.sentence-2)

For certain layout mappings, it is possibly not feasible to determine
whether every instance is strided[.](#reqmts-28.sentence-3)

â *end note*]

#### [23.7.3.4.3](#policy.reqmts) Layout mapping policy requirements [[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts)

[1](#policy.reqmts-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21866)

A type MP meets the [*layout mapping policy*](#def:layout_mapping_policy "23.7.3.4.3 Layout mapping policy requirements [mdspan.layout.policy.reqmts]") requirements
if for a type E that is a specialization of extents,MP​::​mapping<E> is valid and denotes a type X that meets the layout mapping requirements ([[mdspan.layout.reqmts]](#reqmts "23.7.3.4.2 Requirements")), and
for which the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") X​::​layout_type is valid and
denotes the type MP and
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") X​::​extents_type denotes E[.](#policy.reqmts-1.sentence-1)

#### [23.7.3.4.4](#policy.overview) Layout mapping policies [[mdspan.layout.policy.overview]](mdspan.layout.policy.overview)

namespace std {struct layout_left {template<class Extents>class mapping; }; struct layout_right {template<class Extents>class mapping; }; struct layout_stride {template<class Extents>class mapping; }; template<size_t PaddingValue>struct layout_left_padded {template<class Extents> class mapping; }; template<size_t PaddingValue>struct layout_right_padded {template<class Extents> class mapping; };}

[1](#policy.overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21903)

Each of layout_left, layout_right, and layout_stride,
as well as each specialization oflayout_left_padded and layout_right_padded,
meets the layout mapping policy requirements and is a trivially copyable type[.](#policy.overview-1.sentence-1)

Furthermore,is_trivially_default_constructible_v<T> is true for any such type T[.](#policy.overview-1.sentence-2)

#### [23.7.3.4.5](#left) Class template layout_left​::​mapping [[mdspan.layout.left]](mdspan.layout.left)

#### [23.7.3.4.5.1](#left.overview) Overview [[mdspan.layout.left.overview]](mdspan.layout.left.overview)

[1](#left.overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21916)

layout_left provides a layout mapping
where the leftmost extent has stride 1, and
strides increase left-to-right as the product of extents[.](#left.overview-1.sentence-1)

namespace std {template<class Extents>class layout_left::mapping {public:using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_left; // [[mdspan.layout.left.cons]](#left.cons "23.7.3.4.5.2 Constructors"), constructorsconstexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const mapping<OtherExtents>&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_right::mapping<OtherExtents>&) noexcept; template<class LayoutLeftPaddedMapping>constexpr explicit(!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type,
 extents_type>) mapping(const LayoutLeftPaddedMapping&) noexcept; template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&); constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.left.obs]](#left.obs "23.7.3.4.5.3 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept { return true; }static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }static constexpr bool is_exhaustive() noexcept { return true; }static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; template<class OtherExtents>friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; private: extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_­mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}

[2](#left.overview-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21990)

If Extents is not a specialization of extents,
then the program is ill-formed[.](#left.overview-2.sentence-1)

[3](#left.overview-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21994)

layout_left​::​mapping<E> is a trivially copyable type
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#left.overview-3.sentence-1)

[4](#left.overview-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21998)

*Mandates*: If Extents​::​rank_dynamic() == 0 is true,
then the size of the multidimensional index space Extents() is representable as a value of type typename Extents​::​index_type[.](#left.overview-4.sentence-1)

#### [23.7.3.4.5.2](#left.cons) Constructors [[mdspan.layout.left.cons]](mdspan.layout.left.cons)

[ð](#lib:layout_left::mapping,constructor)

`constexpr mapping(const extents_type& e) noexcept;
`

[1](#left.cons-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22012)

*Preconditions*: The size of the multidimensional index space e is representable as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#left.cons-1.sentence-1)

[2](#left.cons-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22017)

*Effects*: Direct-non-list-initializes *extents_* with e[.](#left.cons-2.sentence-1)

[ð](#lib:layout_left::mapping,constructor_)

`template<class OtherExtents>
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
    mapping(const mapping<OtherExtents>& other) noexcept;
`

[3](#left.cons-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22030)

*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#left.cons-3.sentence-1)

[4](#left.cons-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22034)

*Preconditions*: other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#left.cons-4.sentence-1)

[5](#left.cons-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22039)

*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#left.cons-5.sentence-1)

[ð](#lib:layout_left::mapping,constructor__)

`template<class OtherExtents>
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
    mapping(const layout_right::mapping<OtherExtents>& other) noexcept;
`

[6](#left.cons-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22052)

*Constraints*: 

- [(6.1)](#left.cons-6.1)

extents_type​::​rank() <= 1 is true, and

- [(6.2)](#left.cons-6.2)

is_constructible_v<extents_type, OtherExtents> is true[.](#left.cons-6.sentence-1)

[7](#left.cons-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22061)

*Preconditions*: other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#left.cons-7.sentence-1)

[8](#left.cons-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22066)

*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#left.cons-8.sentence-1)

[ð](#lib:layout_left::mapping,constructor___)

`template<class LayoutLeftPaddedMapping>
  constexpr explicit(!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type,
                                       extents_type>)
    mapping(const LayoutLeftPaddedMapping&) noexcept;
`

[9](#left.cons-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22080)

*Constraints*: 

- [(9.1)](#left.cons-9.1)

  *is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#left.cons-9.1.sentence-1)

- [(9.2)](#left.cons-9.2)

  is_constructible_v<extents_type, typename LayoutLeftPaddedMapping​::​extents_type>  
is true[.](#left.cons-9.2.sentence-1)

[10](#left.cons-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22089)

*Mandates*: If

- [(10.1)](#left.cons-10.1)

Extents​::​rank() is greater than one,

- [(10.2)](#left.cons-10.2)

Extents​::​static_extent(0) does not equal dynamic_extent, and

- [(10.3)](#left.cons-10.3)

LayoutLeftPaddedMapping​::​*static-padding-stride* does not equal dynamic_extent,

then Extents​::​static_extent(0) equalsLayoutLeftPaddedMapping​::​*static-padding-stride*[.](#left.cons-10.sentence-1)

[11](#left.cons-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22104)

*Preconditions*: 

- [(11.1)](#left.cons-11.1)

  If extents_type​::​rank() > 1 is true,
then other.stride(1) equals other.extents(0)[.](#left.cons-11.1.sentence-1)

- [(11.2)](#left.cons-11.2)

  other.required_span_size() is representable as
a value of type index_type[.](#left.cons-11.2.sentence-1)

[12](#left.cons-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22115)

*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#left.cons-12.sentence-1)

[ð](#lib:layout_left::mapping,constructor____)

`template<class OtherExtents>
  constexpr explicit(extents_type::rank() > 0)
    mapping(const layout_stride::mapping<OtherExtents>& other);
`

[13](#left.cons-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22128)

*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#left.cons-13.sentence-1)

[14](#left.cons-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22132)

*Preconditions*: 

- [(14.1)](#left.cons-14.1)

If extents_type​::​rank() > 0 is true,
then for all r in the range [0, extents_type​::​rank()),other.stride(r) equalsother.extents().*fwd-prod-of-extents*(r), and

- [(14.2)](#left.cons-14.2)

other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#left.cons-14.sentence-1)

[15](#left.cons-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22145)

*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#left.cons-15.sentence-1)

#### [23.7.3.4.5.3](#left.obs) Observers [[mdspan.layout.left.obs]](mdspan.layout.left.obs)

[ð](#lib:required_span_size,layout_left::mapping)

`constexpr index_type required_span_size() const noexcept;
`

[1](#left.obs-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22158)

*Returns*: extents().*fwd-prod-of-extents*(extents_type​::​rank())[.](#left.obs-1.sentence-1)

[ð](#lib:operator(),layout_left::mapping)

`template<class... Indices>
  constexpr index_type operator()(Indices... i) const noexcept;
`

[2](#left.obs-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22170)

*Constraints*: 

- [(2.1)](#left.obs-2.1)

sizeof...(Indices) == extents_type​::​rank() is true,

- [(2.2)](#left.obs-2.2)

(is_convertible_v<Indices, index_type> && ...) is true, and

- [(2.3)](#left.obs-2.3)

(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#left.obs-2.sentence-1)

[3](#left.obs-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22181)

*Preconditions*: extents_type​::​*index-cast*(i) is
a multidimensional index in *extents_* ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#left.obs-3.sentence-1)

[4](#left.obs-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22186)

*Effects*: Let P be a parameter pack such thatis_same_v<index_sequence_for<Indices...>, index_sequence<P...>> is true[.](#left.obs-4.sentence-1)

Equivalent to:return ((static_cast<index_type>(i) * stride(P)) + ... + 0);

[ð](#lib:stride,layout_left::mapping)

`constexpr index_type stride(rank_type i) const noexcept;
`

[5](#left.obs-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22205)

*Constraints*: extents_type​::​rank() > 0 is true[.](#left.obs-5.sentence-1)

[6](#left.obs-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22209)

*Preconditions*: i < extents_type​::​rank() is true[.](#left.obs-6.sentence-1)

[7](#left.obs-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22213)

*Returns*: extents().*fwd-prod-of-extents*(i)[.](#left.obs-7.sentence-1)

[ð](#lib:operator==,layout_left::mapping)

`template<class OtherExtents>
  friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
`

[8](#left.obs-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22225)

*Constraints*: extents_type​::​rank() == OtherExtents​::​rank() is true[.](#left.obs-8.sentence-1)

[9](#left.obs-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22229)

*Effects*: Equivalent to: return x.extents() == y.extents();

#### [23.7.3.4.6](#right) Class template layout_right​::​mapping [[mdspan.layout.right]](mdspan.layout.right)

#### [23.7.3.4.6.1](#right.overview) Overview [[mdspan.layout.right.overview]](mdspan.layout.right.overview)

[1](#right.overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22238)

layout_right provides a layout mapping
where the rightmost extent is stride 1, and
strides increase right-to-left as the product of extents[.](#right.overview-1.sentence-1)

namespace std {template<class Extents>class layout_right::mapping {public:using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_right; // [[mdspan.layout.right.cons]](#right.cons "23.7.3.4.6.2 Constructors"), constructorsconstexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const mapping<OtherExtents>&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_left::mapping<OtherExtents>&) noexcept; template<class LayoutRightPaddedMapping>constexpr explicit(!is_convertible_v<typename LayoutRightPaddedMapping::extents_type,
 extents_type>) mapping(const LayoutRightPaddedMapping&) noexcept; template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.right.obs]](#right.obs "23.7.3.4.6.3 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept { return true; }static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }static constexpr bool is_exhaustive() noexcept { return true; }static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; template<class OtherExtents>friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; private: extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_­mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}

[2](#right.overview-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22312)

If Extents is not a specialization of extents,
then the program is ill-formed[.](#right.overview-2.sentence-1)

[3](#right.overview-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22316)

layout_right​::​mapping<E> is a trivially copyable type
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#right.overview-3.sentence-1)

[4](#right.overview-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22320)

*Mandates*: If Extents​::​rank_dynamic() == 0 is true,
then the size of the multidimensional index space Extents() is representable as a value of type typename Extents​::​index_type[.](#right.overview-4.sentence-1)

#### [23.7.3.4.6.2](#right.cons) Constructors [[mdspan.layout.right.cons]](mdspan.layout.right.cons)

[ð](#lib:layout_right::mapping,constructor)

`constexpr mapping(const extents_type& e) noexcept;
`

[1](#right.cons-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22334)

*Preconditions*: The size of the multidimensional index space e is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#right.cons-1.sentence-1)

[2](#right.cons-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22339)

*Effects*: Direct-non-list-initializes *extents_* with e[.](#right.cons-2.sentence-1)

[ð](#lib:layout_right::mapping,constructor_)

`template<class OtherExtents>
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
    mapping(const mapping<OtherExtents>& other) noexcept;
`

[3](#right.cons-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22352)

*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#right.cons-3.sentence-1)

[4](#right.cons-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22356)

*Preconditions*: other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#right.cons-4.sentence-1)

[5](#right.cons-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22361)

*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#right.cons-5.sentence-1)

[ð](#lib:layout_right::mapping,constructor__)

`template<class OtherExtents>
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
    mapping(const layout_left::mapping<OtherExtents>& other) noexcept;
`

[6](#right.cons-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22374)

*Constraints*: 

- [(6.1)](#right.cons-6.1)

extents_type​::​rank() <= 1 is true, and

- [(6.2)](#right.cons-6.2)

is_constructible_v<extents_type, OtherExtents> is true[.](#right.cons-6.sentence-1)

[7](#right.cons-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22383)

*Preconditions*: other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#right.cons-7.sentence-1)

[8](#right.cons-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22388)

*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#right.cons-8.sentence-1)

[ð](#lib:layout_right::mapping,constructor___)

`template<class LayoutRightPaddedMapping>
  constexpr explicit(!is_convertible_v<typename LayoutRightPaddedMapping::extents_type,
                                       extents_type>)
    mapping(const LayoutRightPaddedMapping&) noexcept;
`

[9](#right.cons-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22402)

*Constraints*: 

- [(9.1)](#right.cons-9.1)

  *is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#right.cons-9.1.sentence-1)

- [(9.2)](#right.cons-9.2)

  is_constructible_v<extents_type, typename LayoutRightPaddedMapping​::​extents_-  
type> is true[.](#right.cons-9.2.sentence-1)

[10](#right.cons-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22413)

*Mandates*: If

- [(10.1)](#right.cons-10.1)

Extents​::​rank() is greater than one,

- [(10.2)](#right.cons-10.2)

Extents​::​static_extent(Extents​::​rank() - 1) does not equal dynamic_extent, and

- [(10.3)](#right.cons-10.3)

LayoutRightPaddedMapping​::​*static-padding-stride* does not equal dynamic_extent,

then Extents​::​static_extent(Extents​::​rank() - 1) equalsLayoutRightPaddedMapping​::​*static-padding-stride*[.](#right.cons-10.sentence-1)

[11](#right.cons-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22429)

*Preconditions*: 

- [(11.1)](#right.cons-11.1)

  If extents_type​::​rank() > 1 is true,
then other.stride(extents_type​::​rank() - 2)  
equalsother.extents().extent(extents_type​::​rank() - 1)[.](#right.cons-11.1.sentence-1)

- [(11.2)](#right.cons-11.2)

  other.required_span_size() is representable as
a value of type index_type[.](#right.cons-11.2.sentence-1)

[12](#right.cons-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22441)

*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#right.cons-12.sentence-1)

[ð](#lib:layout_right::mapping,constructor____)

`template<class OtherExtents>
 constexpr explicit(extents_type::rank() > 0)
    mapping(const layout_stride::mapping<OtherExtents>& other) noexcept;
`

[13](#right.cons-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22454)

*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#right.cons-13.sentence-1)

[14](#right.cons-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22458)

*Preconditions*: 

- [(14.1)](#right.cons-14.1)

  If extents_type​::​rank() > 0 is true,
then for all r in the range [0, extents_type​::​rank()),other.stride(r) equalsother.extents().*rev-prod-of-extents*(r)[.](#right.cons-14.1.sentence-1)

- [(14.2)](#right.cons-14.2)

  other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#right.cons-14.2.sentence-1)

[15](#right.cons-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22471)

*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#right.cons-15.sentence-1)

#### [23.7.3.4.6.3](#right.obs) Observers [[mdspan.layout.right.obs]](mdspan.layout.right.obs)

[ð](#lib:required_span_size,layout_right::mapping)

`constexpr index_type required_span_size() const noexcept;
`

[1](#right.obs-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22484)

*Returns*: extents().*fwd-prod-of-extents*(extents_type​::​rank())[.](#right.obs-1.sentence-1)

[ð](#lib:operator(),layout_right::mapping)

`template<class... Indices>
  constexpr index_type operator()(Indices... i) const noexcept;
`

[2](#right.obs-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22496)

*Constraints*: 

- [(2.1)](#right.obs-2.1)

sizeof...(Indices) == extents_type​::​rank() is true,

- [(2.2)](#right.obs-2.2)

(is_convertible_v<Indices, index_type> && ...) is true, and

- [(2.3)](#right.obs-2.3)

(is_nothrow_constructible_v<index_type, Indices> && ...) istrue[.](#right.obs-2.sentence-1)

[3](#right.obs-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22508)

*Preconditions*: extents_type​::​*index-cast*(i) is
a multidimensional index in *extents_* ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#right.obs-3.sentence-1)

[4](#right.obs-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22513)

*Effects*: Let P be a parameter pack such thatis_same_v<index_sequence_for<Indices...>, index_sequence<P...>> is true[.](#right.obs-4.sentence-1)

Equivalent to:return ((static_cast<index_type>(i) * stride(P)) + ... + 0);

[ð](#lib:stride,layout_right::mapping)

`constexpr index_type stride(rank_type i) const noexcept;
`

[5](#right.obs-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22531)

*Constraints*: extents_type​::​rank() > 0 is true[.](#right.obs-5.sentence-1)

[6](#right.obs-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22535)

*Preconditions*: i < extents_type​::​rank() is true[.](#right.obs-6.sentence-1)

[7](#right.obs-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22539)

*Returns*: extents().*rev-prod-of-extents*(i)[.](#right.obs-7.sentence-1)

[ð](#lib:operator==,layout_right::mapping)

`template<class OtherExtents>
  friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
`

[8](#right.obs-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22551)

*Constraints*: extents_type​::​rank() == OtherExtents​::​rank() is true[.](#right.obs-8.sentence-1)

[9](#right.obs-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22555)

*Effects*: Equivalent to: return x.extents() == y.extents();

#### [23.7.3.4.7](#stride) Class template layout_stride​::​mapping [[mdspan.layout.stride]](mdspan.layout.stride)

#### [23.7.3.4.7.1](#stride.overview) Overview [[mdspan.layout.stride.overview]](mdspan.layout.stride.overview)

[1](#stride.overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22564)

layout_stride provides a layout mapping
where the strides are user-defined[.](#stride.overview-1.sentence-1)

namespace std {template<class Extents>class layout_stride::mapping {public:using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_stride; private:static constexpr rank_type *rank_* = extents_type::rank(); // *exposition only*public:// [[mdspan.layout.stride.cons]](#stride.cons "23.7.3.4.7.3 Constructors"), constructorsconstexpr mapping() noexcept; constexpr mapping(const mapping&) noexcept = default; template<class OtherIndexType>constexpr mapping(const extents_type&, span<OtherIndexType, *rank_*>) noexcept; template<class OtherIndexType>constexpr mapping(const extents_type&, const array<OtherIndexType, *rank_*>&) noexcept; template<class StridedLayoutMapping>constexpr explicit(*see below*) mapping(const StridedLayoutMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.stride.obs]](#stride.obs "23.7.3.4.7.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr array<index_type, *rank_*> strides() const noexcept { return *strides_*; }constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept { return false; }static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type i) const noexcept { return *strides_*[i]; }template<class OtherMapping>friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept; private: extents_type *extents_*{}; // *exposition only* array<index_type, *rank_*> *strides_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_­mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}

[2](#stride.overview-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22636)

If Extents is not a specialization of extents,
then the program is ill-formed[.](#stride.overview-2.sentence-1)

[3](#stride.overview-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22640)

layout_stride​::​mapping<E> is a trivially copyable type
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#stride.overview-3.sentence-1)

[4](#stride.overview-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22644)

*Mandates*: If Extents​::​rank_dynamic() == 0 is true,
then the size of the multidimensional index space Extents() is representable as a value of type typename Extents​::​index_type[.](#stride.overview-4.sentence-1)

#### [23.7.3.4.7.2](#stride.expo) Exposition-only helpers [[mdspan.layout.stride.expo]](mdspan.layout.stride.expo)

[1](#stride.expo-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22652)

Let *REQUIRED-SPAN-SIZE*(e, strides) be:

- [(1.1)](#stride.expo-1.1)

1, if e.rank() == 0 is true,

- [(1.2)](#stride.expo-1.2)

otherwise 0, if the size of the multidimensional index space e is 0,

- [(1.3)](#stride.expo-1.3)

otherwise 1 plus the sum of products of(e.extent(r) - 1) andextents_type::*index-cast*(strides[r]) for all r in the range [0, e.rank())[.](#stride.expo-1.sentence-1)

[2](#stride.expo-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22668)

Let *OFFSET*(m) be:

- [(2.1)](#stride.expo-2.1)

m(), if e.rank() == 0 is true,

- [(2.2)](#stride.expo-2.2)

otherwise 0, if the size of the multidimensional index space e is 0,

- [(2.3)](#stride.expo-2.3)

otherwise m(z...) for a pack of integers z that is a multidimensional index in m.extents() and
each element of z equals 0[.](#stride.expo-2.sentence-1)

[3](#stride.expo-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22681)

Let *is-extents* be the exposition-only variable template
defined as follows:template<class T>constexpr bool *is-extents* = false; // *exposition only*template<class IndexType, size_t... Args>constexpr bool *is-extents*<extents<IndexType, Args...>> = true; // *exposition only*

[4](#stride.expo-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22691)

Let [*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]") be the exposition-only concept
defined as follows:template<class M>concept [*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]") = requires { // *exposition only*requires *is-extents*<typename M::extents_type>; { M::is_always_strided() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<bool>; { M::is_always_exhaustive() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<bool>; { M::is_always_unique() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<bool>;
 bool_constant<M::is_always_strided()>::value;
 bool_constant<M::is_always_exhaustive()>::value;
 bool_constant<M::is_always_unique()>::value;};

[*Note [1](#stride.expo-note-1)*:

This concept checks that the functionsM​::​is_always_strided(),M​::​is_always_exhaustive(), andM​::​is_always_unique() exist,
are constant expressions, and
have a return type of bool[.](#stride.expo-4.sentence-1)

â *end note*]

#### [23.7.3.4.7.3](#stride.cons) Constructors [[mdspan.layout.stride.cons]](mdspan.layout.stride.cons)

[ð](#lib:layout_stride::mapping,constructor)

`constexpr mapping() noexcept;
`

[1](#stride.cons-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22723)

*Preconditions*: layout_right​::​mapping<extents_type>().required_span_size() is representable as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#stride.cons-1.sentence-1)

[2](#stride.cons-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22728)

*Effects*: Direct-non-list-initializes *extents_* with extents_type(), and
for all d in the range [0, *rank_*),
direct-non-list-initializes *strides_*[d] withlayout_right​::​mapping<extents_type>().stride(d)[.](#stride.cons-2.sentence-1)

[ð](#lib:layout_stride::mapping,constructor_)

`template<class OtherIndexType>
  constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
template<class OtherIndexType>
  constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
`

[3](#stride.cons-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22745)

*Constraints*: 

- [(3.1)](#stride.cons-3.1)

is_convertible_v<const OtherIndexType&, index_type> is true, and

- [(3.2)](#stride.cons-3.2)

is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#stride.cons-3.sentence-1)

[4](#stride.cons-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22754)

*Preconditions*: 

- [(4.1)](#stride.cons-4.1)

  The result of converting s[i] to index_type is greater than 0 for all i in the range [0, *rank_*)[.](#stride.cons-4.1.sentence-1)

- [(4.2)](#stride.cons-4.2)

  *REQUIRED-SPAN-SIZE*(e, s) is representable
as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#stride.cons-4.2.sentence-1)

- [(4.3)](#stride.cons-4.3)

  If *rank_* is greater than 0,
then there exists a permutation P of the integers
in the range [0, *rank_*),
such that s[pi] >= s[piâ1] * e.extent(piâ1) is true for all i in the range [1, *rank_*),
where pi is the ith element of P[.](#stride.cons-4.3.sentence-1)
  [*Note [1](#stride.cons-note-1)*:
  For layout_stride,
this condition is necessary and sufficient
for is_unique() to be true[.](#stride.cons-4.3.sentence-2)
 â *end note*]

[5](#stride.cons-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22778)

*Effects*: Direct-non-list-initializes *extents_* with e, and
for all d in the range [0, *rank_*),
direct-non-list-initializes strides_[d] with as_const(s[d])[.](#stride.cons-5.sentence-1)

[ð](#lib:layout_stride::mapping,constructor__)

`template<class StridedLayoutMapping>
  constexpr explicit(see below)
    mapping(const StridedLayoutMapping& other) noexcept;
`

[6](#stride.cons-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22793)

*Constraints*: 

- [(6.1)](#stride.cons-6.1)

  [*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]")<StridedLayoutMapping> is satisfied[.](#stride.cons-6.1.sentence-1)

- [(6.2)](#stride.cons-6.2)

  is_constructible_v<extents_type, typename StridedLayoutMapping​::​extents_type> is  
  true[.](#stride.cons-6.2.sentence-2)

- [(6.3)](#stride.cons-6.3)

  StridedLayoutMapping​::​is_always_unique() is true[.](#stride.cons-6.3.sentence-1)

- [(6.4)](#stride.cons-6.4)

  StridedLayoutMapping​::​is_always_strided() is true[.](#stride.cons-6.4.sentence-1)

[7](#stride.cons-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22806)

*Preconditions*: 

- [(7.1)](#stride.cons-7.1)

StridedLayoutMapping meets the layout mapping requirements ([[mdspan.layout.reqmts]](#reqmts "23.7.3.4.2 Requirements")),

- [(7.2)](#stride.cons-7.2)

other.stride(r) > 0 is true for every rank index r of extents(),

- [(7.3)](#stride.cons-7.3)

other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")), and

- [(7.4)](#stride.cons-7.4)

*OFFSET*(other) == 0 is true[.](#stride.cons-7.sentence-1)

[8](#stride.cons-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22821)

*Effects*: Direct-non-list-initializes *extents_* with other.extents(), and
for all d in the range [0, *rank_*),
direct-non-list-initializes *strides_*[d] with other.stride(d)[.](#stride.cons-8.sentence-1)

[9](#stride.cons-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22828)

Remarks: The expression inside explicit is equivalent to:!(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&(*is-mapping-of*<layout_left, StridedLayoutMapping> ||*is-mapping-of*<layout_right, StridedLayoutMapping> ||*is-layout-left-padded-mapping-of*<StridedLayoutMapping> ||*is-layout-right-padded-mapping-of*<StridedLayoutMapping> ||*is-mapping-of*<layout_stride, StridedLayoutMapping>))

#### [23.7.3.4.7.4](#stride.obs) Observers [[mdspan.layout.stride.obs]](mdspan.layout.stride.obs)

[ð](#lib:required_span_size,layout_stride::mapping)

`constexpr index_type required_span_size() const noexcept;
`

[1](#stride.obs-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22848)

*Returns*: *REQUIRED-SPAN-SIZE*(extents(), *strides_*)[.](#stride.obs-1.sentence-1)

[ð](#lib:operator(),layout_stride::mapping)

`template<class... Indices>
  constexpr index_type operator()(Indices... i) const noexcept;
`

[2](#stride.obs-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22860)

*Constraints*: 

- [(2.1)](#stride.obs-2.1)

sizeof...(Indices) == *rank_* is true,

- [(2.2)](#stride.obs-2.2)

(is_convertible_v<Indices, index_type> && ...) is true, and

- [(2.3)](#stride.obs-2.3)

(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#stride.obs-2.sentence-1)

[3](#stride.obs-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22871)

*Preconditions*: extents_type​::​*index-cast*(i) is
a multidimensional index in *extents_* ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#stride.obs-3.sentence-1)

[4](#stride.obs-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22876)

*Effects*: Let P be a parameter pack such thatis_same_v<index_sequence_for<Indices...>, index_sequence<P...>> is true[.](#stride.obs-4.sentence-1)

Equivalent to:return ((static_cast<index_type>(i) * stride(P)) + ... + 0);

[ð](#lib:is_exhaustive,layout_stride::mapping)

`constexpr bool is_exhaustive() const noexcept;
`

[5](#stride.obs-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22895)

*Returns*: 

- [(5.1)](#stride.obs-5.1)

  true if *rank_* is 0[.](#stride.obs-5.1.sentence-1)

- [(5.2)](#stride.obs-5.2)

  Otherwise, true if there is
a permutation P of the integers in the range [0, *rank_*) such that stride(p0) equals 1, andstride(pi) equals stride(piâ1) * extents().extent(piâ1) for i in the range [1, *rank_*),
where pi is the ith element of P[.](#stride.obs-5.2.sentence-1)

- [(5.3)](#stride.obs-5.3)

  Otherwise, false[.](#stride.obs-5.3.sentence-1)

[ð](#lib:operator==,layout_stride::mapping)

`template<class OtherMapping>
  friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept;
`

[6](#stride.obs-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22919)

*Constraints*: 

- [(6.1)](#stride.obs-6.1)

  [*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]")<OtherMapping> is satisfied[.](#stride.obs-6.1.sentence-1)

- [(6.2)](#stride.obs-6.2)

  *rank_* == OtherMapping​::​extents_type​::​rank() is true[.](#stride.obs-6.2.sentence-1)

- [(6.3)](#stride.obs-6.3)

  OtherMapping​::​is_always_strided() is true[.](#stride.obs-6.3.sentence-1)

[7](#stride.obs-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22930)

*Preconditions*: OtherMapping meets the layout mapping requirements ([[mdspan.layout.policy.reqmts]](#policy.reqmts "23.7.3.4.3 Layout mapping policy requirements"))[.](#stride.obs-7.sentence-1)

[8](#stride.obs-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22934)

*Returns*: true if x.extents() == y.extents() is true,*OFFSET*(y) == 0 is true, and
each of x.stride(r) == y.stride(r) is true for r in the range [0, x.extents().rank())[.](#stride.obs-8.sentence-1)

Otherwise, false[.](#stride.obs-8.sentence-2)

#### [23.7.3.4.8](#leftpad) Class template layout_left_padded​::​mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad)

#### [23.7.3.4.8.1](#leftpad.overview) Overview [[mdspan.layout.leftpad.overview]](mdspan.layout.leftpad.overview)

[1](#leftpad.overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22947)

layout_left_padded provides a layout mapping
that behaves like layout_left​::​mapping,
except that the padding stride stride(1) can be greater than or equal to extent(0)[.](#leftpad.overview-1.sentence-1)

namespace std {template<size_t PaddingValue>template<class Extents>class layout_left_padded<PaddingValue>::mapping {public:static constexpr size_t padding_value = PaddingValue; using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_left_padded<PaddingValue>; private:static constexpr size_t *rank_* = extents_type::rank(); // *exposition only*static constexpr size_t *first-static-extent* = // *exposition only* extents_type::static_extent(0); // [[mdspan.layout.leftpad.expo]](#leftpad.expo "23.7.3.4.8.2 Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.leftpad.cons]](#leftpad.cons "23.7.3.4.8.3 Constructors"), constructorsconstexpr mapping() noexcept : mapping(extents_type{}) {}constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&); template<class OtherIndexType>constexpr mapping(const extents_type&, OtherIndexType); template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_left::mapping<OtherExtents>&); template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&); template<class LayoutLeftPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutLeftPaddedMapping&); template<class LayoutRightPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutRightPaddedMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.leftpad.obs]](#leftpad.obs "23.7.3.4.8.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr array<index_type, rank_> strides() const noexcept; constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept; static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; template<class LayoutLeftPaddedMapping>friend constexpr bool operator==(const mapping&, const LayoutLeftPaddedMapping&) noexcept; private:// [[mdspan.layout.leftpad.expo]](#leftpad.expo "23.7.3.4.8.2 Exposition-only members"), exposition-only members index_type *stride-1* = *static-padding-stride*; // *exposition only* extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_­mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}

[2](#leftpad.overview-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23035)

If Extents is not a specialization of extents,
then the program is ill-formed[.](#leftpad.overview-2.sentence-1)

[3](#leftpad.overview-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23039)

layout_left_padded​::​mapping<E> is a trivially copyable type
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#leftpad.overview-3.sentence-1)

[4](#leftpad.overview-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23043)

Throughout [[mdspan.layout.leftpad]](#leftpad "23.7.3.4.8 Class template layout_­left_­padded​::​mapping"),
let P_rank be the following
size *rank_* parameter pack of size_t values:

- [(4.1)](#leftpad.overview-4.1)

the empty parameter pack, if *rank_* equals zero;

- [(4.2)](#leftpad.overview-4.2)

otherwise, 0zu, if *rank_* equals one;

- [(4.3)](#leftpad.overview-4.3)

otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#leftpad.overview-4.sentence-1)

[5](#leftpad.overview-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23056)

*Mandates*: 

- [(5.1)](#leftpad.overview-5.1)

  If rank_dynamic() == 0 is true,
then the size of the multidimensional index space Extents() is representable as a value of type index_type[.](#leftpad.overview-5.1.sentence-1)

- [(5.2)](#leftpad.overview-5.2)

  padding_value is representable as a value of type index_type[.](#leftpad.overview-5.2.sentence-1)

- [(5.3)](#leftpad.overview-5.3)

  If
  * [(5.3.1)](#leftpad.overview-5.3.1)

*rank_* is greater than one,

  * [(5.3.2)](#leftpad.overview-5.3.2)

padding_value does not equal dynamic_extent, and

  * [(5.3.3)](#leftpad.overview-5.3.3)

*first-static-extent* does not equal dynamic_extent,

then *LEAST-MULTIPLE-AT-LEAST*(padding_value, *first-static-extent*) is representable as a value of type size_t, and
is representable as a value of type index_type[.](#leftpad.overview-5.3.sentence-1)

- [(5.4)](#leftpad.overview-5.4)

  If
  * [(5.4.1)](#leftpad.overview-5.4.1)

*rank_* is greater than one,

  * [(5.4.2)](#leftpad.overview-5.4.2)

padding_value does not equal dynamic_extent, and

  * [(5.4.3)](#leftpad.overview-5.4.3)

extents_type​::​static_extent(k) does not equal dynamic_extent for all k in the range [0, extents_type​::​rank()),

then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.static_extent(0)) and
all values ext.static_extent(k) with k in the range of [1, *rank_*)
is representable as a value of type size_t, and
is representable as a value of type index_type[.](#leftpad.overview-5.4.sentence-1)

#### [23.7.3.4.8.2](#leftpad.expo) Exposition-only members [[mdspan.layout.leftpad.expo]](mdspan.layout.leftpad.expo)

[ð](#leftpad.expo-itemdecl:1)

`static constexpr size_t static-padding-stride = see below;
`

[1](#leftpad.expo-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23104)

The value is

- [(1.1)](#leftpad.expo-1.1)

0, if *rank_* equals zero or one;

- [(1.2)](#leftpad.expo-1.2)

otherwise, dynamic_extent,
if padding_value or *first-static-extent* equalsdynamic_extent;

- [(1.3)](#leftpad.expo-1.3)

otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *first-static-extent*)[.](#leftpad.expo-1.sentence-1)

[ð](#leftpad.expo-itemdecl:2)

`index_type stride-1 = static-padding-stride;
`

[2](#leftpad.expo-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23124)

*Recommended practice*: Implementations should not store this value
if *static-padding-stride* is not dynamic_extent[.](#leftpad.expo-2.sentence-1)

[*Note [1](#leftpad.expo-note-1)*:

Using extents<index_type, *static-padding-stride*> instead ofindex_type as the type of *stride-1* would achieve this[.](#leftpad.expo-2.sentence-2)

â *end note*]

#### [23.7.3.4.8.3](#leftpad.cons) Constructors [[mdspan.layout.leftpad.cons]](mdspan.layout.leftpad.cons)

[ð](#lib:layout_left_padded::mapping,constructor)

`constexpr mapping(const extents_type& ext);
`

[1](#leftpad.cons-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23142)

*Preconditions*: 

- [(1.1)](#leftpad.cons-1.1)

  The size of the multidimensional index space ext is representable as
a value of type index_type[.](#leftpad.cons-1.1.sentence-1)

- [(1.2)](#leftpad.cons-1.2)

  If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0)) is representable as a value of type *index_type*[.](#leftpad.cons-1.2.sentence-1)

- [(1.3)](#leftpad.cons-1.3)

  If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0)) and
all values ext.extent(k) with k in the range of [1, *rank_*)
is representable as a value of type index_type[.](#leftpad.cons-1.3.sentence-1)

[2](#leftpad.cons-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23163)

*Effects*: 

- [(2.1)](#leftpad.cons-2.1)

Direct-non-list-initializes *extents_* with ext; and

- [(2.2)](#leftpad.cons-2.2)

if *rank_* is greater than one,
direct-non-list-initializes *stride-1*
  * [(2.2.1)](#leftpad.cons-2.2.1)

with ext.extent(0) if padding_value is dynamic_extent,

  * [(2.2.2)](#leftpad.cons-2.2.2)

otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0))[.](#leftpad.cons-2.sentence-1)

[ð](#lib:layout_left_padded::mapping,constructor_)

`template<class OtherIndexType>
constexpr mapping(const extents_type& ext, OtherIndexType pad);
`

[3](#leftpad.cons-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23188)

*Constraints*: 

- [(3.1)](#leftpad.cons-3.1)

  is_convertible_v<OtherIndexType, index_type> is true[.](#leftpad.cons-3.1.sentence-1)

- [(3.2)](#leftpad.cons-3.2)

  is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#leftpad.cons-3.2.sentence-1)

[4](#leftpad.cons-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23197)

*Preconditions*: 

- [(4.1)](#leftpad.cons-4.1)

  pad is representable as a value of type index_type[.](#leftpad.cons-4.1.sentence-1)

- [(4.2)](#leftpad.cons-4.2)

  extents_type​::​index-cast(pad) is greater than zero[.](#leftpad.cons-4.2.sentence-1)

- [(4.3)](#leftpad.cons-4.3)

  If *rank_* is greater than one,
then *LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0)) is representable as a value of type index_type.

- [(4.4)](#leftpad.cons-4.4)

  If *rank_* is greater than one,
then the product of*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0)) and
all values ext.extent(k) with k in the range of [1, *rank_*)
is representable as a value of type index_type[.](#leftpad.cons-4.4.sentence-1)

- [(4.5)](#leftpad.cons-4.5)

  If padding_value is not equal to dynamic_extent,padding_value equals extents_type​::​*index-cast*(pad)[.](#leftpad.cons-4.5.sentence-1)

[5](#leftpad.cons-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23220)

*Effects*: Direct-non-list-initializes *extents_* with ext, and
if *rank_* is greater than one,
direct-non-list-initializes *stride-1* with*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0))[.](#leftpad.cons-5.sentence-1)

[ð](#lib:layout_left_padded::mapping,constructor__)

`template<class OtherExtents>
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
    mapping(const layout_left::mapping<OtherExtents>& other);
`

[6](#leftpad.cons-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23236)

*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#leftpad.cons-6.sentence-1)

[7](#leftpad.cons-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23240)

*Mandates*: If OtherExtents​::​rank() is greater than 1, then(*static-padding-stride* == dynamic_extent) ||(OtherExtents::static_extent(0) == dynamic_extent) ||(*static-padding-stride* == OtherExtents::static_extent(0)) is true[.](#leftpad.cons-7.sentence-1)

[8](#leftpad.cons-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23250)

*Preconditions*: 

- [(8.1)](#leftpad.cons-8.1)

If extents_type​::​rank() > 1 is true andpadding_value == dynamic_extent is false,
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
 extents_type::*index-cast*(other.extents().extent(0))) and

- [(8.2)](#leftpad.cons-8.2)

other.required_span_size() is representable as
a value of type index_type[.](#leftpad.cons-8.sentence-1)

[9](#leftpad.cons-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23267)

*Effects*: Equivalent to mapping(other.extents())[.](#leftpad.cons-9.sentence-1)

[ð](#lib:layout_left_padded::mapping,constructor___)

`template<class OtherExtents>
  constexpr explicit(rank_ > 0)
    mapping(const layout_stride::mapping<OtherExtents>& other);
`

[10](#leftpad.cons-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23280)

*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#leftpad.cons-10.sentence-1)

[11](#leftpad.cons-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23284)

*Preconditions*: 

- [(11.1)](#leftpad.cons-11.1)

  If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
 extents_type::*index-cast*(other.extents().extent(0)))

- [(11.2)](#leftpad.cons-11.2)

  If *rank_* is greater than 0,
then other.stride(0) equals 1[.](#leftpad.cons-11.2.sentence-1)

- [(11.3)](#leftpad.cons-11.3)

  If *rank_* is greater than 2,
then for all r in the range [2, *rank_*),other.stride(r) equals(other.extents().*fwd-prod-of-extents*(r) / other.extents().extent(0)) * other.stride(1)

- [(11.4)](#leftpad.cons-11.4)

  other.required_span_size() is representable as
a value of type *index_type*[.](#leftpad.cons-11.4.sentence-1)

[12](#leftpad.cons-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23310)

*Effects*: 

- [(12.1)](#leftpad.cons-12.1)

Direct-non-list-initializes *extents_* with other.extents() and

- [(12.2)](#leftpad.cons-12.2)

if *rank_* is greater than one,
direct-non-list-initializes *stride-1* withother.stride(1)[.](#leftpad.cons-12.sentence-1)

[ð](#lib:layout_left_padded::mapping,constructor____)

`template<class LayoutLeftPaddedMapping>
  constexpr explicit(see below)
    mapping(const LayoutLeftPaddedMapping& other);
`

[13](#leftpad.cons-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23330)

*Constraints*: 

- [(13.1)](#leftpad.cons-13.1)

  *is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#leftpad.cons-13.1.sentence-1)

- [(13.2)](#leftpad.cons-13.2)

  is_constructible_v<extents_type, typename LayoutLeftPaddedMapping​::​extents_type>  
is true[.](#leftpad.cons-13.2.sentence-1)

[14](#leftpad.cons-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23341)

*Mandates*: If *rank_* is greater than 1,
thenpadding_value == dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutLeftPaddedMapping::padding_value is true[.](#leftpad.cons-14.sentence-1)

[15](#leftpad.cons-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23352)

*Preconditions*: 

- [(15.1)](#leftpad.cons-15.1)

If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
 extents_type::*index-cast*(other.extent(0)))

- [(15.2)](#leftpad.cons-15.2)

other.required_span_size() is representable as
a value of type index_type[.](#leftpad.cons-15.sentence-1)

[16](#leftpad.cons-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23368)

*Effects*: 

- [(16.1)](#leftpad.cons-16.1)

Direct-non-list-initializes *extents_* with other.extents() and

- [(16.2)](#leftpad.cons-16.2)

if *rank_* is greater than one,
direct-non-list-initializes *stride-1* with other.stride(1)[.](#leftpad.cons-16.sentence-1)

[17](#leftpad.cons-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23378)

*Remarks*: The expression inside explicit is equivalent to:rank_> 1 &&(padding_value != dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent)

[ð](#lib:layout_left_padded::mapping,constructor_____)

`template<class LayoutRightPaddedMapping>
  constexpr explicit(see below)
    mapping(const LayoutRightPaddedMapping& other) noexcept;
`

[18](#leftpad.cons-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23396)

*Constraints*: 

- [(18.1)](#leftpad.cons-18.1)

  *is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true or  
*is-mapping-of*<layout_right, LayoutRightPaddedMapping> is true[.](#leftpad.cons-18.1.sentence-1)

- [(18.2)](#leftpad.cons-18.2)

  *rank_* equals zero or one[.](#leftpad.cons-18.2.sentence-1)

- [(18.3)](#leftpad.cons-18.3)

  is_constructible_v<extents_type, typename LayoutRightPaddedMapping​::​extents_-  
type> is true[.](#leftpad.cons-18.3.sentence-1)

[19](#leftpad.cons-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23411)

*Preconditions*: other.required_span_size() is representable as
a value of type index_type[.](#leftpad.cons-19.sentence-1)

[20](#leftpad.cons-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23416)

*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#leftpad.cons-20.sentence-1)

[21](#leftpad.cons-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23420)

*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<typename LayoutRightPaddedMapping::extents_type, extents_type>

[*Note [1](#leftpad.cons-note-1)*:

Neither the input mapping nor the mapping to be constructed
uses the padding stride in the rank-0 or rank-1 case,
so the padding stride does not affect
either the constraints or the preconditions[.](#leftpad.cons-21.sentence-2)

â *end note*]

#### [23.7.3.4.8.4](#leftpad.obs) Observers [[mdspan.layout.leftpad.obs]](mdspan.layout.leftpad.obs)

[ð](#leftpad.obs-itemdecl:1)

`constexpr array<index_type, rank_> strides() const noexcept;
`

[1](#leftpad.obs-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23442)

*Returns*: array<index_type, *rank_*>({stride(P_rank)...})[.](#leftpad.obs-1.sentence-1)

[ð](#leftpad.obs-itemdecl:2)

`constexpr index_type required_span_size() const noexcept;
`

[2](#leftpad.obs-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23452)

*Returns*: 

- [(2.1)](#leftpad.obs-2.1)

0 if the multidimensional index space *extents_* is empty,

- [(2.2)](#leftpad.obs-2.2)

otherwise, *this(((*extents_*(P_rank) - index_type(1))...)) + 1[.](#leftpad.obs-2.sentence-1)

[ð](#leftpad.obs-itemdecl:3)

`template<class... Indices>
constexpr size_t operator()(Indices... idxs) const noexcept;
`

[3](#leftpad.obs-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23468)

*Constraints*: 

- [(3.1)](#leftpad.obs-3.1)

  sizeof...(Indices) == *rank_* is true[.](#leftpad.obs-3.1.sentence-1)

- [(3.2)](#leftpad.obs-3.2)

  (is_convertible_v<Indices, index_type> && ...) is true[.](#leftpad.obs-3.2.sentence-1)

- [(3.3)](#leftpad.obs-3.3)

  (is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#leftpad.obs-3.3.sentence-1)

[4](#leftpad.obs-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23479)

*Preconditions*: extents_type​::​*index-cast*(idxs) is
a multidimensional index in extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#leftpad.obs-4.sentence-1)

[5](#leftpad.obs-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23484)

*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#leftpad.obs-5.sentence-1)

[ð](#leftpad.obs-itemdecl:4)

`static constexpr bool is_always_exhaustive() noexcept;
`

[6](#leftpad.obs-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23494)

*Returns*: 

- [(6.1)](#leftpad.obs-6.1)

If *rank_* equals zero or one, then true;

- [(6.2)](#leftpad.obs-6.2)

otherwise, if
neither *static-padding-stride* nor *first-static-extent* equal dynamic_extent,
then *static-padding-stride* == *first-static-extent*;

- [(6.3)](#leftpad.obs-6.3)

otherwise, false[.](#leftpad.obs-6.sentence-1)

[ð](#leftpad.obs-itemdecl:5)

`constexpr bool is_exhaustive() const noexcept;
`

[7](#leftpad.obs-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23514)

*Returns*: true if *rank_* equals zero or one;
otherwise, extents_.extent(0) == stride(1)[.](#leftpad.obs-7.sentence-1)

[ð](#leftpad.obs-itemdecl:6)

`constexpr index_type stride(rank_type r) const noexcept;
`

[8](#leftpad.obs-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23525)

*Preconditions*: r is smaller than *rank_*[.](#leftpad.obs-8.sentence-1)

[9](#leftpad.obs-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23529)

*Returns*: 

- [(9.1)](#leftpad.obs-9.1)

If r equals zero: 1;

- [(9.2)](#leftpad.obs-9.2)

otherwise, if r equals one: *stride-1*;

- [(9.3)](#leftpad.obs-9.3)

otherwise, the product of *stride-1* and
all values extents_.extent(k) with k in the range [1, r)[.](#leftpad.obs-9.sentence-1)

[ð](#leftpad.obs-itemdecl:7)

`template<class LayoutLeftPaddedMapping>
  friend constexpr bool operator==(const mapping& x, const LayoutLeftPaddedMapping& y) noexcept;
`

[10](#leftpad.obs-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23548)

*Constraints*: 

- [(10.1)](#leftpad.obs-10.1)

  *is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#leftpad.obs-10.1.sentence-1)

- [(10.2)](#leftpad.obs-10.2)

  LayoutLeftPaddedMapping​::​extents_type​::​rank() == rank_ is true[.](#leftpad.obs-10.2.sentence-1)

[11](#leftpad.obs-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23558)

*Returns*: true if x.extents() == y.extents() is true and*rank_* < 2 || x.stride(1) == y.  
stride(1) is true[.](#leftpad.obs-11.sentence-1)

Otherwise, false[.](#leftpad.obs-11.sentence-2)

#### [23.7.3.4.9](#rightpad) Class template layout_right_padded​::​mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad)

#### [23.7.3.4.9.1](#rightpad.overview) Overview [[mdspan.layout.rightpad.overview]](mdspan.layout.rightpad.overview)

[1](#rightpad.overview-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23569)

layout_right_padded provides a layout mapping
that behaves like layout_right​::​mapping,
except that the padding stride stride(extents_type​::​rank() - 2) can be greater than or equal toextents_type​::​extent(extents_type​::​rank() - 1)[.](#rightpad.overview-1.sentence-1)

namespace std {template<size_t PaddingValue>template<class Extents>class layout_right_padded<PaddingValue>::mapping {public:static constexpr size_t padding_value = PaddingValue; using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_right_padded<PaddingValue>; private:static constexpr size_t *rank_* = extents_type::rank(); // *exposition only*static constexpr size_t *last-static-extent* = // *exposition only* extents_type::static_extent(*rank_* - 1); // [[mdspan.layout.rightpad.expo]](#rightpad.expo "23.7.3.4.9.2 Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.rightpad.cons]](#rightpad.cons "23.7.3.4.9.3 Constructors"), constructorsconstexpr mapping() noexcept : mapping(extents_type{}) {}constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&); template<class OtherIndexType>constexpr mapping(const extents_type&, OtherIndexType); template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_right::mapping<OtherExtents>&); template<class OtherExtents>constexpr explicit(rank_ > 0) mapping(const layout_stride::mapping<OtherExtents>&); template<class LayoutRightPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutRightPaddedMapping&); template<class LayoutLeftPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutLeftPaddedMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.rightpad.obs]](#rightpad.obs "23.7.3.4.9.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return extents_; }constexpr array<index_type, rank_> strides() const noexcept; constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept; static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; template<class LayoutRightPaddedMapping>friend constexpr bool operator==(const mapping&, const LayoutRightPaddedMapping&) noexcept; private:// [[mdspan.layout.rightpad.expo]](#rightpad.expo "23.7.3.4.9.2 Exposition-only members"), exposition-only members index_type *stride-rm2* = *static-padding-stride*; // *exposition only* extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_­mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}

[2](#rightpad.overview-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23661)

If Extents is not a specialization of extents,
then the program is ill-formed[.](#rightpad.overview-2.sentence-1)

[3](#rightpad.overview-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23665)

layout_right_padded​::​mapping<E> is a trivially copyable type
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#rightpad.overview-3.sentence-1)

[4](#rightpad.overview-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23669)

Throughout [[mdspan.layout.rightpad]](#rightpad "23.7.3.4.9 Class template layout_­right_­padded​::​mapping"),
let P_rank be the following
size *rank_* parameter pack of size_t values:

- [(4.1)](#rightpad.overview-4.1)

the empty parameter pack, if *rank_* equals zero;

- [(4.2)](#rightpad.overview-4.2)

otherwise, 0zu, if *rank_* equals one;

- [(4.3)](#rightpad.overview-4.3)

otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#rightpad.overview-4.sentence-1)

[5](#rightpad.overview-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23682)

*Mandates*: 

- [(5.1)](#rightpad.overview-5.1)

  If rank_dynamic() == 0 is true,
then the size of the multidimensional index space Extents() is representable as a value of type index_type[.](#rightpad.overview-5.1.sentence-1)

- [(5.2)](#rightpad.overview-5.2)

  padding_value is representable as a value of type index_type[.](#rightpad.overview-5.2.sentence-1)

- [(5.3)](#rightpad.overview-5.3)

  If
  * [(5.3.1)](#rightpad.overview-5.3.1)

*rank_* is greater than one,

  * [(5.3.2)](#rightpad.overview-5.3.2)

padding_value does not equal dynamic_extent, and

  * [(5.3.3)](#rightpad.overview-5.3.3)

*last-static-extent* does not equal dynamic_extent,

then *LEAST-MULTIPLE-AT-LEAST*(padding_value, *last-static-extent*) is representable as a value of type size_t, and
is representable as a value of type index_type[.](#rightpad.overview-5.3.sentence-1)

- [(5.4)](#rightpad.overview-5.4)

  If
  * [(5.4.1)](#rightpad.overview-5.4.1)

*rank_* is greater than one,

  * [(5.4.2)](#rightpad.overview-5.4.2)

padding_value does not equal dynamic_extent, and

  * [(5.4.3)](#rightpad.overview-5.4.3)

extents_type​::​static_extent(k) does not equal dynamic_extent for all k in the range [0, *rank_*),

then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.static_extent(*rank_* - 1)) and
all values ext.static_extent(k) with k in the range of [0, *rank_* - 1)
is representable as a value of type size_t, and
is representable as a value of type index_type[.](#rightpad.overview-5.4.sentence-1)

#### [23.7.3.4.9.2](#rightpad.expo) Exposition-only members [[mdspan.layout.rightpad.expo]](mdspan.layout.rightpad.expo)

[ð](#rightpad.expo-itemdecl:1)

`static constexpr size_t static-padding-stride = see below;
`

[1](#rightpad.expo-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23730)

The value is

- [(1.1)](#rightpad.expo-1.1)

0, if *rank_* equals zero or one;

- [(1.2)](#rightpad.expo-1.2)

otherwise, dynamic_extent,
if padding_value or *last-static-extent* equalsdynamic_extent;

- [(1.3)](#rightpad.expo-1.3)

otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *last-static-extent*)[.](#rightpad.expo-1.sentence-1)

[ð](#rightpad.expo-itemdecl:2)

`index_type stride-rm2 = static-padding-stride;
`

[2](#rightpad.expo-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23750)

*Recommended practice*: Implementations should not store this value
if *static-padding-stride* is not dynamic_extent[.](#rightpad.expo-2.sentence-1)

[*Note [1](#rightpad.expo-note-1)*:

Using extents<index_type, *static-padding-stride*> instead of index_type as the type of *stride-rm2* would achieve this[.](#rightpad.expo-2.sentence-2)

â *end note*]

#### [23.7.3.4.9.3](#rightpad.cons) Constructors [[mdspan.layout.rightpad.cons]](mdspan.layout.rightpad.cons)

[ð](#lib:layout_right_padded::mapping,constructor)

`constexpr mapping(const extents_type& ext);
`

[1](#rightpad.cons-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23769)

*Preconditions*: 

- [(1.1)](#rightpad.cons-1.1)

  The size of the multidimensional index space ext is representable as a value of type index_type[.](#rightpad.cons-1.1.sentence-1)

- [(1.2)](#rightpad.cons-1.2)

  If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1)) is representable as a value of type *index_type*[.](#rightpad.cons-1.2.sentence-1)

- [(1.3)](#rightpad.cons-1.3)

  If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1)) and
all values ext.extent(k) with k in the range of [0, *rank_* - 1)
is representable as a value of type index_type[.](#rightpad.cons-1.3.sentence-1)

[2](#rightpad.cons-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23790)

*Effects*: 

- [(2.1)](#rightpad.cons-2.1)

Direct-non-list-initializes *extents_* with ext; and

- [(2.2)](#rightpad.cons-2.2)

if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2*
  * [(2.2.1)](#rightpad.cons-2.2.1)

with ext.extent(*rank_* - 1) if padding_value is dynamic_extent,

  * [(2.2.2)](#rightpad.cons-2.2.2)

otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1))[.](#rightpad.cons-2.sentence-1)

[ð](#lib:layout_right_padded::mapping,constructor_)

`template<class OtherIndexType>
constexpr mapping(const extents_type& ext, OtherIndexType pad);
`

[3](#rightpad.cons-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23816)

*Constraints*: 

- [(3.1)](#rightpad.cons-3.1)

  is_convertible_v<OtherIndexType, index_type> is true[.](#rightpad.cons-3.1.sentence-1)

- [(3.2)](#rightpad.cons-3.2)

  is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#rightpad.cons-3.2.sentence-1)

[4](#rightpad.cons-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23825)

*Preconditions*: 

- [(4.1)](#rightpad.cons-4.1)

  pad is representable as a value of type index_type[.](#rightpad.cons-4.1.sentence-1)

- [(4.2)](#rightpad.cons-4.2)

  extents_type​::​*index-cast*(pad) is greater than zero[.](#rightpad.cons-4.2.sentence-1)

- [(4.3)](#rightpad.cons-4.3)

  If *rank_* is greater than one,
then *LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1)) is representable as a value of type index_type[.](#rightpad.cons-4.3.sentence-1)

- [(4.4)](#rightpad.cons-4.4)

  If *rank_* is greater than one,
then the product of*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1)) and
all values ext.extent(k) with k in the range of [0, *rank_* - 1)
is representable as a value of type index_type[.](#rightpad.cons-4.4.sentence-1)

- [(4.5)](#rightpad.cons-4.5)

  If padding_value is not equal to dynamic_extent,padding_value equals extents_type​::​*index-cast*(pad)[.](#rightpad.cons-4.5.sentence-1)

[5](#rightpad.cons-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23848)

*Effects*: Direct-non-list-initializes *extents_* with ext, and
if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2* with*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1))[.](#rightpad.cons-5.sentence-1)

[ð](#lib:layout_right_padded::mapping,constructor__)

`template<class OtherExtents>
  constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
    mapping(const layout_right::mapping<OtherExtents>& other);
`

[6](#rightpad.cons-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23864)

*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#rightpad.cons-6.sentence-1)

[7](#rightpad.cons-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23868)

*Mandates*: If OtherExtents​::​rank() is greater than 1, then(*static-padding-stride* == dynamic_extent) ||(OtherExtents::static_extent(*rank_* - 1) == dynamic_extent) ||(*static-padding-stride* == OtherExtents::static_extent(*rank_* - 1)) is true[.](#rightpad.cons-7.sentence-1)

[8](#rightpad.cons-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23878)

*Preconditions*: 

- [(8.1)](#rightpad.cons-8.1)

If *rank_* > 1 is true andpadding_value == dynamic_extent is false, thenother.stride(  
*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
 extents_type::*index-cast*(other.extents().extent(rank_ - 1))) and

- [(8.2)](#rightpad.cons-8.2)

other.required_span_size() is representable as
a value of type index_type[.](#rightpad.cons-8.sentence-1)

[9](#rightpad.cons-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23895)

*Effects*: Equivalent to mapping(other.extents())[.](#rightpad.cons-9.sentence-1)

[ð](#lib:layout_right_padded::mapping,constructor___)

`template<class OtherExtents>
  constexpr explicit(rank_ > 0)
    mapping(const layout_stride::mapping<OtherExtents>& other);
`

[10](#rightpad.cons-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23908)

*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#rightpad.cons-10.sentence-1)

[11](#rightpad.cons-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23912)

*Preconditions*: 

- [(11.1)](#rightpad.cons-11.1)

  If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
then other.stride(*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
 extents_type::*index-cast*(other.extents().extent(*rank_* - 1)))

- [(11.2)](#rightpad.cons-11.2)

  If *rank_* is greater than 0,
then other.stride(*rank_* - 1) equals 1[.](#rightpad.cons-11.2.sentence-1)

- [(11.3)](#rightpad.cons-11.3)

  If *rank_* is greater than 2,
then for all r in the range [0, *rank_* - 2),other.stride(r) equals(other.extents().*rev-prod-of-extents*(r) / other.extents().extent(*rank_* - 1)) * other.stride(*rank_* - 2)

- [(11.4)](#rightpad.cons-11.4)

  other.required_span_size() is representable as
a value of type index_type[.](#rightpad.cons-11.4.sentence-1)

[12](#rightpad.cons-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23939)

*Effects*: 

- [(12.1)](#rightpad.cons-12.1)

Direct-non-list-initializes *extents_* with other.extents(); and

- [(12.2)](#rightpad.cons-12.2)

if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2* with other.stride(*rank_* - 2)[.](#rightpad.cons-12.sentence-1)

[ð](#lib:layout_right_padded::mapping,constructor____)

`template<class LayoutRightPaddedMapping>
  constexpr explicit(see below)
    mapping(const LayoutRightPaddedMapping& other);
`

[13](#rightpad.cons-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23959)

*Constraints*: 

- [(13.1)](#rightpad.cons-13.1)

  *is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#rightpad.cons-13.1.sentence-1)

- [(13.2)](#rightpad.cons-13.2)

  is_constructible_v<extents_type, typename LayoutRightPaddedMapping​::​extents_-  
type> is true[.](#rightpad.cons-13.2.sentence-1)

[14](#rightpad.cons-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23970)

*Mandates*: If *rank_* is greater than 1, thenpadding_value == dynamic_extent || LayoutRightPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutRightPaddedMapping::padding_value is true[.](#rightpad.cons-14.sentence-1)

[15](#rightpad.cons-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23980)

*Preconditions*: 

- [(15.1)](#rightpad.cons-15.1)

If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
then other.stride(*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
 extents_type::*index-cast*(other.extent(*rank_* - 1)))

- [(15.2)](#rightpad.cons-15.2)

other.required_span_size() is representable as
a value of type index_type[.](#rightpad.cons-15.sentence-1)

[16](#rightpad.cons-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23996)

*Effects*: 

- [(16.1)](#rightpad.cons-16.1)

Direct-non-list-initializes *extents_* with other.extents(); and

- [(16.2)](#rightpad.cons-16.2)

if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2* with other.stride(rank_ - 2)[.](#rightpad.cons-16.sentence-1)

[17](#rightpad.cons-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24007)

*Remarks*: The expression inside explicit is equivalent to:*rank_* > 1 &&(padding_value != dynamic_extent || LayoutRightPaddedMapping::padding_value == dynamic_extent)

[ð](#lib:layout_right_padded::mapping,constructor_____)

`template<class LayoutLeftPaddedMapping>
  constexpr explicit(see below)
    mapping(const LayoutLeftPaddedMapping& other) noexcept;
`

[18](#rightpad.cons-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24025)

*Constraints*: 

- [(18.1)](#rightpad.cons-18.1)

  *is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true or  
*is-mapping-of*<layout_left, LayoutLeftPaddedMapping> is true[.](#rightpad.cons-18.1.sentence-1)

- [(18.2)](#rightpad.cons-18.2)

  *rank_* equals zero or one[.](#rightpad.cons-18.2.sentence-1)

- [(18.3)](#rightpad.cons-18.3)

  is_constructible_v<extents_type, typename LayoutLeftPaddedMapping​::​extents_type>  
is true[.](#rightpad.cons-18.3.sentence-1)

[19](#rightpad.cons-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24040)

*Preconditions*: other.required_span_size() is representable as
a value of type index_type[.](#rightpad.cons-19.sentence-1)

[20](#rightpad.cons-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24045)

*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#rightpad.cons-20.sentence-1)

[21](#rightpad.cons-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24049)

*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type, extents_type>

[*Note [1](#rightpad.cons-note-1)*:

Neither the input mapping nor the mapping to be constructed
uses the padding stride in the rank-0 or rank-1 case,
so the padding stride affects neither the constraints nor the preconditions[.](#rightpad.cons-21.sentence-1)

â *end note*]

#### [23.7.3.4.9.4](#rightpad.obs) Observers [[mdspan.layout.rightpad.obs]](mdspan.layout.rightpad.obs)

[ð](#lib:layout_right_padded::mapping,strides)

`constexpr array<index_type, rank_> strides() const noexcept;
`

[1](#rightpad.obs-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24070)

*Returns*: array<index_type, *rank_*>(stride(P_rank)...)[.](#rightpad.obs-1.sentence-1)

[ð](#lib:layout_right_padded::mapping,required_span_size)

`constexpr index_type required_span_size() const noexcept;
`

[2](#rightpad.obs-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24081)

*Returns*: 0 if the multidimensional index space *extents_* is empty,
otherwise *this(((*extents_*(P_rank) - index_type(1))...)) + 1[.](#rightpad.obs-2.sentence-1)

[ð](#lib:layout_right_padded::mapping,operator())

`template<class... Indices>
constexpr size_t operator()(Indices... idxs) const noexcept;
`

[3](#rightpad.obs-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24094)

*Constraints*: 

- [(3.1)](#rightpad.obs-3.1)

  sizeof...(Indices) == *rank_* is true[.](#rightpad.obs-3.1.sentence-1)

- [(3.2)](#rightpad.obs-3.2)

  (is_convertible_v<Indices, index_type> && ...) is true[.](#rightpad.obs-3.2.sentence-1)

- [(3.3)](#rightpad.obs-3.3)

  (is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#rightpad.obs-3.3.sentence-1)

[4](#rightpad.obs-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24105)

*Preconditions*: extents_type​::​*index-cast*(idxs) is
a multidimensional index in extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#rightpad.obs-4.sentence-1)

[5](#rightpad.obs-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24110)

*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#rightpad.obs-5.sentence-1)

[ð](#lib:layout_right_padded::mapping,is_always_exhaustive)

`static constexpr bool is_always_exhaustive() noexcept;
`

[6](#rightpad.obs-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24121)

*Returns*: 

- [(6.1)](#rightpad.obs-6.1)

If *rank_* equals zero or one, then true;

- [(6.2)](#rightpad.obs-6.2)

otherwise,
if neither *static-padding-stride* nor *last-static-extent* equal dynamic_extent,
then *static-padding-stride* == *last-static-extent*;

- [(6.3)](#rightpad.obs-6.3)

otherwise, false[.](#rightpad.obs-6.sentence-1)

[ð](#lib:layout_right_padded::mapping,is_exhaustive)

`constexpr bool is_exhaustive() const noexcept;
`

[7](#rightpad.obs-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24142)

*Returns*: true if *rank_* equals zero or one;
otherwise,*extents_*.extent(*rank_* - 1) == stride(*rank_* - 2)

[ð](#rightpad.obs-itemdecl:6)

`constexpr index_type stride(rank_type r) const noexcept;
`

[8](#rightpad.obs-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24156)

*Preconditions*: r is smaller than *rank_*[.](#rightpad.obs-8.sentence-1)

[9](#rightpad.obs-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24160)

*Returns*: 

- [(9.1)](#rightpad.obs-9.1)

If r equals *rank_* - 1: 1;

- [(9.2)](#rightpad.obs-9.2)

otherwise, if r equals *rank_* - 2: *stride-rm2*;

- [(9.3)](#rightpad.obs-9.3)

otherwise,
the product of *stride-rm2* and
all values extents_.extent(k) with k in the range of [r + 1, *rank_* - 1)[.](#rightpad.obs-9.sentence-1)

[ð](#lib:layout_right_padded::mapping,operator==)

`template<class LayoutRightPaddedMapping>
  friend constexpr bool operator==(const mapping& x, const LayoutRightPaddedMapping& y) noexcept;
`

[10](#rightpad.obs-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24182)

*Constraints*: 

- [(10.1)](#rightpad.obs-10.1)

  *is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#rightpad.obs-10.1.sentence-1)

- [(10.2)](#rightpad.obs-10.2)

  LayoutRightPaddedMapping​::​extents_type​::​rank() == *rank_* is true[.](#rightpad.obs-10.2.sentence-1)

[11](#rightpad.obs-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24193)

*Returns*: true if x.extents() == y.extents() is true and*rank_* < 2 || x.stride(*rank_* - 2) == y.stride(*rank_* - 2) is true[.](#rightpad.obs-11.sentence-1)

Otherwise, false[.](#rightpad.obs-11.sentence-2)
