This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
[mdspan.layout.general]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.general)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.general)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#general)
#### 23.7.3.4.1 General [mdspan.layout.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21522)
In [[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2Requirements") and [[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3Layout mapping policy requirements"):
- [(1.1)](#1.1)
M denotes a layout mapping class[.](#1.1.sentence-1)
- [(1.2)](#1.2)
m denotes a (possibly const) value of type M[.](#1.2.sentence-1)
- [(1.3)](#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.1Overview"))[.](#1.3.sentence-1)
[*Note [1](#note-1)*:
The type of each element of the packs can be a different integer type[.](#1.3.sentence-2)
— *end note*]
- [(1.4)](#1.4)
r is a (possibly const) rank index of typename M::extents_type[.](#1.4.sentence-1)
- [(1.5)](#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[.](#1.5.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21549)
In [[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2Requirements") through [[mdspan.layout.stride]](mdspan.layout.stride "23.7.3.4.7Class template layout_­stride::mapping"):
- [(2.1)](#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)](#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)](#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)](#2.4)
For nonnegative integers x and y,
let LEAST-MULTIPLE-AT-LEAST(x,y) denote
* [(2.4.1)](#2.4.1)
y if x is zero,
* [(2.4.2)](#2.4.2)
otherwise, the least multiple of x that is greater than or equal to y.

View File

@@ -0,0 +1,317 @@
[mdspan.layout.left]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.left)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.left)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#left)
#### 23.7.3.4.5 Class template layout_left::mapping [mdspan.layout.left]
#### [23.7.3.4.5.1](#overview) Overview [[mdspan.layout.left.overview]](mdspan.layout.left.overview)
[1](#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[.](#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]](#cons "23.7.3.4.5.2Constructors"), 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]](#obs "23.7.3.4.5.3Observers"), 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.6Specializations 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](#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[.](#overview-2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#overview-3.sentence-1)
[4](#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[.](#overview-4.sentence-1)
#### [23.7.3.4.5.2](#cons) Constructors [[mdspan.layout.left.cons]](mdspan.layout.left.cons)
[🔗](#lib:layout_left::mapping,constructor)
`constexpr mapping(const extents_type& e) noexcept;
`
[1](#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.2Fundamental types"))[.](#cons-1.sentence-1)
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22017)
*Effects*: Direct-non-list-initializes *extents_* with e[.](#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](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22030)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-3.sentence-1)
[4](#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.2Fundamental types"))[.](#cons-4.sentence-1)
[5](#cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22039)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#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](#cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22052)
*Constraints*:
- [(6.1)](#cons-6.1)
extents_type::rank() <= 1 is true, and
- [(6.2)](#cons-6.2)
is_constructible_v<extents_type, OtherExtents> is true[.](#cons-6.sentence-1)
[7](#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.2Fundamental types"))[.](#cons-7.sentence-1)
[8](#cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22066)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#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](#cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22080)
*Constraints*:
- [(9.1)](#cons-9.1)
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#cons-9.1.sentence-1)
- [(9.2)](#cons-9.2)
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
is true[.](#cons-9.2.sentence-1)
[10](#cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22089)
*Mandates*: If
- [(10.1)](#cons-10.1)
Extents::rank() is greater than one,
- [(10.2)](#cons-10.2)
Extents::static_extent(0) does not equal dynamic_extent, and
- [(10.3)](#cons-10.3)
LayoutLeftPaddedMapping::*static-padding-stride* does not equal dynamic_extent,
then Extents::static_extent(0) equalsLayoutLeftPaddedMapping::*static-padding-stride*[.](#cons-10.sentence-1)
[11](#cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22104)
*Preconditions*:
- [(11.1)](#cons-11.1)
If extents_type::rank() > 1 is true,
then other.stride(1) equals other.extents(0)[.](#cons-11.1.sentence-1)
- [(11.2)](#cons-11.2)
other.required_span_size() is representable as
a value of type index_type[.](#cons-11.2.sentence-1)
[12](#cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22115)
*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#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](#cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22128)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-13.sentence-1)
[14](#cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22132)
*Preconditions*:
- [(14.1)](#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)](#cons-14.2)
other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#cons-14.sentence-1)
[15](#cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22145)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-15.sentence-1)
#### [23.7.3.4.5.3](#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](#obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22158)
*Returns*: extents().*fwd-prod-of-extents*(extents_type::rank())[.](#obs-1.sentence-1)
[🔗](#lib:operator(),layout_left::mapping)
`template<class... Indices>
constexpr index_type operator()(Indices... i) const noexcept;
`
[2](#obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22170)
*Constraints*:
- [(2.1)](#obs-2.1)
sizeof...(Indices) == extents_type::rank() is true,
- [(2.2)](#obs-2.2)
(is_convertible_v<Indices, index_type> && ...) is true, and
- [(2.3)](#obs-2.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#obs-2.sentence-1)
[3](#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.1Overview"))[.](#obs-3.sentence-1)
[4](#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[.](#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](#obs-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22205)
*Constraints*: extents_type::rank() > 0 is true[.](#obs-5.sentence-1)
[6](#obs-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22209)
*Preconditions*: i < extents_type::rank() is true[.](#obs-6.sentence-1)
[7](#obs-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22213)
*Returns*: extents().*fwd-prod-of-extents*(i)[.](#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](#obs-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22225)
*Constraints*: extents_type::rank() == OtherExtents::rank() is true[.](#obs-8.sentence-1)
[9](#obs-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22229)
*Effects*: Equivalent to: return x.extents() == y.extents();

View File

@@ -0,0 +1,190 @@
[mdspan.layout.left.cons]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.left.cons)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.left.cons)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#left.cons)
#### 23.7.3.4.5 Class template layout_left::mapping [[mdspan.layout.left]](mdspan.layout.left#cons)
#### 23.7.3.4.5.2 Constructors [mdspan.layout.left.cons]
[🔗](#lib:layout_left::mapping,constructor)
`constexpr mapping(const extents_type& e) noexcept;
`
[1](#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.2Fundamental types"))[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22017)
*Effects*: Direct-non-list-initializes *extents_* with e[.](#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](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22030)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#3.sentence-1)
[4](#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.2Fundamental types"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22039)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#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](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22052)
*Constraints*:
- [(6.1)](#6.1)
extents_type::rank() <= 1 is true, and
- [(6.2)](#6.2)
is_constructible_v<extents_type, OtherExtents> is true[.](#6.sentence-1)
[7](#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.2Fundamental types"))[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22066)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#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](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22080)
*Constraints*:
- [(9.1)](#9.1)
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#9.1.sentence-1)
- [(9.2)](#9.2)
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
is true[.](#9.2.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22089)
*Mandates*: If
- [(10.1)](#10.1)
Extents::rank() is greater than one,
- [(10.2)](#10.2)
Extents::static_extent(0) does not equal dynamic_extent, and
- [(10.3)](#10.3)
LayoutLeftPaddedMapping::*static-padding-stride* does not equal dynamic_extent,
then Extents::static_extent(0) equalsLayoutLeftPaddedMapping::*static-padding-stride*[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22104)
*Preconditions*:
- [(11.1)](#11.1)
If extents_type::rank() > 1 is true,
then other.stride(1) equals other.extents(0)[.](#11.1.sentence-1)
- [(11.2)](#11.2)
other.required_span_size() is representable as
a value of type index_type[.](#11.2.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22115)
*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#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](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22128)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22132)
*Preconditions*:
- [(14.1)](#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)](#14.2)
other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22145)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#15.sentence-1)

View File

@@ -0,0 +1,104 @@
[mdspan.layout.left.obs]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.left.obs)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.left.obs)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#left.obs)
#### 23.7.3.4.5 Class template layout_left::mapping [[mdspan.layout.left]](mdspan.layout.left#obs)
#### 23.7.3.4.5.3 Observers [mdspan.layout.left.obs]
[🔗](#lib:required_span_size,layout_left::mapping)
`constexpr index_type required_span_size() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22158)
*Returns*: extents().*fwd-prod-of-extents*(extents_type::rank())[.](#1.sentence-1)
[🔗](#lib:operator(),layout_left::mapping)
`template<class... Indices>
constexpr index_type operator()(Indices... i) const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22170)
*Constraints*:
- [(2.1)](#2.1)
sizeof...(Indices) == extents_type::rank() is true,
- [(2.2)](#2.2)
(is_convertible_v<Indices, index_type> && ...) is true, and
- [(2.3)](#2.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#2.sentence-1)
[3](#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.1Overview"))[.](#3.sentence-1)
[4](#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[.](#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](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22205)
*Constraints*: extents_type::rank() > 0 is true[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22209)
*Preconditions*: i < extents_type::rank() is true[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22213)
*Returns*: extents().*fwd-prod-of-extents*(i)[.](#7.sentence-1)
[🔗](#lib:operator==,layout_left::mapping)
`template<class OtherExtents>
friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22225)
*Constraints*: extents_type::rank() == OtherExtents::rank() is true[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22229)
*Effects*: Equivalent to: return x.extents() == y.extents();

View File

@@ -0,0 +1,45 @@
[mdspan.layout.left.overview]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.left.overview)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.left.overview)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#left.overview)
#### 23.7.3.4.5 Class template layout_left::mapping [[mdspan.layout.left]](mdspan.layout.left#overview)
#### 23.7.3.4.5.1 Overview [mdspan.layout.left.overview]
[1](#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[.](#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]](mdspan.layout.left.cons "23.7.3.4.5.2Constructors"), 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]](mdspan.layout.left.obs "23.7.3.4.5.3Observers"), 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.6Specializations 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](#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[.](#2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#3.sentence-1)
[4](#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[.](#4.sentence-1)

View File

@@ -0,0 +1,648 @@
[mdspan.layout.leftpad]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.leftpad)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad)
#### 23.7.3.4.8 Class template layout_left_padded::mapping [mdspan.layout.leftpad]
#### [23.7.3.4.8.1](#overview) Overview [[mdspan.layout.leftpad.overview]](mdspan.layout.leftpad.overview)
[1](#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)[.](#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]](#expo "23.7.3.4.8.2Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.leftpad.cons]](#cons "23.7.3.4.8.3Constructors"), 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]](#obs "23.7.3.4.8.4Observers"), 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]](#expo "23.7.3.4.8.2Exposition-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.6Specializations 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](#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[.](#overview-2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#overview-3.sentence-1)
[4](#overview-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23043)
Throughout [mdspan.layout.leftpad],
let P_rank be the following
size *rank_* parameter pack of size_t values:
- [(4.1)](#overview-4.1)
the empty parameter pack, if *rank_* equals zero;
- [(4.2)](#overview-4.2)
otherwise, 0zu, if *rank_* equals one;
- [(4.3)](#overview-4.3)
otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#overview-4.sentence-1)
[5](#overview-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23056)
*Mandates*:
- [(5.1)](#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[.](#overview-5.1.sentence-1)
- [(5.2)](#overview-5.2)
padding_value is representable as a value of type index_type[.](#overview-5.2.sentence-1)
- [(5.3)](#overview-5.3)
If
* [(5.3.1)](#overview-5.3.1)
*rank_* is greater than one,
* [(5.3.2)](#overview-5.3.2)
padding_value does not equal dynamic_extent, and
* [(5.3.3)](#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[.](#overview-5.3.sentence-1)
- [(5.4)](#overview-5.4)
If
* [(5.4.1)](#overview-5.4.1)
*rank_* is greater than one,
* [(5.4.2)](#overview-5.4.2)
padding_value does not equal dynamic_extent, and
* [(5.4.3)](#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[.](#overview-5.4.sentence-1)
#### [23.7.3.4.8.2](#expo) Exposition-only members [[mdspan.layout.leftpad.expo]](mdspan.layout.leftpad.expo)
[🔗](#expo-itemdecl:1)
`static constexpr size_t static-padding-stride = see below;
`
[1](#expo-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23104)
The value is
- [(1.1)](#expo-1.1)
0, if *rank_* equals zero or one;
- [(1.2)](#expo-1.2)
otherwise, dynamic_extent,
if padding_value or *first-static-extent* equalsdynamic_extent;
- [(1.3)](#expo-1.3)
otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *first-static-extent*)[.](#expo-1.sentence-1)
[🔗](#expo-itemdecl:2)
`index_type stride-1 = static-padding-stride;
`
[2](#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[.](#expo-2.sentence-1)
[*Note [1](#expo-note-1)*:
Using extents<index_type, *static-padding-stride*> instead ofindex_type as the type of *stride-1* would achieve this[.](#expo-2.sentence-2)
— *end note*]
#### [23.7.3.4.8.3](#cons) Constructors [[mdspan.layout.leftpad.cons]](mdspan.layout.leftpad.cons)
[🔗](#lib:layout_left_padded::mapping,constructor)
`constexpr mapping(const extents_type& ext);
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23142)
*Preconditions*:
- [(1.1)](#cons-1.1)
The size of the multidimensional index space ext is representable as
a value of type index_type[.](#cons-1.1.sentence-1)
- [(1.2)](#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*[.](#cons-1.2.sentence-1)
- [(1.3)](#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[.](#cons-1.3.sentence-1)
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23163)
*Effects*:
- [(2.1)](#cons-2.1)
Direct-non-list-initializes *extents_* with ext; and
- [(2.2)](#cons-2.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-1*
* [(2.2.1)](#cons-2.2.1)
with ext.extent(0) if padding_value is dynamic_extent,
* [(2.2.2)](#cons-2.2.2)
otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0))[.](#cons-2.sentence-1)
[🔗](#lib:layout_left_padded::mapping,constructor_)
`template<class OtherIndexType>
constexpr mapping(const extents_type& ext, OtherIndexType pad);
`
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23188)
*Constraints*:
- [(3.1)](#cons-3.1)
is_convertible_v<OtherIndexType, index_type> is true[.](#cons-3.1.sentence-1)
- [(3.2)](#cons-3.2)
is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#cons-3.2.sentence-1)
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23197)
*Preconditions*:
- [(4.1)](#cons-4.1)
pad is representable as a value of type index_type[.](#cons-4.1.sentence-1)
- [(4.2)](#cons-4.2)
extents_type::index-cast(pad) is greater than zero[.](#cons-4.2.sentence-1)
- [(4.3)](#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)](#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[.](#cons-4.4.sentence-1)
- [(4.5)](#cons-4.5)
If padding_value is not equal to dynamic_extent,padding_value equals extents_type::*index-cast*(pad)[.](#cons-4.5.sentence-1)
[5](#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))[.](#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](#cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23236)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-6.sentence-1)
[7](#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[.](#cons-7.sentence-1)
[8](#cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23250)
*Preconditions*:
- [(8.1)](#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)](#cons-8.2)
other.required_span_size() is representable as
a value of type index_type[.](#cons-8.sentence-1)
[9](#cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23267)
*Effects*: Equivalent to mapping(other.extents())[.](#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](#cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23280)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-10.sentence-1)
[11](#cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23284)
*Preconditions*:
- [(11.1)](#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)](#cons-11.2)
If *rank_* is greater than 0,
then other.stride(0) equals 1[.](#cons-11.2.sentence-1)
- [(11.3)](#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)](#cons-11.4)
other.required_span_size() is representable as
a value of type *index_type*[.](#cons-11.4.sentence-1)
[12](#cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23310)
*Effects*:
- [(12.1)](#cons-12.1)
Direct-non-list-initializes *extents_* with other.extents() and
- [(12.2)](#cons-12.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-1* withother.stride(1)[.](#cons-12.sentence-1)
[🔗](#lib:layout_left_padded::mapping,constructor____)
`template<class LayoutLeftPaddedMapping>
constexpr explicit(see below)
mapping(const LayoutLeftPaddedMapping& other);
`
[13](#cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23330)
*Constraints*:
- [(13.1)](#cons-13.1)
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#cons-13.1.sentence-1)
- [(13.2)](#cons-13.2)
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
is true[.](#cons-13.2.sentence-1)
[14](#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[.](#cons-14.sentence-1)
[15](#cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23352)
*Preconditions*:
- [(15.1)](#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)](#cons-15.2)
other.required_span_size() is representable as
a value of type index_type[.](#cons-15.sentence-1)
[16](#cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23368)
*Effects*:
- [(16.1)](#cons-16.1)
Direct-non-list-initializes *extents_* with other.extents() and
- [(16.2)](#cons-16.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-1* with other.stride(1)[.](#cons-16.sentence-1)
[17](#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](#cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23396)
*Constraints*:
- [(18.1)](#cons-18.1)
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true or
*is-mapping-of*<layout_right, LayoutRightPaddedMapping> is true[.](#cons-18.1.sentence-1)
- [(18.2)](#cons-18.2)
*rank_* equals zero or one[.](#cons-18.2.sentence-1)
- [(18.3)](#cons-18.3)
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
type> is true[.](#cons-18.3.sentence-1)
[19](#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[.](#cons-19.sentence-1)
[20](#cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23416)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-20.sentence-1)
[21](#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](#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[.](#cons-21.sentence-2)
— *end note*]
#### [23.7.3.4.8.4](#obs) Observers [[mdspan.layout.leftpad.obs]](mdspan.layout.leftpad.obs)
[🔗](#obs-itemdecl:1)
`constexpr array<index_type, rank_> strides() const noexcept;
`
[1](#obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23442)
*Returns*: array<index_type, *rank_*>({stride(P_rank)...})[.](#obs-1.sentence-1)
[🔗](#obs-itemdecl:2)
`constexpr index_type required_span_size() const noexcept;
`
[2](#obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23452)
*Returns*:
- [(2.1)](#obs-2.1)
0 if the multidimensional index space *extents_* is empty,
- [(2.2)](#obs-2.2)
otherwise, *this(((*extents_*(P_rank) - index_type(1))...)) + 1[.](#obs-2.sentence-1)
[🔗](#obs-itemdecl:3)
`template<class... Indices>
constexpr size_t operator()(Indices... idxs) const noexcept;
`
[3](#obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23468)
*Constraints*:
- [(3.1)](#obs-3.1)
sizeof...(Indices) == *rank_* is true[.](#obs-3.1.sentence-1)
- [(3.2)](#obs-3.2)
(is_convertible_v<Indices, index_type> && ...) is true[.](#obs-3.2.sentence-1)
- [(3.3)](#obs-3.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#obs-3.3.sentence-1)
[4](#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.1Overview"))[.](#obs-4.sentence-1)
[5](#obs-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23484)
*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#obs-5.sentence-1)
[🔗](#obs-itemdecl:4)
`static constexpr bool is_always_exhaustive() noexcept;
`
[6](#obs-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23494)
*Returns*:
- [(6.1)](#obs-6.1)
If *rank_* equals zero or one, then true;
- [(6.2)](#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)](#obs-6.3)
otherwise, false[.](#obs-6.sentence-1)
[🔗](#obs-itemdecl:5)
`constexpr bool is_exhaustive() const noexcept;
`
[7](#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)[.](#obs-7.sentence-1)
[🔗](#obs-itemdecl:6)
`constexpr index_type stride(rank_type r) const noexcept;
`
[8](#obs-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23525)
*Preconditions*: r is smaller than *rank_*[.](#obs-8.sentence-1)
[9](#obs-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23529)
*Returns*:
- [(9.1)](#obs-9.1)
If r equals zero: 1;
- [(9.2)](#obs-9.2)
otherwise, if r equals one: *stride-1*;
- [(9.3)](#obs-9.3)
otherwise, the product of *stride-1* and
all values extents_.extent(k) with k in the range [1, r)[.](#obs-9.sentence-1)
[🔗](#obs-itemdecl:7)
`template<class LayoutLeftPaddedMapping>
friend constexpr bool operator==(const mapping& x, const LayoutLeftPaddedMapping& y) noexcept;
`
[10](#obs-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23548)
*Constraints*:
- [(10.1)](#obs-10.1)
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#obs-10.1.sentence-1)
- [(10.2)](#obs-10.2)
LayoutLeftPaddedMapping::extents_type::rank() == rank_ is true[.](#obs-10.2.sentence-1)
[11](#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[.](#obs-11.sentence-1)
Otherwise, false[.](#obs-11.sentence-2)

View File

@@ -0,0 +1,340 @@
[mdspan.layout.leftpad.cons]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.leftpad.cons)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad.cons)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad.cons)
#### 23.7.3.4.8 Class template layout_left_padded::mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad#cons)
#### 23.7.3.4.8.3 Constructors [mdspan.layout.leftpad.cons]
[🔗](#lib:layout_left_padded::mapping,constructor)
`constexpr mapping(const extents_type& ext);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23142)
*Preconditions*:
- [(1.1)](#1.1)
The size of the multidimensional index space ext is representable as
a value of type index_type[.](#1.1.sentence-1)
- [(1.2)](#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*[.](#1.2.sentence-1)
- [(1.3)](#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[.](#1.3.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23163)
*Effects*:
- [(2.1)](#2.1)
Direct-non-list-initializes *extents_* with ext; and
- [(2.2)](#2.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-1*
* [(2.2.1)](#2.2.1)
with ext.extent(0) if padding_value is dynamic_extent,
* [(2.2.2)](#2.2.2)
otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0))[.](#2.sentence-1)
[🔗](#lib:layout_left_padded::mapping,constructor_)
`template<class OtherIndexType>
constexpr mapping(const extents_type& ext, OtherIndexType pad);
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23188)
*Constraints*:
- [(3.1)](#3.1)
is_convertible_v<OtherIndexType, index_type> is true[.](#3.1.sentence-1)
- [(3.2)](#3.2)
is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#3.2.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23197)
*Preconditions*:
- [(4.1)](#4.1)
pad is representable as a value of type index_type[.](#4.1.sentence-1)
- [(4.2)](#4.2)
extents_type::index-cast(pad) is greater than zero[.](#4.2.sentence-1)
- [(4.3)](#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)](#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[.](#4.4.sentence-1)
- [(4.5)](#4.5)
If padding_value is not equal to dynamic_extent,padding_value equals extents_type::*index-cast*(pad)[.](#4.5.sentence-1)
[5](#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))[.](#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](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23236)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#6.sentence-1)
[7](#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[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23250)
*Preconditions*:
- [(8.1)](#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)](#8.2)
other.required_span_size() is representable as
a value of type index_type[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23267)
*Effects*: Equivalent to mapping(other.extents())[.](#9.sentence-1)
[🔗](#lib:layout_left_padded::mapping,constructor___)
`template<class OtherExtents>
constexpr explicit(rank_ > 0)
mapping(const layout_stride::mapping<OtherExtents>& other);
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23280)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23284)
*Preconditions*:
- [(11.1)](#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)](#11.2)
If *rank_* is greater than 0,
then other.stride(0) equals 1[.](#11.2.sentence-1)
- [(11.3)](#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)](#11.4)
other.required_span_size() is representable as
a value of type *index_type*[.](#11.4.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23310)
*Effects*:
- [(12.1)](#12.1)
Direct-non-list-initializes *extents_* with other.extents() and
- [(12.2)](#12.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-1* withother.stride(1)[.](#12.sentence-1)
[🔗](#lib:layout_left_padded::mapping,constructor____)
`template<class LayoutLeftPaddedMapping>
constexpr explicit(see below)
mapping(const LayoutLeftPaddedMapping& other);
`
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23330)
*Constraints*:
- [(13.1)](#13.1)
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#13.1.sentence-1)
- [(13.2)](#13.2)
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
is true[.](#13.2.sentence-1)
[14](#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[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23352)
*Preconditions*:
- [(15.1)](#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)](#15.2)
other.required_span_size() is representable as
a value of type index_type[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23368)
*Effects*:
- [(16.1)](#16.1)
Direct-non-list-initializes *extents_* with other.extents() and
- [(16.2)](#16.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-1* with other.stride(1)[.](#16.sentence-1)
[17](#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](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23396)
*Constraints*:
- [(18.1)](#18.1)
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true or
*is-mapping-of*<layout_right, LayoutRightPaddedMapping> is true[.](#18.1.sentence-1)
- [(18.2)](#18.2)
*rank_* equals zero or one[.](#18.2.sentence-1)
- [(18.3)](#18.3)
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
type> is true[.](#18.3.sentence-1)
[19](#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[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23416)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#20.sentence-1)
[21](#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](#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[.](#21.sentence-2)
— *end note*]

View File

@@ -0,0 +1,55 @@
[mdspan.layout.leftpad.expo]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.leftpad.expo)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad.expo)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad.expo)
#### 23.7.3.4.8 Class template layout_left_padded::mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad#expo)
#### 23.7.3.4.8.2 Exposition-only members [mdspan.layout.leftpad.expo]
[🔗](#itemdecl:1)
`static constexpr size_t static-padding-stride = see below;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23104)
The value is
- [(1.1)](#1.1)
0, if *rank_* equals zero or one;
- [(1.2)](#1.2)
otherwise, dynamic_extent,
if padding_value or *first-static-extent* equalsdynamic_extent;
- [(1.3)](#1.3)
otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *first-static-extent*)[.](#1.sentence-1)
[🔗](#itemdecl:2)
`index_type stride-1 = static-padding-stride;
`
[2](#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[.](#2.sentence-1)
[*Note [1](#note-1)*:
Using extents<index_type, *static-padding-stride*> instead ofindex_type as the type of *stride-1* would achieve this[.](#2.sentence-2)
— *end note*]

View File

@@ -0,0 +1,176 @@
[mdspan.layout.leftpad.obs]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.leftpad.obs)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad.obs)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad.obs)
#### 23.7.3.4.8 Class template layout_left_padded::mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad#obs)
#### 23.7.3.4.8.4 Observers [mdspan.layout.leftpad.obs]
[🔗](#itemdecl:1)
`constexpr array<index_type, rank_> strides() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23442)
*Returns*: array<index_type, *rank_*>({stride(P_rank)...})[.](#1.sentence-1)
[🔗](#itemdecl:2)
`constexpr index_type required_span_size() const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23452)
*Returns*:
- [(2.1)](#2.1)
0 if the multidimensional index space *extents_* is empty,
- [(2.2)](#2.2)
otherwise, *this(((*extents_*(P_rank) - index_type(1))...)) + 1[.](#2.sentence-1)
[🔗](#itemdecl:3)
`template<class... Indices>
constexpr size_t operator()(Indices... idxs) const noexcept;
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23468)
*Constraints*:
- [(3.1)](#3.1)
sizeof...(Indices) == *rank_* is true[.](#3.1.sentence-1)
- [(3.2)](#3.2)
(is_convertible_v<Indices, index_type> && ...) is true[.](#3.2.sentence-1)
- [(3.3)](#3.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#3.3.sentence-1)
[4](#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.1Overview"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23484)
*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#5.sentence-1)
[🔗](#itemdecl:4)
`static constexpr bool is_always_exhaustive() noexcept;
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23494)
*Returns*:
- [(6.1)](#6.1)
If *rank_* equals zero or one, then true;
- [(6.2)](#6.2)
otherwise, if
neither *static-padding-stride* nor *first-static-extent* equal dynamic_extent,
then *static-padding-stride* == *first-static-extent*;
- [(6.3)](#6.3)
otherwise, false[.](#6.sentence-1)
[🔗](#itemdecl:5)
`constexpr bool is_exhaustive() const noexcept;
`
[7](#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)[.](#7.sentence-1)
[🔗](#itemdecl:6)
`constexpr index_type stride(rank_type r) const noexcept;
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23525)
*Preconditions*: r is smaller than *rank_*[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23529)
*Returns*:
- [(9.1)](#9.1)
If r equals zero: 1;
- [(9.2)](#9.2)
otherwise, if r equals one: *stride-1*;
- [(9.3)](#9.3)
otherwise, the product of *stride-1* and
all values extents_.extent(k) with k in the range [1, r)[.](#9.sentence-1)
[🔗](#itemdecl:7)
`template<class LayoutLeftPaddedMapping>
friend constexpr bool operator==(const mapping& x, const LayoutLeftPaddedMapping& y) noexcept;
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23548)
*Constraints*:
- [(10.1)](#10.1)
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#10.1.sentence-1)
- [(10.2)](#10.2)
LayoutLeftPaddedMapping::extents_type::rank() == rank_ is true[.](#10.2.sentence-1)
[11](#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[.](#11.sentence-1)
Otherwise, false[.](#11.sentence-2)

View File

@@ -0,0 +1,110 @@
[mdspan.layout.leftpad.overview]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.leftpad.overview)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad.overview)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad.overview)
#### 23.7.3.4.8 Class template layout_left_padded::mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad#overview)
#### 23.7.3.4.8.1 Overview [mdspan.layout.leftpad.overview]
[1](#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)[.](#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]](mdspan.layout.leftpad.expo "23.7.3.4.8.2Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.leftpad.cons]](mdspan.layout.leftpad.cons "23.7.3.4.8.3Constructors"), 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]](mdspan.layout.leftpad.obs "23.7.3.4.8.4Observers"), 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]](mdspan.layout.leftpad.expo "23.7.3.4.8.2Exposition-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.6Specializations 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](#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[.](#2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23043)
Throughout [[mdspan.layout.leftpad]](mdspan.layout.leftpad "23.7.3.4.8Class template layout_­left_­padded::mapping"),
let P_rank be the following
size *rank_* parameter pack of size_t values:
- [(4.1)](#4.1)
the empty parameter pack, if *rank_* equals zero;
- [(4.2)](#4.2)
otherwise, 0zu, if *rank_* equals one;
- [(4.3)](#4.3)
otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23056)
*Mandates*:
- [(5.1)](#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[.](#5.1.sentence-1)
- [(5.2)](#5.2)
padding_value is representable as a value of type index_type[.](#5.2.sentence-1)
- [(5.3)](#5.3)
If
* [(5.3.1)](#5.3.1)
*rank_* is greater than one,
* [(5.3.2)](#5.3.2)
padding_value does not equal dynamic_extent, and
* [(5.3.3)](#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[.](#5.3.sentence-1)
- [(5.4)](#5.4)
If
* [(5.4.1)](#5.4.1)
*rank_* is greater than one,
* [(5.4.2)](#5.4.2)
padding_value does not equal dynamic_extent, and
* [(5.4.3)](#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[.](#5.4.sentence-1)

View File

@@ -0,0 +1,23 @@
[mdspan.layout.policy.overview]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.policy.overview)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.policy.overview)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#policy.overview)
#### 23.7.3.4.4 Layout mapping policies [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](#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[.](#1.sentence-1)
Furthermore,is_trivially_default_constructible_v<T> is true for any such type T[.](#1.sentence-2)

View File

@@ -0,0 +1,21 @@
[mdspan.layout.policy.reqmts]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.policy.reqmts)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.policy.reqmts)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#policy.reqmts)
#### 23.7.3.4.3 Layout mapping policy requirements [mdspan.layout.policy.reqmts]
[1](#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.3Layout 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]](mdspan.layout.reqmts "23.7.3.4.2Requirements")), and
for which the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified 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.3Qualified names[expr.prim.id.qual]") X::extents_type denotes E[.](#1.sentence-1)

View File

@@ -0,0 +1,352 @@
[mdspan.layout.reqmts]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.reqmts)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.reqmts)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#reqmts)
#### 23.7.3.4.2 Requirements [mdspan.layout.reqmts]
[1](#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.2Requirements[mdspan.layout.reqmts]") requirements if
- [(1.1)](#1.1)
M models [copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]") and [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]"),
- [(1.2)](#1.2)
is_nothrow_move_constructible_v<M> is true,
- [(1.3)](#1.3)
is_nothrow_move_assignable_v<M> is true,
- [(1.4)](#1.4)
is_nothrow_swappable_v<M> is true, and
- [(1.5)](#1.5)
the following types and expressions are well-formed and
have the specified semantics.
[🔗](#itemdecl:1)
`typename M::extents_type
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21616)
*Result*: A type that is a specialization of extents[.](#2.sentence-1)
[🔗](#itemdecl:2)
`typename M::index_type
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21626)
*Result*: typename M::extents_type::index_type[.](#3.sentence-1)
[🔗](#itemdecl:3)
`typename M::rank_type
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21636)
*Result*: typename M::extents_type::rank_type[.](#4.sentence-1)
[🔗](#itemdecl:4)
`typename M::layout_type
`
[5](#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]](mdspan.layout.policy.reqmts "23.7.3.4.3Layout mapping policy requirements")) and
for which *is-mapping-of*<MP, M> is true[.](#5.sentence-1)
[🔗](#itemdecl:5)
`m.extents()
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21658)
*Result*: const typename M::extents_type&
[🔗](#itemdecl:6)
`m(i...)
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21668)
*Result*: typename M::index_type
[8](#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()[.](#8.sentence-1)
[🔗](#itemdecl:7)
`m(i...) == m(static_cast<typename M::index_type>(i)...)
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21684)
*Result*: bool
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21688)
*Returns*: true
[🔗](#itemdecl:8)
`m.required_span_size()
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21698)
*Result*: typename M::index_type
[12](#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[.](#12.sentence-1)
[🔗](#itemdecl:9)
`m.is_unique()
`
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21714)
*Result*: bool
[14](#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[.](#14.sentence-1)
[*Note [1](#note-1)*:
A mapping can return false even if the condition is met[.](#14.sentence-2)
For certain layouts, it is possibly not feasible to determine efficiently
whether the layout is unique[.](#14.sentence-3)
— *end note*]
[🔗](#itemdecl:10)
`m.is_exhaustive()
`
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21735)
*Result*: bool
[16](#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[.](#16.sentence-1)
[*Note [2](#note-2)*:
A mapping can return false even if the condition is met[.](#16.sentence-2)
For certain layouts, it is possibly not feasible to determine efficiently
whether the layout is exhaustive[.](#16.sentence-3)
— *end note*]
[🔗](#itemdecl:11)
`m.is_strided()
`
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21756)
*Result*: bool
[18](#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.1Overview")),m((i + dr)...) - m(i...) equals sr[.](#18.sentence-1)
[*Note [3](#note-3)*:
This implies that for a strided layoutm(i0,…,ik)=m(0,…,0)+i0×s0+⋯+ik×sk[.](#18.sentence-2)
— *end note*]
[*Note [4](#note-4)*:
A mapping can return false even if the condition is met[.](#18.sentence-3)
For certain layouts, it is possibly not feasible to determine efficiently
whether the layout is strided[.](#18.sentence-4)
— *end note*]
[🔗](#itemdecl:12)
`m.stride(r)
`
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21784)
*Preconditions*: m.is_strided() is true[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21788)
*Result*: typename M::index_type
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21792)
*Returns*: sr as defined in m.is_strided() above[.](#21.sentence-1)
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21796)
[*Note [5](#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[.](#22.sentence-1)
— *end note*]
[🔗](#itemdecl:13)
`M::is_always_unique()
`
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21809)
*Result*: A constant expression ([[expr.const]](expr.const "7.7Constant expressions")) of type bool[.](#23.sentence-1)
[24](#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[.](#24.sentence-1)
[*Note [6](#note-6)*:
A mapping can return false even if the above condition is met[.](#24.sentence-2)
For certain layout mappings, it is possibly not feasible to determine
whether every instance is unique[.](#24.sentence-3)
— *end note*]
[🔗](#itemdecl:14)
`M::is_always_exhaustive()
`
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21829)
*Result*: A constant expression ([[expr.const]](expr.const "7.7Constant expressions")) of type bool[.](#25.sentence-1)
[26](#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[.](#26.sentence-1)
[*Note [7](#note-7)*:
A mapping can return false even if the above condition is met[.](#26.sentence-2)
For certain layout mappings, it is possibly not feasible to determine
whether every instance is exhaustive[.](#26.sentence-3)
— *end note*]
[🔗](#itemdecl:15)
`M::is_always_strided()
`
[27](#27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21849)
*Result*: A constant expression ([[expr.const]](expr.const "7.7Constant expressions")) of type bool[.](#27.sentence-1)
[28](#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[.](#28.sentence-1)
[*Note [8](#note-8)*:
A mapping can return false even if the above condition is met[.](#28.sentence-2)
For certain layout mappings, it is possibly not feasible to determine
whether every instance is strided[.](#28.sentence-3)
— *end note*]

View File

@@ -0,0 +1,319 @@
[mdspan.layout.right]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.right)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.right)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#right)
#### 23.7.3.4.6 Class template layout_right::mapping [mdspan.layout.right]
#### [23.7.3.4.6.1](#overview) Overview [[mdspan.layout.right.overview]](mdspan.layout.right.overview)
[1](#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[.](#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]](#cons "23.7.3.4.6.2Constructors"), 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]](#obs "23.7.3.4.6.3Observers"), 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.6Specializations 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](#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[.](#overview-2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#overview-3.sentence-1)
[4](#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[.](#overview-4.sentence-1)
#### [23.7.3.4.6.2](#cons) Constructors [[mdspan.layout.right.cons]](mdspan.layout.right.cons)
[🔗](#lib:layout_right::mapping,constructor)
`constexpr mapping(const extents_type& e) noexcept;
`
[1](#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.2Fundamental types"))[.](#cons-1.sentence-1)
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22339)
*Effects*: Direct-non-list-initializes *extents_* with e[.](#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](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22352)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-3.sentence-1)
[4](#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.2Fundamental types"))[.](#cons-4.sentence-1)
[5](#cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22361)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#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](#cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22374)
*Constraints*:
- [(6.1)](#cons-6.1)
extents_type::rank() <= 1 is true, and
- [(6.2)](#cons-6.2)
is_constructible_v<extents_type, OtherExtents> is true[.](#cons-6.sentence-1)
[7](#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.2Fundamental types"))[.](#cons-7.sentence-1)
[8](#cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22388)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#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](#cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22402)
*Constraints*:
- [(9.1)](#cons-9.1)
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#cons-9.1.sentence-1)
- [(9.2)](#cons-9.2)
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
type> is true[.](#cons-9.2.sentence-1)
[10](#cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22413)
*Mandates*: If
- [(10.1)](#cons-10.1)
Extents::rank() is greater than one,
- [(10.2)](#cons-10.2)
Extents::static_extent(Extents::rank() - 1) does not equal dynamic_extent, and
- [(10.3)](#cons-10.3)
LayoutRightPaddedMapping::*static-padding-stride* does not equal dynamic_extent,
then Extents::static_extent(Extents::rank() - 1) equalsLayoutRightPaddedMapping::*static-padding-stride*[.](#cons-10.sentence-1)
[11](#cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22429)
*Preconditions*:
- [(11.1)](#cons-11.1)
If extents_type::rank() > 1 is true,
then other.stride(extents_type::rank() - 2)
equalsother.extents().extent(extents_type::rank() - 1)[.](#cons-11.1.sentence-1)
- [(11.2)](#cons-11.2)
other.required_span_size() is representable as
a value of type index_type[.](#cons-11.2.sentence-1)
[12](#cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22441)
*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#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](#cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22454)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-13.sentence-1)
[14](#cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22458)
*Preconditions*:
- [(14.1)](#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)[.](#cons-14.1.sentence-1)
- [(14.2)](#cons-14.2)
other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#cons-14.2.sentence-1)
[15](#cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22471)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-15.sentence-1)
#### [23.7.3.4.6.3](#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](#obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22484)
*Returns*: extents().*fwd-prod-of-extents*(extents_type::rank())[.](#obs-1.sentence-1)
[🔗](#lib:operator(),layout_right::mapping)
`template<class... Indices>
constexpr index_type operator()(Indices... i) const noexcept;
`
[2](#obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22496)
*Constraints*:
- [(2.1)](#obs-2.1)
sizeof...(Indices) == extents_type::rank() is true,
- [(2.2)](#obs-2.2)
(is_convertible_v<Indices, index_type> && ...) is true, and
- [(2.3)](#obs-2.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) istrue[.](#obs-2.sentence-1)
[3](#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.1Overview"))[.](#obs-3.sentence-1)
[4](#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[.](#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](#obs-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22531)
*Constraints*: extents_type::rank() > 0 is true[.](#obs-5.sentence-1)
[6](#obs-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22535)
*Preconditions*: i < extents_type::rank() is true[.](#obs-6.sentence-1)
[7](#obs-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22539)
*Returns*: extents().*rev-prod-of-extents*(i)[.](#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](#obs-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22551)
*Constraints*: extents_type::rank() == OtherExtents::rank() is true[.](#obs-8.sentence-1)
[9](#obs-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22555)
*Effects*: Equivalent to: return x.extents() == y.extents();

View File

@@ -0,0 +1,192 @@
[mdspan.layout.right.cons]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.right.cons)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.right.cons)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#right.cons)
#### 23.7.3.4.6 Class template layout_right::mapping [[mdspan.layout.right]](mdspan.layout.right#cons)
#### 23.7.3.4.6.2 Constructors [mdspan.layout.right.cons]
[🔗](#lib:layout_right::mapping,constructor)
`constexpr mapping(const extents_type& e) noexcept;
`
[1](#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.2Fundamental types"))[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22339)
*Effects*: Direct-non-list-initializes *extents_* with e[.](#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](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22352)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#3.sentence-1)
[4](#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.2Fundamental types"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22361)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#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](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22374)
*Constraints*:
- [(6.1)](#6.1)
extents_type::rank() <= 1 is true, and
- [(6.2)](#6.2)
is_constructible_v<extents_type, OtherExtents> is true[.](#6.sentence-1)
[7](#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.2Fundamental types"))[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22388)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#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](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22402)
*Constraints*:
- [(9.1)](#9.1)
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#9.1.sentence-1)
- [(9.2)](#9.2)
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
type> is true[.](#9.2.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22413)
*Mandates*: If
- [(10.1)](#10.1)
Extents::rank() is greater than one,
- [(10.2)](#10.2)
Extents::static_extent(Extents::rank() - 1) does not equal dynamic_extent, and
- [(10.3)](#10.3)
LayoutRightPaddedMapping::*static-padding-stride* does not equal dynamic_extent,
then Extents::static_extent(Extents::rank() - 1) equalsLayoutRightPaddedMapping::*static-padding-stride*[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22429)
*Preconditions*:
- [(11.1)](#11.1)
If extents_type::rank() > 1 is true,
then other.stride(extents_type::rank() - 2)
equalsother.extents().extent(extents_type::rank() - 1)[.](#11.1.sentence-1)
- [(11.2)](#11.2)
other.required_span_size() is representable as
a value of type index_type[.](#11.2.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22441)
*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#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](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22454)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22458)
*Preconditions*:
- [(14.1)](#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)[.](#14.1.sentence-1)
- [(14.2)](#14.2)
other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#14.2.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22471)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#15.sentence-1)

View File

@@ -0,0 +1,104 @@
[mdspan.layout.right.obs]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.right.obs)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.right.obs)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#right.obs)
#### 23.7.3.4.6 Class template layout_right::mapping [[mdspan.layout.right]](mdspan.layout.right#obs)
#### 23.7.3.4.6.3 Observers [mdspan.layout.right.obs]
[🔗](#lib:required_span_size,layout_right::mapping)
`constexpr index_type required_span_size() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22484)
*Returns*: extents().*fwd-prod-of-extents*(extents_type::rank())[.](#1.sentence-1)
[🔗](#lib:operator(),layout_right::mapping)
`template<class... Indices>
constexpr index_type operator()(Indices... i) const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22496)
*Constraints*:
- [(2.1)](#2.1)
sizeof...(Indices) == extents_type::rank() is true,
- [(2.2)](#2.2)
(is_convertible_v<Indices, index_type> && ...) is true, and
- [(2.3)](#2.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) istrue[.](#2.sentence-1)
[3](#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.1Overview"))[.](#3.sentence-1)
[4](#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[.](#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](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22531)
*Constraints*: extents_type::rank() > 0 is true[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22535)
*Preconditions*: i < extents_type::rank() is true[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22539)
*Returns*: extents().*rev-prod-of-extents*(i)[.](#7.sentence-1)
[🔗](#lib:operator==,layout_right::mapping)
`template<class OtherExtents>
friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22551)
*Constraints*: extents_type::rank() == OtherExtents::rank() is true[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22555)
*Effects*: Equivalent to: return x.extents() == y.extents();

View File

@@ -0,0 +1,45 @@
[mdspan.layout.right.overview]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.right.overview)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.right.overview)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#right.overview)
#### 23.7.3.4.6 Class template layout_right::mapping [[mdspan.layout.right]](mdspan.layout.right#overview)
#### 23.7.3.4.6.1 Overview [mdspan.layout.right.overview]
[1](#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[.](#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]](mdspan.layout.right.cons "23.7.3.4.6.2Constructors"), 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]](mdspan.layout.right.obs "23.7.3.4.6.3Observers"), 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.6Specializations 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](#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[.](#2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#3.sentence-1)
[4](#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[.](#4.sentence-1)

View File

@@ -0,0 +1,638 @@
[mdspan.layout.rightpad]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.rightpad)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad)
#### 23.7.3.4.9 Class template layout_right_padded::mapping [mdspan.layout.rightpad]
#### [23.7.3.4.9.1](#overview) Overview [[mdspan.layout.rightpad.overview]](mdspan.layout.rightpad.overview)
[1](#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)[.](#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]](#expo "23.7.3.4.9.2Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.rightpad.cons]](#cons "23.7.3.4.9.3Constructors"), 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]](#obs "23.7.3.4.9.4Observers"), 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]](#expo "23.7.3.4.9.2Exposition-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.6Specializations 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](#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[.](#overview-2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#overview-3.sentence-1)
[4](#overview-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23669)
Throughout [mdspan.layout.rightpad],
let P_rank be the following
size *rank_* parameter pack of size_t values:
- [(4.1)](#overview-4.1)
the empty parameter pack, if *rank_* equals zero;
- [(4.2)](#overview-4.2)
otherwise, 0zu, if *rank_* equals one;
- [(4.3)](#overview-4.3)
otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#overview-4.sentence-1)
[5](#overview-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23682)
*Mandates*:
- [(5.1)](#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[.](#overview-5.1.sentence-1)
- [(5.2)](#overview-5.2)
padding_value is representable as a value of type index_type[.](#overview-5.2.sentence-1)
- [(5.3)](#overview-5.3)
If
* [(5.3.1)](#overview-5.3.1)
*rank_* is greater than one,
* [(5.3.2)](#overview-5.3.2)
padding_value does not equal dynamic_extent, and
* [(5.3.3)](#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[.](#overview-5.3.sentence-1)
- [(5.4)](#overview-5.4)
If
* [(5.4.1)](#overview-5.4.1)
*rank_* is greater than one,
* [(5.4.2)](#overview-5.4.2)
padding_value does not equal dynamic_extent, and
* [(5.4.3)](#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[.](#overview-5.4.sentence-1)
#### [23.7.3.4.9.2](#expo) Exposition-only members [[mdspan.layout.rightpad.expo]](mdspan.layout.rightpad.expo)
[🔗](#expo-itemdecl:1)
`static constexpr size_t static-padding-stride = see below;
`
[1](#expo-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23730)
The value is
- [(1.1)](#expo-1.1)
0, if *rank_* equals zero or one;
- [(1.2)](#expo-1.2)
otherwise, dynamic_extent,
if padding_value or *last-static-extent* equalsdynamic_extent;
- [(1.3)](#expo-1.3)
otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *last-static-extent*)[.](#expo-1.sentence-1)
[🔗](#expo-itemdecl:2)
`index_type stride-rm2 = static-padding-stride;
`
[2](#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[.](#expo-2.sentence-1)
[*Note [1](#expo-note-1)*:
Using extents<index_type, *static-padding-stride*> instead of index_type as the type of *stride-rm2* would achieve this[.](#expo-2.sentence-2)
— *end note*]
#### [23.7.3.4.9.3](#cons) Constructors [[mdspan.layout.rightpad.cons]](mdspan.layout.rightpad.cons)
[🔗](#lib:layout_right_padded::mapping,constructor)
`constexpr mapping(const extents_type& ext);
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23769)
*Preconditions*:
- [(1.1)](#cons-1.1)
The size of the multidimensional index space ext is representable as a value of type index_type[.](#cons-1.1.sentence-1)
- [(1.2)](#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*[.](#cons-1.2.sentence-1)
- [(1.3)](#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[.](#cons-1.3.sentence-1)
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23790)
*Effects*:
- [(2.1)](#cons-2.1)
Direct-non-list-initializes *extents_* with ext; and
- [(2.2)](#cons-2.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2*
* [(2.2.1)](#cons-2.2.1)
with ext.extent(*rank_* - 1) if padding_value is dynamic_extent,
* [(2.2.2)](#cons-2.2.2)
otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1))[.](#cons-2.sentence-1)
[🔗](#lib:layout_right_padded::mapping,constructor_)
`template<class OtherIndexType>
constexpr mapping(const extents_type& ext, OtherIndexType pad);
`
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23816)
*Constraints*:
- [(3.1)](#cons-3.1)
is_convertible_v<OtherIndexType, index_type> is true[.](#cons-3.1.sentence-1)
- [(3.2)](#cons-3.2)
is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#cons-3.2.sentence-1)
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23825)
*Preconditions*:
- [(4.1)](#cons-4.1)
pad is representable as a value of type index_type[.](#cons-4.1.sentence-1)
- [(4.2)](#cons-4.2)
extents_type::*index-cast*(pad) is greater than zero[.](#cons-4.2.sentence-1)
- [(4.3)](#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[.](#cons-4.3.sentence-1)
- [(4.4)](#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[.](#cons-4.4.sentence-1)
- [(4.5)](#cons-4.5)
If padding_value is not equal to dynamic_extent,padding_value equals extents_type::*index-cast*(pad)[.](#cons-4.5.sentence-1)
[5](#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))[.](#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](#cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23864)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-6.sentence-1)
[7](#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[.](#cons-7.sentence-1)
[8](#cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23878)
*Preconditions*:
- [(8.1)](#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)](#cons-8.2)
other.required_span_size() is representable as
a value of type index_type[.](#cons-8.sentence-1)
[9](#cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23895)
*Effects*: Equivalent to mapping(other.extents())[.](#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](#cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23908)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-10.sentence-1)
[11](#cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23912)
*Preconditions*:
- [(11.1)](#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)](#cons-11.2)
If *rank_* is greater than 0,
then other.stride(*rank_* - 1) equals 1[.](#cons-11.2.sentence-1)
- [(11.3)](#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)](#cons-11.4)
other.required_span_size() is representable as
a value of type index_type[.](#cons-11.4.sentence-1)
[12](#cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23939)
*Effects*:
- [(12.1)](#cons-12.1)
Direct-non-list-initializes *extents_* with other.extents(); and
- [(12.2)](#cons-12.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2* with other.stride(*rank_* - 2)[.](#cons-12.sentence-1)
[🔗](#lib:layout_right_padded::mapping,constructor____)
`template<class LayoutRightPaddedMapping>
constexpr explicit(see below)
mapping(const LayoutRightPaddedMapping& other);
`
[13](#cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23959)
*Constraints*:
- [(13.1)](#cons-13.1)
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#cons-13.1.sentence-1)
- [(13.2)](#cons-13.2)
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
type> is true[.](#cons-13.2.sentence-1)
[14](#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[.](#cons-14.sentence-1)
[15](#cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23980)
*Preconditions*:
- [(15.1)](#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)](#cons-15.2)
other.required_span_size() is representable as
a value of type index_type[.](#cons-15.sentence-1)
[16](#cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23996)
*Effects*:
- [(16.1)](#cons-16.1)
Direct-non-list-initializes *extents_* with other.extents(); and
- [(16.2)](#cons-16.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2* with other.stride(rank_ - 2)[.](#cons-16.sentence-1)
[17](#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](#cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24025)
*Constraints*:
- [(18.1)](#cons-18.1)
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true or
*is-mapping-of*<layout_left, LayoutLeftPaddedMapping> is true[.](#cons-18.1.sentence-1)
- [(18.2)](#cons-18.2)
*rank_* equals zero or one[.](#cons-18.2.sentence-1)
- [(18.3)](#cons-18.3)
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
is true[.](#cons-18.3.sentence-1)
[19](#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[.](#cons-19.sentence-1)
[20](#cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24045)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-20.sentence-1)
[21](#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](#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[.](#cons-21.sentence-1)
— *end note*]
#### [23.7.3.4.9.4](#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](#obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24070)
*Returns*: array<index_type, *rank_*>(stride(P_rank)...)[.](#obs-1.sentence-1)
[🔗](#lib:layout_right_padded::mapping,required_span_size)
`constexpr index_type required_span_size() const noexcept;
`
[2](#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[.](#obs-2.sentence-1)
[🔗](#lib:layout_right_padded::mapping,operator())
`template<class... Indices>
constexpr size_t operator()(Indices... idxs) const noexcept;
`
[3](#obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24094)
*Constraints*:
- [(3.1)](#obs-3.1)
sizeof...(Indices) == *rank_* is true[.](#obs-3.1.sentence-1)
- [(3.2)](#obs-3.2)
(is_convertible_v<Indices, index_type> && ...) is true[.](#obs-3.2.sentence-1)
- [(3.3)](#obs-3.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#obs-3.3.sentence-1)
[4](#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.1Overview"))[.](#obs-4.sentence-1)
[5](#obs-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24110)
*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#obs-5.sentence-1)
[🔗](#lib:layout_right_padded::mapping,is_always_exhaustive)
`static constexpr bool is_always_exhaustive() noexcept;
`
[6](#obs-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24121)
*Returns*:
- [(6.1)](#obs-6.1)
If *rank_* equals zero or one, then true;
- [(6.2)](#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)](#obs-6.3)
otherwise, false[.](#obs-6.sentence-1)
[🔗](#lib:layout_right_padded::mapping,is_exhaustive)
`constexpr bool is_exhaustive() const noexcept;
`
[7](#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)
[🔗](#obs-itemdecl:6)
`constexpr index_type stride(rank_type r) const noexcept;
`
[8](#obs-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24156)
*Preconditions*: r is smaller than *rank_*[.](#obs-8.sentence-1)
[9](#obs-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24160)
*Returns*:
- [(9.1)](#obs-9.1)
If r equals *rank_* - 1: 1;
- [(9.2)](#obs-9.2)
otherwise, if r equals *rank_* - 2: *stride-rm2*;
- [(9.3)](#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)[.](#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](#obs-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24182)
*Constraints*:
- [(10.1)](#obs-10.1)
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#obs-10.1.sentence-1)
- [(10.2)](#obs-10.2)
LayoutRightPaddedMapping::extents_type::rank() == *rank_* is true[.](#obs-10.2.sentence-1)
[11](#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[.](#obs-11.sentence-1)
Otherwise, false[.](#obs-11.sentence-2)

View File

@@ -0,0 +1,337 @@
[mdspan.layout.rightpad.cons]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.rightpad.cons)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad.cons)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad.cons)
#### 23.7.3.4.9 Class template layout_right_padded::mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad#cons)
#### 23.7.3.4.9.3 Constructors [mdspan.layout.rightpad.cons]
[🔗](#lib:layout_right_padded::mapping,constructor)
`constexpr mapping(const extents_type& ext);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23769)
*Preconditions*:
- [(1.1)](#1.1)
The size of the multidimensional index space ext is representable as a value of type index_type[.](#1.1.sentence-1)
- [(1.2)](#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*[.](#1.2.sentence-1)
- [(1.3)](#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[.](#1.3.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23790)
*Effects*:
- [(2.1)](#2.1)
Direct-non-list-initializes *extents_* with ext; and
- [(2.2)](#2.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2*
* [(2.2.1)](#2.2.1)
with ext.extent(*rank_* - 1) if padding_value is dynamic_extent,
* [(2.2.2)](#2.2.2)
otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1))[.](#2.sentence-1)
[🔗](#lib:layout_right_padded::mapping,constructor_)
`template<class OtherIndexType>
constexpr mapping(const extents_type& ext, OtherIndexType pad);
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23816)
*Constraints*:
- [(3.1)](#3.1)
is_convertible_v<OtherIndexType, index_type> is true[.](#3.1.sentence-1)
- [(3.2)](#3.2)
is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#3.2.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23825)
*Preconditions*:
- [(4.1)](#4.1)
pad is representable as a value of type index_type[.](#4.1.sentence-1)
- [(4.2)](#4.2)
extents_type::*index-cast*(pad) is greater than zero[.](#4.2.sentence-1)
- [(4.3)](#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[.](#4.3.sentence-1)
- [(4.4)](#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[.](#4.4.sentence-1)
- [(4.5)](#4.5)
If padding_value is not equal to dynamic_extent,padding_value equals extents_type::*index-cast*(pad)[.](#4.5.sentence-1)
[5](#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))[.](#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](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23864)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#6.sentence-1)
[7](#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[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23878)
*Preconditions*:
- [(8.1)](#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)](#8.2)
other.required_span_size() is representable as
a value of type index_type[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23895)
*Effects*: Equivalent to mapping(other.extents())[.](#9.sentence-1)
[🔗](#lib:layout_right_padded::mapping,constructor___)
`template<class OtherExtents>
constexpr explicit(rank_ > 0)
mapping(const layout_stride::mapping<OtherExtents>& other);
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23908)
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23912)
*Preconditions*:
- [(11.1)](#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)](#11.2)
If *rank_* is greater than 0,
then other.stride(*rank_* - 1) equals 1[.](#11.2.sentence-1)
- [(11.3)](#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)](#11.4)
other.required_span_size() is representable as
a value of type index_type[.](#11.4.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23939)
*Effects*:
- [(12.1)](#12.1)
Direct-non-list-initializes *extents_* with other.extents(); and
- [(12.2)](#12.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2* with other.stride(*rank_* - 2)[.](#12.sentence-1)
[🔗](#lib:layout_right_padded::mapping,constructor____)
`template<class LayoutRightPaddedMapping>
constexpr explicit(see below)
mapping(const LayoutRightPaddedMapping& other);
`
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23959)
*Constraints*:
- [(13.1)](#13.1)
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#13.1.sentence-1)
- [(13.2)](#13.2)
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
type> is true[.](#13.2.sentence-1)
[14](#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[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23980)
*Preconditions*:
- [(15.1)](#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)](#15.2)
other.required_span_size() is representable as
a value of type index_type[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23996)
*Effects*:
- [(16.1)](#16.1)
Direct-non-list-initializes *extents_* with other.extents(); and
- [(16.2)](#16.2)
if *rank_* is greater than one,
direct-non-list-initializes *stride-rm2* with other.stride(rank_ - 2)[.](#16.sentence-1)
[17](#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](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24025)
*Constraints*:
- [(18.1)](#18.1)
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true or
*is-mapping-of*<layout_left, LayoutLeftPaddedMapping> is true[.](#18.1.sentence-1)
- [(18.2)](#18.2)
*rank_* equals zero or one[.](#18.2.sentence-1)
- [(18.3)](#18.3)
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
is true[.](#18.3.sentence-1)
[19](#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[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24045)
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#20.sentence-1)
[21](#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](#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[.](#21.sentence-1)
— *end note*]

View File

@@ -0,0 +1,55 @@
[mdspan.layout.rightpad.expo]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.rightpad.expo)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad.expo)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad.expo)
#### 23.7.3.4.9 Class template layout_right_padded::mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad#expo)
#### 23.7.3.4.9.2 Exposition-only members [mdspan.layout.rightpad.expo]
[🔗](#itemdecl:1)
`static constexpr size_t static-padding-stride = see below;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23730)
The value is
- [(1.1)](#1.1)
0, if *rank_* equals zero or one;
- [(1.2)](#1.2)
otherwise, dynamic_extent,
if padding_value or *last-static-extent* equalsdynamic_extent;
- [(1.3)](#1.3)
otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *last-static-extent*)[.](#1.sentence-1)
[🔗](#itemdecl:2)
`index_type stride-rm2 = static-padding-stride;
`
[2](#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[.](#2.sentence-1)
[*Note [1](#note-1)*:
Using extents<index_type, *static-padding-stride*> instead of index_type as the type of *stride-rm2* would achieve this[.](#2.sentence-2)
— *end note*]

View File

@@ -0,0 +1,169 @@
[mdspan.layout.rightpad.obs]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.rightpad.obs)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad.obs)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad.obs)
#### 23.7.3.4.9 Class template layout_right_padded::mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad#obs)
#### 23.7.3.4.9.4 Observers [mdspan.layout.rightpad.obs]
[🔗](#lib:layout_right_padded::mapping,strides)
`constexpr array<index_type, rank_> strides() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24070)
*Returns*: array<index_type, *rank_*>(stride(P_rank)...)[.](#1.sentence-1)
[🔗](#lib:layout_right_padded::mapping,required_span_size)
`constexpr index_type required_span_size() const noexcept;
`
[2](#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[.](#2.sentence-1)
[🔗](#lib:layout_right_padded::mapping,operator())
`template<class... Indices>
constexpr size_t operator()(Indices... idxs) const noexcept;
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24094)
*Constraints*:
- [(3.1)](#3.1)
sizeof...(Indices) == *rank_* is true[.](#3.1.sentence-1)
- [(3.2)](#3.2)
(is_convertible_v<Indices, index_type> && ...) is true[.](#3.2.sentence-1)
- [(3.3)](#3.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#3.3.sentence-1)
[4](#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.1Overview"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24110)
*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#5.sentence-1)
[🔗](#lib:layout_right_padded::mapping,is_always_exhaustive)
`static constexpr bool is_always_exhaustive() noexcept;
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24121)
*Returns*:
- [(6.1)](#6.1)
If *rank_* equals zero or one, then true;
- [(6.2)](#6.2)
otherwise,
if neither *static-padding-stride* nor *last-static-extent* equal dynamic_extent,
then *static-padding-stride* == *last-static-extent*;
- [(6.3)](#6.3)
otherwise, false[.](#6.sentence-1)
[🔗](#lib:layout_right_padded::mapping,is_exhaustive)
`constexpr bool is_exhaustive() const noexcept;
`
[7](#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)
[🔗](#itemdecl:6)
`constexpr index_type stride(rank_type r) const noexcept;
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24156)
*Preconditions*: r is smaller than *rank_*[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24160)
*Returns*:
- [(9.1)](#9.1)
If r equals *rank_* - 1: 1;
- [(9.2)](#9.2)
otherwise, if r equals *rank_* - 2: *stride-rm2*;
- [(9.3)](#9.3)
otherwise,
the product of *stride-rm2* and
all values extents_.extent(k) with k in the range of [r + 1, *rank_* - 1)[.](#9.sentence-1)
[🔗](#lib:layout_right_padded::mapping,operator==)
`template<class LayoutRightPaddedMapping>
friend constexpr bool operator==(const mapping& x, const LayoutRightPaddedMapping& y) noexcept;
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24182)
*Constraints*:
- [(10.1)](#10.1)
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#10.1.sentence-1)
- [(10.2)](#10.2)
LayoutRightPaddedMapping::extents_type::rank() == *rank_* is true[.](#10.2.sentence-1)
[11](#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[.](#11.sentence-1)
Otherwise, false[.](#11.sentence-2)

View File

@@ -0,0 +1,110 @@
[mdspan.layout.rightpad.overview]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.rightpad.overview)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad.overview)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad.overview)
#### 23.7.3.4.9 Class template layout_right_padded::mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad#overview)
#### 23.7.3.4.9.1 Overview [mdspan.layout.rightpad.overview]
[1](#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)[.](#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]](mdspan.layout.rightpad.expo "23.7.3.4.9.2Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.rightpad.cons]](mdspan.layout.rightpad.cons "23.7.3.4.9.3Constructors"), 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]](mdspan.layout.rightpad.obs "23.7.3.4.9.4Observers"), 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]](mdspan.layout.rightpad.expo "23.7.3.4.9.2Exposition-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.6Specializations 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](#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[.](#2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23669)
Throughout [[mdspan.layout.rightpad]](mdspan.layout.rightpad "23.7.3.4.9Class template layout_­right_­padded::mapping"),
let P_rank be the following
size *rank_* parameter pack of size_t values:
- [(4.1)](#4.1)
the empty parameter pack, if *rank_* equals zero;
- [(4.2)](#4.2)
otherwise, 0zu, if *rank_* equals one;
- [(4.3)](#4.3)
otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23682)
*Mandates*:
- [(5.1)](#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[.](#5.1.sentence-1)
- [(5.2)](#5.2)
padding_value is representable as a value of type index_type[.](#5.2.sentence-1)
- [(5.3)](#5.3)
If
* [(5.3.1)](#5.3.1)
*rank_* is greater than one,
* [(5.3.2)](#5.3.2)
padding_value does not equal dynamic_extent, and
* [(5.3.3)](#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[.](#5.3.sentence-1)
- [(5.4)](#5.4)
If
* [(5.4.1)](#5.4.1)
*rank_* is greater than one,
* [(5.4.2)](#5.4.2)
padding_value does not equal dynamic_extent, and
* [(5.4.3)](#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[.](#5.4.sentence-1)

View File

@@ -0,0 +1,369 @@
[mdspan.layout.stride]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.stride)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride)
#### 23.7.3.4.7 Class template layout_stride::mapping [mdspan.layout.stride]
#### [23.7.3.4.7.1](#overview) Overview [[mdspan.layout.stride.overview]](mdspan.layout.stride.overview)
[1](#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[.](#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]](#cons "23.7.3.4.7.3Constructors"), 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]](#obs "23.7.3.4.7.4Observers"), 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.6Specializations 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](#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[.](#overview-2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#overview-3.sentence-1)
[4](#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[.](#overview-4.sentence-1)
#### [23.7.3.4.7.2](#expo) Exposition-only helpers [[mdspan.layout.stride.expo]](mdspan.layout.stride.expo)
[1](#expo-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22652)
Let *REQUIRED-SPAN-SIZE*(e, strides) be:
- [(1.1)](#expo-1.1)
1, if e.rank() == 0 is true,
- [(1.2)](#expo-1.2)
otherwise 0, if the size of the multidimensional index space e is 0,
- [(1.3)](#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())[.](#expo-1.sentence-1)
[2](#expo-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22668)
Let *OFFSET*(m) be:
- [(2.1)](#expo-2.1)
m(), if e.rank() == 0 is true,
- [(2.2)](#expo-2.2)
otherwise 0, if the size of the multidimensional index space e is 0,
- [(2.3)](#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[.](#expo-2.sentence-1)
[3](#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](#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.2Exposition-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.2Exposition-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.2Concept same_­as[concept.same]")<bool>; { M::is_always_exhaustive() } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<bool>; { M::is_always_unique() } -> [same_as](concept.same#concept:same_as "18.4.2Concept 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](#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[.](#expo-4.sentence-1)
— *end note*]
#### [23.7.3.4.7.3](#cons) Constructors [[mdspan.layout.stride.cons]](mdspan.layout.stride.cons)
[🔗](#lib:layout_stride::mapping,constructor)
`constexpr mapping() noexcept;
`
[1](#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.2Fundamental types"))[.](#cons-1.sentence-1)
[2](#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)[.](#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](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22745)
*Constraints*:
- [(3.1)](#cons-3.1)
is_convertible_v<const OtherIndexType&, index_type> is true, and
- [(3.2)](#cons-3.2)
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#cons-3.sentence-1)
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22754)
*Preconditions*:
- [(4.1)](#cons-4.1)
The result of converting s[i] to index_type is greater than 0 for all i in the range [0, *rank_*)[.](#cons-4.1.sentence-1)
- [(4.2)](#cons-4.2)
*REQUIRED-SPAN-SIZE*(e, s) is representable
as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#cons-4.2.sentence-1)
- [(4.3)](#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[.](#cons-4.3.sentence-1)
[*Note [1](#cons-note-1)*:
For layout_stride,
this condition is necessary and sufficient
for is_unique() to be true[.](#cons-4.3.sentence-2)
— *end note*]
[5](#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])[.](#cons-5.sentence-1)
[🔗](#lib:layout_stride::mapping,constructor__)
`template<class StridedLayoutMapping>
constexpr explicit(see below)
mapping(const StridedLayoutMapping& other) noexcept;
`
[6](#cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22793)
*Constraints*:
- [(6.1)](#cons-6.1)
[*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2Exposition-only helpers[mdspan.layout.stride.expo]")<StridedLayoutMapping> is satisfied[.](#cons-6.1.sentence-1)
- [(6.2)](#cons-6.2)
is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type> is
true[.](#cons-6.2.sentence-2)
- [(6.3)](#cons-6.3)
StridedLayoutMapping::is_always_unique() is true[.](#cons-6.3.sentence-1)
- [(6.4)](#cons-6.4)
StridedLayoutMapping::is_always_strided() is true[.](#cons-6.4.sentence-1)
[7](#cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22806)
*Preconditions*:
- [(7.1)](#cons-7.1)
StridedLayoutMapping meets the layout mapping requirements ([[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2Requirements")),
- [(7.2)](#cons-7.2)
other.stride(r) > 0 is true for every rank index r of extents(),
- [(7.3)](#cons-7.3)
other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types")), and
- [(7.4)](#cons-7.4)
*OFFSET*(other) == 0 is true[.](#cons-7.sentence-1)
[8](#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)[.](#cons-8.sentence-1)
[9](#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](#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](#obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22848)
*Returns*: *REQUIRED-SPAN-SIZE*(extents(), *strides_*)[.](#obs-1.sentence-1)
[🔗](#lib:operator(),layout_stride::mapping)
`template<class... Indices>
constexpr index_type operator()(Indices... i) const noexcept;
`
[2](#obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22860)
*Constraints*:
- [(2.1)](#obs-2.1)
sizeof...(Indices) == *rank_* is true,
- [(2.2)](#obs-2.2)
(is_convertible_v<Indices, index_type> && ...) is true, and
- [(2.3)](#obs-2.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#obs-2.sentence-1)
[3](#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.1Overview"))[.](#obs-3.sentence-1)
[4](#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[.](#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](#obs-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22895)
*Returns*:
- [(5.1)](#obs-5.1)
true if *rank_* is 0[.](#obs-5.1.sentence-1)
- [(5.2)](#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[.](#obs-5.2.sentence-1)
- [(5.3)](#obs-5.3)
Otherwise, false[.](#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](#obs-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22919)
*Constraints*:
- [(6.1)](#obs-6.1)
[*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2Exposition-only helpers[mdspan.layout.stride.expo]")<OtherMapping> is satisfied[.](#obs-6.1.sentence-1)
- [(6.2)](#obs-6.2)
*rank_* == OtherMapping::extents_type::rank() is true[.](#obs-6.2.sentence-1)
- [(6.3)](#obs-6.3)
OtherMapping::is_always_strided() is true[.](#obs-6.3.sentence-1)
[7](#obs-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22930)
*Preconditions*: OtherMapping meets the layout mapping requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3Layout mapping policy requirements"))[.](#obs-7.sentence-1)
[8](#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())[.](#obs-8.sentence-1)
Otherwise, false[.](#obs-8.sentence-2)

View File

@@ -0,0 +1,157 @@
[mdspan.layout.stride.cons]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.stride.cons)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride.cons)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride.cons)
#### 23.7.3.4.7 Class template layout_stride::mapping [[mdspan.layout.stride]](mdspan.layout.stride#cons)
#### 23.7.3.4.7.3 Constructors [mdspan.layout.stride.cons]
[🔗](#lib:layout_stride::mapping,constructor)
`constexpr mapping() noexcept;
`
[1](#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.2Fundamental types"))[.](#1.sentence-1)
[2](#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)[.](#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](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22745)
*Constraints*:
- [(3.1)](#3.1)
is_convertible_v<const OtherIndexType&, index_type> is true, and
- [(3.2)](#3.2)
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22754)
*Preconditions*:
- [(4.1)](#4.1)
The result of converting s[i] to index_type is greater than 0 for all i in the range [0, *rank_*)[.](#4.1.sentence-1)
- [(4.2)](#4.2)
*REQUIRED-SPAN-SIZE*(e, s) is representable
as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#4.2.sentence-1)
- [(4.3)](#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[.](#4.3.sentence-1)
[*Note [1](#note-1)*:
For layout_stride,
this condition is necessary and sufficient
for is_unique() to be true[.](#4.3.sentence-2)
— *end note*]
[5](#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])[.](#5.sentence-1)
[🔗](#lib:layout_stride::mapping,constructor__)
`template<class StridedLayoutMapping>
constexpr explicit(see below)
mapping(const StridedLayoutMapping& other) noexcept;
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22793)
*Constraints*:
- [(6.1)](#6.1)
[*layout-mapping-alike*](mdspan.layout.stride.expo#concept:layout-mapping-alike "23.7.3.4.7.2Exposition-only helpers[mdspan.layout.stride.expo]")<StridedLayoutMapping> is satisfied[.](#6.1.sentence-1)
- [(6.2)](#6.2)
is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type> is
true[.](#6.2.sentence-2)
- [(6.3)](#6.3)
StridedLayoutMapping::is_always_unique() is true[.](#6.3.sentence-1)
- [(6.4)](#6.4)
StridedLayoutMapping::is_always_strided() is true[.](#6.4.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22806)
*Preconditions*:
- [(7.1)](#7.1)
StridedLayoutMapping meets the layout mapping requirements ([[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2Requirements")),
- [(7.2)](#7.2)
other.stride(r) > 0 is true for every rank index r of extents(),
- [(7.3)](#7.3)
other.required_span_size() is representable as
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types")), and
- [(7.4)](#7.4)
*OFFSET*(other) == 0 is true[.](#7.sentence-1)
[8](#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)[.](#8.sentence-1)
[9](#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>))

View File

@@ -0,0 +1,75 @@
[mdspan.layout.stride.expo]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.stride.expo)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride.expo)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride.expo)
#### 23.7.3.4.7 Class template layout_stride::mapping [[mdspan.layout.stride]](mdspan.layout.stride#expo)
#### 23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22652)
Let *REQUIRED-SPAN-SIZE*(e, strides) be:
- [(1.1)](#1.1)
1, if e.rank() == 0 is true,
- [(1.2)](#1.2)
otherwise 0, if the size of the multidimensional index space e is 0,
- [(1.3)](#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())[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22668)
Let *OFFSET*(m) be:
- [(2.1)](#2.1)
m(), if e.rank() == 0 is true,
- [(2.2)](#2.2)
otherwise 0, if the size of the multidimensional index space e is 0,
- [(2.3)](#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[.](#2.sentence-1)
[3](#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](#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.2Exposition-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.2Exposition-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.2Concept same_­as[concept.same]")<bool>; { M::is_always_exhaustive() } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<bool>; { M::is_always_unique() } -> [same_as](concept.same#concept:same_as "18.4.2Concept 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](#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[.](#4.sentence-1)
— *end note*]

View File

@@ -0,0 +1,127 @@
[mdspan.layout.stride.obs]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.stride.obs)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride.obs)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride.obs)
#### 23.7.3.4.7 Class template layout_stride::mapping [[mdspan.layout.stride]](mdspan.layout.stride#obs)
#### 23.7.3.4.7.4 Observers [mdspan.layout.stride.obs]
[🔗](#lib:required_span_size,layout_stride::mapping)
`constexpr index_type required_span_size() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22848)
*Returns*: *REQUIRED-SPAN-SIZE*(extents(), *strides_*)[.](#1.sentence-1)
[🔗](#lib:operator(),layout_stride::mapping)
`template<class... Indices>
constexpr index_type operator()(Indices... i) const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22860)
*Constraints*:
- [(2.1)](#2.1)
sizeof...(Indices) == *rank_* is true,
- [(2.2)](#2.2)
(is_convertible_v<Indices, index_type> && ...) is true, and
- [(2.3)](#2.3)
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#2.sentence-1)
[3](#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.1Overview"))[.](#3.sentence-1)
[4](#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[.](#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](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22895)
*Returns*:
- [(5.1)](#5.1)
true if *rank_* is 0[.](#5.1.sentence-1)
- [(5.2)](#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[.](#5.2.sentence-1)
- [(5.3)](#5.3)
Otherwise, false[.](#5.3.sentence-1)
[🔗](#lib:operator==,layout_stride::mapping)
`template<class OtherMapping>
friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept;
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22919)
*Constraints*:
- [(6.1)](#6.1)
[*layout-mapping-alike*](mdspan.layout.stride.expo#concept:layout-mapping-alike "23.7.3.4.7.2Exposition-only helpers[mdspan.layout.stride.expo]")<OtherMapping> is satisfied[.](#6.1.sentence-1)
- [(6.2)](#6.2)
*rank_* == OtherMapping::extents_type::rank() is true[.](#6.2.sentence-1)
- [(6.3)](#6.3)
OtherMapping::is_always_strided() is true[.](#6.3.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22930)
*Preconditions*: OtherMapping meets the layout mapping requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3Layout mapping policy requirements"))[.](#7.sentence-1)
[8](#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())[.](#8.sentence-1)
Otherwise, false[.](#8.sentence-2)

View File

@@ -0,0 +1,43 @@
[mdspan.layout.stride.overview]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.layout.stride.overview)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride.overview)
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride.overview)
#### 23.7.3.4.7 Class template layout_stride::mapping [[mdspan.layout.stride]](mdspan.layout.stride#overview)
#### 23.7.3.4.7.1 Overview [mdspan.layout.stride.overview]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22564)
layout_stride provides a layout mapping
where the strides are user-defined[.](#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]](mdspan.layout.stride.cons "23.7.3.4.7.3Constructors"), 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]](mdspan.layout.stride.obs "23.7.3.4.7.4Observers"), 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.6Specializations 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](#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[.](#2.sentence-1)
[3](#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.6Object concepts[concepts.object]") for each E[.](#3.sentence-1)
[4](#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[.](#4.sentence-1)