From Jason Turner

[views.multidim]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpr_27_uu6/{from.md → to.md} +2029 -0
tmp/tmpr_27_uu6/{from.md → to.md} RENAMED
@@ -0,0 +1,2029 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Multidimensional access <a id="views.multidim">[[views.multidim]]</a>
2
+
3
+ #### Overview <a id="mdspan.overview">[[mdspan.overview]]</a>
4
+
5
+ A *multidimensional index space* is a Cartesian product of integer
6
+ intervals. Each interval can be represented by a half-open range
7
+ [Lᵢ, Uᵢ), where Lᵢ and Uᵢ are the lower and upper bounds of the iᵗʰ
8
+ dimension. The *rank* of a multidimensional index space is the number of
9
+ intervals it represents. The *size of a multidimensional index space* is
10
+ the product of Uᵢ - Lᵢ for each dimension i if its rank is greater than
11
+ 0, and 1 otherwise.
12
+
13
+ An integer r is a *rank index* of an index space S if r is in the range
14
+ [0, rank of $S$).
15
+
16
+ A pack of integers `idx` is a *multidimensional index* in a
17
+ multidimensional index space S (or representation thereof) if both of
18
+ the following are true:
19
+
20
+ - `sizeof...(idx)` is equal to the rank of S, and
21
+ - for every rank index i of S, the iᵗʰ value of `idx` is an integer in
22
+ the interval [Lᵢ, Uᵢ) of S.
23
+
24
+ #### Header `<mdspan>` synopsis <a id="mdspan.syn">[[mdspan.syn]]</a>
25
+
26
+ ``` cpp
27
+ namespace std {
28
+ // [mdspan.extents], class template extents
29
+ template<class IndexType, size_t... Extents>
30
+ class extents;
31
+
32
+ // [mdspan.extents.dextents], alias template dextents
33
+ template<class IndexType, size_t Rank>
34
+ using dextents = see below;
35
+
36
+ // [mdspan.layout], layout mapping
37
+ struct layout_left;
38
+ struct layout_right;
39
+ struct layout_stride;
40
+
41
+ // [mdspan.accessor.default], class template default_accessor
42
+ template<class ElementType>
43
+ class default_accessor;
44
+
45
+ // [mdspan.mdspan], class template mdspan
46
+ template<class ElementType, class Extents, class LayoutPolicy = layout_right,
47
+ class AccessorPolicy = default_accessor<ElementType>>
48
+ class mdspan;
49
+ }
50
+ ```
51
+
52
+ #### Class template `extents` <a id="mdspan.extents">[[mdspan.extents]]</a>
53
+
54
+ ##### Overview <a id="mdspan.extents.overview">[[mdspan.extents.overview]]</a>
55
+
56
+ The class template `extents` represents a multidimensional index space
57
+ of rank equal to `sizeof...(Extents)`. In subclause [[views]], `extents`
58
+ is used synonymously with multidimensional index space.
59
+
60
+ ``` cpp
61
+ namespace std {
62
+ template<class IndexType, size_t... Extents>
63
+ class extents {
64
+ public:
65
+ using index_type = IndexType;
66
+ using size_type = make_unsigned_t<index_type>;
67
+ using rank_type = size_t;
68
+
69
+ // [mdspan.extents.obs], observers of the multidimensional index space
70
+ static constexpr rank_type rank() noexcept { return sizeof...(Extents); }
71
+ static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
72
+ static constexpr size_t static_extent(rank_type) noexcept;
73
+ constexpr index_type extent(rank_type) const noexcept;
74
+
75
+ // [mdspan.extents.cons], constructors
76
+ constexpr extents() noexcept = default;
77
+
78
+ template<class OtherIndexType, size_t... OtherExtents>
79
+ constexpr explicit(see below)
80
+ extents(const extents<OtherIndexType, OtherExtents...>&) noexcept;
81
+ template<class... OtherIndexTypes>
82
+ constexpr explicit extents(OtherIndexTypes...) noexcept;
83
+ template<class OtherIndexType, size_t N>
84
+ constexpr explicit(N != rank_dynamic())
85
+ extents(span<OtherIndexType, N>) noexcept;
86
+ template<class OtherIndexType, size_t N>
87
+ constexpr explicit(N != rank_dynamic())
88
+ extents(const array<OtherIndexType, N>&) noexcept;
89
+
90
+ // [mdspan.extents.cmp], comparison operators
91
+ template<class OtherIndexType, size_t... OtherExtents>
92
+ friend constexpr bool operator==(const extents&,
93
+ const extents<OtherIndexType, OtherExtents...>&) noexcept;
94
+
95
+ // [mdspan.extents.expo], exposition-only helpers
96
+ constexpr size_t fwd-prod-of-extents(rank_type) const noexcept; // exposition only
97
+ constexpr size_t rev-prod-of-extents(rank_type) const noexcept; // exposition only
98
+ template<class OtherIndexType>
99
+ static constexpr auto index-cast(OtherIndexType&&) noexcept; // exposition only
100
+
101
+ private:
102
+ static constexpr rank_type dynamic-index(rank_type) noexcept; // exposition only
103
+ static constexpr rank_type dynamic-index-inv(rank_type) noexcept; // exposition only
104
+ array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only
105
+ };
106
+
107
+ template<class... Integrals>
108
+ explicit extents(Integrals...)
109
+ -> see below;
110
+ }
111
+ ```
112
+
113
+ *Mandates:*
114
+
115
+ - `IndexType` is a signed or unsigned integer type, and
116
+ - each element of `Extents` is either equal to `dynamic_extent`, or is
117
+ representable as a value of type `IndexType`.
118
+
119
+ Each specialization of `extents` models `regular` and is trivially
120
+ copyable.
121
+
122
+ Let Eᵣ be the rᵗʰ element of `Extents`. Eᵣ is a *dynamic extent* if it
123
+ is equal to `dynamic_extent`, otherwise Eᵣ is a *static extent*. Let Dᵣ
124
+ be the value of `dynamic-extents[dynamic-index(r)]` if Eᵣ is a dynamic
125
+ extent, otherwise Eᵣ.
126
+
127
+ The rᵗʰ interval of the multidimensional index space represented by an
128
+ `extents` object is [0, Dᵣ).
129
+
130
+ ##### Exposition-only helpers <a id="mdspan.extents.expo">[[mdspan.extents.expo]]</a>
131
+
132
+ ``` cpp
133
+ static constexpr rank_type dynamic-index(rank_type i) noexcept;
134
+ ```
135
+
136
+ *Preconditions:* `i <= rank()` is `true`.
137
+
138
+ *Returns:* The number of Eᵣ with r < `i` for which Eᵣ is a dynamic
139
+ extent.
140
+
141
+ ``` cpp
142
+ static constexpr rank_type dynamic-index-inv(rank_type i) noexcept;
143
+ ```
144
+
145
+ *Preconditions:* `i < rank_dynamic()` is `true`.
146
+
147
+ *Returns:* The minimum value of r such that
148
+ *`dynamic-index`*`(`r` + 1) == i + 1` is `true`.
149
+
150
+ ``` cpp
151
+ constexpr size_t fwd-prod-of-extents(rank_type i) const noexcept;
152
+ ```
153
+
154
+ *Preconditions:* `i <= rank()` is `true`.
155
+
156
+ *Returns:* If `i > 0` is `true`, the product of `extent(`k`)` for all k
157
+ in the range [0, `i`), otherwise `1`.
158
+
159
+ ``` cpp
160
+ constexpr size_t rev-prod-of-extents(rank_type i) const noexcept;
161
+ ```
162
+
163
+ *Preconditions:* `i < rank()` is `true`.
164
+
165
+ *Returns:* If `i + 1 < rank()` is `true`, the product of `extent(`k`)`
166
+ for all k in the range [`i + 1`, `rank()`), otherwise `1`.
167
+
168
+ ``` cpp
169
+ template<class OtherIndexType>
170
+ static constexpr auto index-cast(OtherIndexType&& i) noexcept;
171
+ ```
172
+
173
+ *Effects:*
174
+
175
+ - If `OtherIndexType` is an integral type other than `bool`, then
176
+ equivalent to `return i;`,
177
+ - otherwise, equivalent to `return static_cast<index_type>(i);`.
178
+
179
+ [*Note 1*: This function will always return an integral type other than
180
+ `bool`. Since this function’s call sites are constrained on
181
+ convertibility of `OtherIndexType` to `index_type`, integer-class types
182
+ can use the `static_cast` branch without loss of
183
+ precision. — *end note*]
184
+
185
+ ##### Constructors <a id="mdspan.extents.cons">[[mdspan.extents.cons]]</a>
186
+
187
+ ``` cpp
188
+ template<class OtherIndexType, size_t... OtherExtents>
189
+ constexpr explicit(see below)
190
+ extents(const extents<OtherIndexType, OtherExtents...>& other) noexcept;
191
+ ```
192
+
193
+ *Constraints:*
194
+
195
+ - `sizeof...(OtherExtents) == rank()` is `true`.
196
+ - `((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents == Extents) && ...)`
197
+ is `true`.
198
+
199
+ *Preconditions:*
200
+
201
+ - `other.extent(`r`)` equals Eᵣ for each r for which Eᵣ is a static
202
+ extent, and
203
+ - either
204
+ - `sizeof...(OtherExtents)` is zero, or
205
+ - `other.extent(`r`)` is representable as a value of type `index_type`
206
+ for every rank index r of `other`.
207
+
208
+ *Ensures:* `*this == other` is `true`.
209
+
210
+ *Remarks:* The expression inside `explicit` is equivalent to:
211
+
212
+ ``` cpp
213
+ (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||
214
+ (numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
215
+ ```
216
+
217
+ ``` cpp
218
+ template<class... OtherIndexTypes>
219
+ constexpr explicit extents(OtherIndexTypes... exts) noexcept;
220
+ ```
221
+
222
+ Let `N` be `sizeof...(OtherIndexTypes)`, and let `exts_arr` be
223
+ `array<index_type, N>{static_cast<`
224
+ `index_type>(std::move(exts))...}`.
225
+
226
+ *Constraints:*
227
+
228
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
229
+ - `(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)` is
230
+ `true`, and
231
+ - `N == rank_dynamic() || N == rank()` is `true`. \[*Note 1*: One can
232
+ construct `extents` from just dynamic extents, which are all the
233
+ values getting stored, or from all the extents with a
234
+ precondition. — *end note*]
235
+
236
+ *Preconditions:*
237
+
238
+ - If `N != rank_dynamic()` is `true`, `exts_arr[`r`]` equals Eᵣ for each
239
+ r for which Eᵣ is a static extent, and
240
+ - either
241
+ - `sizeof...(exts) == 0` is `true`, or
242
+ - each element of `exts` is nonnegative and is representable as a
243
+ value of type `index_type`.
244
+
245
+ *Ensures:* `*this == extents(exts_arr)` is `true`.
246
+
247
+ ``` cpp
248
+ template<class OtherIndexType, size_t N>
249
+ constexpr explicit(N != rank_dynamic())
250
+ extents(span<OtherIndexType, N> exts) noexcept;
251
+ template<class OtherIndexType, size_t N>
252
+ constexpr explicit(N != rank_dynamic())
253
+ extents(const array<OtherIndexType, N>& exts) noexcept;
254
+ ```
255
+
256
+ *Constraints:*
257
+
258
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
259
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
260
+ `true`, and
261
+ - `N == rank_dynamic() || N == rank()` is `true`.
262
+
263
+ *Preconditions:*
264
+
265
+ - If `N != rank_dynamic()` is `true`, `exts[`r`]` equals Eᵣ for each r
266
+ for which Eᵣ is a static extent, and
267
+ - either
268
+ - `N` is zero, or
269
+ - `exts[`r`]` is nonnegative and is representable as a value of type
270
+ `index_type` for every rank index r.
271
+
272
+ *Effects:*
273
+
274
+ - If `N` equals `dynamic_rank()`, for all d in the range
275
+ [0, `rank_dynamic()`), direct-non-list-initializes
276
+ *`dynamic-extents`*`[`d`]` with `as_const(exts[`d`])`.
277
+ - Otherwise, for all d in the range [0, `rank_dynamic()`),
278
+ direct-non-list-initializes *`dynamic-extents`*`[`d`]` with
279
+ `as_const(exts[`*`dynamic-index-inv`*`(`d`)])`.
280
+
281
+ ``` cpp
282
+ template<class... Integrals>
283
+ explicit extents(Integrals...) -> see below;
284
+ ```
285
+
286
+ *Constraints:* `(is_convertible_v<Integrals, size_t> && ...)` is `true`.
287
+
288
+ *Remarks:* The deduced type is `dextents<size_t, sizeof...(Integrals)>`.
289
+
290
+ ##### Observers of the multidimensional index space <a id="mdspan.extents.obs">[[mdspan.extents.obs]]</a>
291
+
292
+ ``` cpp
293
+ static constexpr size_t static_extent(rank_type i) noexcept;
294
+ ```
295
+
296
+ *Preconditions:* `i < rank()` is `true`.
297
+
298
+ *Returns:* E_`i`.
299
+
300
+ ``` cpp
301
+ constexpr index_type extent(rank_type i) const noexcept;
302
+ ```
303
+
304
+ *Preconditions:* `i < rank()` is `true`.
305
+
306
+ *Returns:* D_`i`.
307
+
308
+ ##### Comparison operators <a id="mdspan.extents.cmp">[[mdspan.extents.cmp]]</a>
309
+
310
+ ``` cpp
311
+ template<class OtherIndexType, size_t... OtherExtents>
312
+ friend constexpr bool operator==(const extents& lhs,
313
+ const extents<OtherIndexType, OtherExtents...>& rhs) noexcept;
314
+ ```
315
+
316
+ *Returns:* `true` if `lhs.rank()` equals `rhs.rank()` and if
317
+ `lhs.extent(r)` equals `rhs.extent(r)` for every rank index `r` of
318
+ `rhs`, otherwise `false`.
319
+
320
+ ##### Alias template `dextents` <a id="mdspan.extents.dextents">[[mdspan.extents.dextents]]</a>
321
+
322
+ ``` cpp
323
+ template<class IndexType, size_t Rank>
324
+ using dextents = see below;
325
+ ```
326
+
327
+ *Result:* A type `E` that is a specialization of `extents` such that
328
+ `E::rank() == Rank && E::rank() == E::rank_dynamic()` is `true`, and
329
+ `E::index_type` denotes `IndexType`.
330
+
331
+ #### Layout mapping <a id="mdspan.layout">[[mdspan.layout]]</a>
332
+
333
+ ##### General <a id="mdspan.layout.general">[[mdspan.layout.general]]</a>
334
+
335
+ In subclauses [[mdspan.layout.reqmts]] and
336
+ [[mdspan.layout.policy.reqmts]]:
337
+
338
+ - `M` denotes a layout mapping class.
339
+ - `m` denotes a (possibly const) value of type `M`.
340
+ - `i` and `j` are packs of (possibly const) integers that are
341
+ multidimensional indices in `m.extents()` [[mdspan.overview]].
342
+ \[*Note 1*: The type of each element of the packs can be a different
343
+ integer type. — *end note*]
344
+ - `r` is a (possibly const) rank index of `typename M::extents_type`.
345
+ - `dᵣ` is a pack of (possibly const) integers for which
346
+ `sizeof...(dᵣ) == M::extents_type::rank()` is `true`, the rᵗʰ element
347
+ is equal to 1, and all other elements are equal to 0.
348
+
349
+ In subclauses [[mdspan.layout.reqmts]] through [[mdspan.layout.stride]],
350
+ let *`is-mapping-of`* be the exposition-only variable template defined
351
+ as follows:
352
+
353
+ ``` cpp
354
+ template<class Layout, class Mapping>
355
+ constexpr bool is-mapping-of = // exposition only
356
+ is_same_v<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>;
357
+ ```
358
+
359
+ ##### Requirements <a id="mdspan.layout.reqmts">[[mdspan.layout.reqmts]]</a>
360
+
361
+ A type `M` meets the *layout mapping* requirements if
362
+
363
+ - `M` models `copyable` and `equality_comparable`,
364
+ - `is_nothrow_move_constructible_v<M>` is `true`,
365
+ - `is_nothrow_move_assignable_v<M>` is `true`,
366
+ - `is_nothrow_swappable_v<M>` is `true`, and
367
+ - the following types and expressions are well-formed and have the
368
+ specified semantics.
369
+
370
+ ``` cpp
371
+ typename M::extents_type
372
+ ```
373
+
374
+ *Result:* A type that is a specialization of `extents`.
375
+
376
+ ``` cpp
377
+ typename M::index_type
378
+ ```
379
+
380
+ *Result:* `typename M::extents_type::index_type`.
381
+
382
+ ``` cpp
383
+ typename M::rank_type
384
+ ```
385
+
386
+ *Result:* `typename M::extents_type::rank_type`.
387
+
388
+ ``` cpp
389
+ typename M::layout_type
390
+ ```
391
+
392
+ *Result:* A type `MP` that meets the layout mapping policy
393
+ requirements [[mdspan.layout.policy.reqmts]] and for which
394
+ *`is-mapping-of`*`<MP, M>` is `true`.
395
+
396
+ ``` cpp
397
+ m.extents()
398
+ ```
399
+
400
+ *Result:* `const typename M::extents_type&`
401
+
402
+ ``` cpp
403
+ m(i...)
404
+ ```
405
+
406
+ *Result:* `typename M::index_type`
407
+
408
+ *Returns:* A nonnegative integer less than
409
+ `numeric_limits<typename M::index_type>::max()` and less than or equal
410
+ to `numeric_limits<size_t>::max()`.
411
+
412
+ ``` cpp
413
+ m(i...) == m(static_cast<typename M::index_type>(i)...)
414
+ ```
415
+
416
+ *Result:* `bool`
417
+
418
+ *Returns:* `true`
419
+
420
+ ``` cpp
421
+ m.required_span_size()
422
+ ```
423
+
424
+ *Result:* `typename M::index_type`
425
+
426
+ *Returns:* If the size of the multidimensional index space `m.extents()`
427
+ is 0, then `0`, else `1` plus the maximum value of `m(i...)` for all
428
+ `i`.
429
+
430
+ ``` cpp
431
+ m.is_unique()
432
+ ```
433
+
434
+ *Result:* `bool`
435
+
436
+ *Returns:* `true` only if for every `i` and `j` where `(i != j || ...)`
437
+ is `true`, `m(i...) != m(j...)` is `true`.
438
+
439
+ [*Note 1*: A mapping can return `false` even if the condition is met.
440
+ For certain layouts, it is possibly not feasible to determine
441
+ efficiently whether the layout is unique. — *end note*]
442
+
443
+ ``` cpp
444
+ m.is_exhaustive()
445
+ ```
446
+
447
+ *Result:* `bool`
448
+
449
+ *Returns:* `true` only if for all k in the range
450
+ [0, `m.required_span_size()`) there exists an `i` such that `m(i...)`
451
+ equals k.
452
+
453
+ [*Note 2*: A mapping can return `false` even if the condition is met.
454
+ For certain layouts, it is possibly not feasible to determine
455
+ efficiently whether the layout is exhaustive. — *end note*]
456
+
457
+ ``` cpp
458
+ m.is_strided()
459
+ ```
460
+
461
+ *Result:* `bool`
462
+
463
+ *Returns:* `true` only if for every rank index r of `m.extents()` there
464
+ exists an integer sᵣ such that, for all `i` where (`i`+dᵣ) is a
465
+ multidimensional index in `m.extents()` [[mdspan.overview]],
466
+ `m((i + `dᵣ`)...) - m(i...)` equals sᵣ.
467
+
468
+ [*Note 3*: This implies that for a strided layout
469
+ m(i₀, …, iₖ) = m(0, …, 0) + i₀ × s₀ + … + iₖ × sₖ. — *end note*]
470
+
471
+ [*Note 4*: A mapping can return `false` even if the condition is met.
472
+ For certain layouts, it is possibly not feasible to determine
473
+ efficiently whether the layout is strided. — *end note*]
474
+
475
+ ``` cpp
476
+ m.stride(r)
477
+ ```
478
+
479
+ *Preconditions:* `m.is_strided()` is `true`.
480
+
481
+ *Result:* `typename M::index_type`
482
+
483
+ *Returns:* sᵣ as defined in `m.is_strided()` above.
484
+
485
+ ``` cpp
486
+ M::is_always_unique()
487
+ ```
488
+
489
+ *Result:* A constant expression [[expr.const]] of type `bool`.
490
+
491
+ *Returns:* `true` only if `m.is_unique()` is `true` for all possible
492
+ objects `m` of type `M`.
493
+
494
+ [*Note 5*: A mapping can return `false` even if the above condition is
495
+ met. For certain layout mappings, it is possibly not feasible to
496
+ determine whether every instance is unique. — *end note*]
497
+
498
+ ``` cpp
499
+ M::is_always_exhaustive()
500
+ ```
501
+
502
+ *Result:* A constant expression [[expr.const]] of type `bool`.
503
+
504
+ *Returns:* `true` only if `m.is_exhaustive()` is `true` for all possible
505
+ objects `m` of type `M`.
506
+
507
+ [*Note 6*: A mapping can return `false` even if the above condition is
508
+ met. For certain layout mappings, it is possibly not feasible to
509
+ determine whether every instance is exhaustive. — *end note*]
510
+
511
+ ``` cpp
512
+ M::is_always_strided()
513
+ ```
514
+
515
+ *Result:* A constant expression [[expr.const]] of type `bool`.
516
+
517
+ *Returns:* `true` only if `m.is_strided()` is `true` for all possible
518
+ objects `m` of type `M`.
519
+
520
+ [*Note 7*: A mapping can return `false` even if the above condition is
521
+ met. For certain layout mappings, it is possibly not feasible to
522
+ determine whether every instance is strided. — *end note*]
523
+
524
+ ##### Layout mapping policy requirements <a id="mdspan.layout.policy.reqmts">[[mdspan.layout.policy.reqmts]]</a>
525
+
526
+ A type `MP` meets the *layout mapping policy* requirements if for a type
527
+ `E` that is a specialization of `extents`, `MP::mapping<E>` is valid and
528
+ denotes a type `X` that meets the layout mapping requirements
529
+ [[mdspan.layout.reqmts]], and for which the *qualified-id*
530
+ `X::layout_type` is valid and denotes the type `MP` and the
531
+ *qualified-id* `X::extents_type` denotes `E`.
532
+
533
+ ##### Layout mapping policies <a id="mdspan.layout.policy.overview">[[mdspan.layout.policy.overview]]</a>
534
+
535
+ ``` cpp
536
+ namespace std {
537
+ struct layout_left {
538
+ template<class Extents>
539
+ class mapping;
540
+ };
541
+ struct layout_right {
542
+ template<class Extents>
543
+ class mapping;
544
+ };
545
+ struct layout_stride {
546
+ template<class Extents>
547
+ class mapping;
548
+ };
549
+ }
550
+ ```
551
+
552
+ Each of `layout_left`, `layout_right`, and `layout_stride` meets the
553
+ layout mapping policy requirements and is a trivial type.
554
+
555
+ ##### Class template `layout_left::mapping` <a id="mdspan.layout.left">[[mdspan.layout.left]]</a>
556
+
557
+ ###### Overview <a id="mdspan.layout.left.overview">[[mdspan.layout.left.overview]]</a>
558
+
559
+ `layout_left` provides a layout mapping where the leftmost extent has
560
+ stride 1, and strides increase left-to-right as the product of extents.
561
+
562
+ ``` cpp
563
+ namespace std {
564
+ template<class Extents>
565
+ class layout_left::mapping {
566
+ public:
567
+ using extents_type = Extents;
568
+ using index_type = typename extents_type::index_type;
569
+ using size_type = typename extents_type::size_type;
570
+ using rank_type = typename extents_type::rank_type;
571
+ using layout_type = layout_left;
572
+
573
+ // [mdspan.layout.left.cons], constructors
574
+ constexpr mapping() noexcept = default;
575
+ constexpr mapping(const mapping&) noexcept = default;
576
+ constexpr mapping(const extents_type&) noexcept;
577
+ template<class OtherExtents>
578
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
579
+ mapping(const mapping<OtherExtents>&) noexcept;
580
+ template<class OtherExtents>
581
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
582
+ mapping(const layout_right::mapping<OtherExtents>&) noexcept;
583
+ template<class OtherExtents>
584
+ constexpr explicit(extents_type::rank() > 0)
585
+ mapping(const layout_stride::mapping<OtherExtents>&);
586
+
587
+ constexpr mapping& operator=(const mapping&) noexcept = default;
588
+
589
+ // [mdspan.layout.left.obs], observers
590
+ constexpr const extents_type& extents() const noexcept { return extents_; }
591
+
592
+ constexpr index_type required_span_size() const noexcept;
593
+
594
+ template<class... Indices>
595
+ constexpr index_type operator()(Indices...) const noexcept;
596
+
597
+ static constexpr bool is_always_unique() noexcept { return true; }
598
+ static constexpr bool is_always_exhaustive() noexcept { return true; }
599
+ static constexpr bool is_always_strided() noexcept { return true; }
600
+
601
+ static constexpr bool is_unique() noexcept { return true; }
602
+ static constexpr bool is_exhaustive() noexcept { return true; }
603
+ static constexpr bool is_strided() noexcept { return true; }
604
+
605
+ constexpr index_type stride(rank_type) const noexcept;
606
+
607
+ template<class OtherExtents>
608
+ friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
609
+
610
+ private:
611
+ extents_type extents_{}; // exposition only
612
+ };
613
+ }
614
+ ```
615
+
616
+ If `Extents` is not a specialization of `extents`, then the program is
617
+ ill-formed.
618
+
619
+ `layout_left::mapping<E>` is a trivially copyable type that models
620
+ `regular` for each `E`.
621
+
622
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
623
+ of the multidimensional index space `Extents()` is representable as a
624
+ value of type `typename Extents::index_type`.
625
+
626
+ ###### Constructors <a id="mdspan.layout.left.cons">[[mdspan.layout.left.cons]]</a>
627
+
628
+ ``` cpp
629
+ constexpr mapping(const extents_type& e) noexcept;
630
+ ```
631
+
632
+ *Preconditions:* The size of the multidimensional index space `e` is
633
+ representable as a value of type `index_type` [[basic.fundamental]].
634
+
635
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`.
636
+
637
+ ``` cpp
638
+ template<class OtherExtents>
639
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
640
+ mapping(const mapping<OtherExtents>& other) noexcept;
641
+ ```
642
+
643
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
644
+ `true`.
645
+
646
+ *Preconditions:* `other.required_span_size()` is representable as a
647
+ value of type `index_type` [[basic.fundamental]].
648
+
649
+ *Effects:* Direct-non-list-initializes *extents\_* with
650
+ `other.extents()`.
651
+
652
+ ``` cpp
653
+ template<class OtherExents>
654
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
655
+ mapping(const layout_right::mapping<OtherExtents>& other) noexcept;
656
+ ```
657
+
658
+ *Constraints:*
659
+
660
+ - `extents_type::rank() <= 1` is `true`, and
661
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
662
+
663
+ *Preconditions:* `other.required_span_size()` is representable as a
664
+ value of type `index_type` [[basic.fundamental]].
665
+
666
+ *Effects:* Direct-non-list-initializes *extents\_* with
667
+ `other.extents()`.
668
+
669
+ ``` cpp
670
+ template<class OtherExtents>
671
+ constexpr explicit(extents_type::rank() > 0)
672
+ mapping(const layout_stride::mapping<OtherExtents>& other);
673
+ ```
674
+
675
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
676
+ `true`.
677
+
678
+ *Preconditions:*
679
+
680
+ - If `extents_type::rank() > 0` is `true`, then for all r in the range
681
+ [0, `extents_type::rank()`), `other.stride(`r`)` equals
682
+ `other.extents().`*`fwd-prod-of-extents`*`(`r`)`, and
683
+ - `other.required_span_size()` is representable as a value of type
684
+ `index_type` [[basic.fundamental]].
685
+
686
+ *Effects:* Direct-non-list-initializes *extents\_* with
687
+ `other.extents()`.
688
+
689
+ ###### Observers <a id="mdspan.layout.left.obs">[[mdspan.layout.left.obs]]</a>
690
+
691
+ ``` cpp
692
+ constexpr index_type required_span_size() const noexcept;
693
+ ```
694
+
695
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(extents_type::rank())`.
696
+
697
+ ``` cpp
698
+ template<class... Indices>
699
+ constexpr index_type operator()(Indices... i) const noexcept;
700
+ ```
701
+
702
+ *Constraints:*
703
+
704
+ - `sizeof...(Indices) == extents_type::rank()` is `true`,
705
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
706
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
707
+
708
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
709
+ multidimensional index in *extents\_*[[mdspan.overview]].
710
+
711
+ *Effects:* Let `P` be a parameter pack such that
712
+
713
+ ``` cpp
714
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
715
+ ```
716
+
717
+ is `true`. Equivalent to:
718
+
719
+ ``` cpp
720
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
721
+ ```
722
+
723
+ ``` cpp
724
+ constexpr index_type stride(rank_type i) const;
725
+ ```
726
+
727
+ *Constraints:* `extents_type::rank() > 0` is `true`.
728
+
729
+ *Preconditions:* `i < extents_type::rank()` is `true`.
730
+
731
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(i)`.
732
+
733
+ ``` cpp
734
+ template<class OtherExtents>
735
+ friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
736
+ ```
737
+
738
+ *Constraints:* `extents_type::rank() == OtherExtents::rank()` is `true`.
739
+
740
+ *Effects:* Equivalent to: `return x.extents() == y.extents();`
741
+
742
+ ##### Class template `layout_right::mapping` <a id="mdspan.layout.right">[[mdspan.layout.right]]</a>
743
+
744
+ ###### Overview <a id="mdspan.layout.right.overview">[[mdspan.layout.right.overview]]</a>
745
+
746
+ `layout_right` provides a layout mapping where the rightmost extent is
747
+ stride 1, and strides increase right-to-left as the product of extents.
748
+
749
+ ``` cpp
750
+ namespace std {
751
+ template<class Extents>
752
+ class layout_right::mapping {
753
+ public:
754
+ using extents_type = Extents;
755
+ using index_type = typename extents_type::index_type;
756
+ using size_type = typename extents_type::size_type;
757
+ using rank_type = typename extents_type::rank_type;
758
+ using layout_type = layout_right;
759
+
760
+ // [mdspan.layout.right.cons], constructors
761
+ constexpr mapping() noexcept = default;
762
+ constexpr mapping(const mapping&) noexcept = default;
763
+ constexpr mapping(const extents_type&) noexcept;
764
+ template<class OtherExtents>
765
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
766
+ mapping(const mapping<OtherExtents>&) noexcept;
767
+ template<class OtherExtents>
768
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
769
+ mapping(const layout_left::mapping<OtherExtents>&) noexcept;
770
+ template<class OtherExtents>
771
+ constexpr explicit(extents_type::rank() > 0)
772
+ mapping(const layout_stride::mapping<OtherExtents>&) noexcept;
773
+
774
+ constexpr mapping& operator=(const mapping&) noexcept = default;
775
+
776
+ // [mdspan.layout.right.obs], observers
777
+ constexpr const extents_type& extents() const noexcept { return extents_; }
778
+
779
+ constexpr index_type required_span_size() const noexcept;
780
+
781
+ template<class... Indices>
782
+ constexpr index_type operator()(Indices...) const noexcept;
783
+
784
+ static constexpr bool is_always_unique() noexcept { return true; }
785
+ static constexpr bool is_always_exhaustive() noexcept { return true; }
786
+ static constexpr bool is_always_strided() noexcept { return true; }
787
+
788
+ static constexpr bool is_unique() noexcept { return true; }
789
+ static constexpr bool is_exhaustive() noexcept { return true; }
790
+ static constexpr bool is_strided() noexcept { return true; }
791
+
792
+ constexpr index_type stride(rank_type) const noexcept;
793
+
794
+ template<class OtherExtents>
795
+ friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
796
+
797
+ private:
798
+ extents_type extents_{}; // exposition only
799
+ };
800
+ }
801
+ ```
802
+
803
+ If `Extents` is not a specialization of `extents`, then the program is
804
+ ill-formed.
805
+
806
+ `layout_right::mapping<E>` is a trivially copyable type that models
807
+ `regular` for each `E`.
808
+
809
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
810
+ of the multidimensional index space `Extents()` is representable as a
811
+ value of type `typename Extents::index_type`.
812
+
813
+ ###### Constructors <a id="mdspan.layout.right.cons">[[mdspan.layout.right.cons]]</a>
814
+
815
+ ``` cpp
816
+ constexpr mapping(const extents_type& e) noexcept;
817
+ ```
818
+
819
+ *Preconditions:* The size of the multidimensional index space `e` is
820
+ representable as a value of type `index_type` [[basic.fundamental]].
821
+
822
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`.
823
+
824
+ ``` cpp
825
+ template<class OtherExtents>
826
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
827
+ mapping(const mapping<OtherExtents>& other) noexcept;
828
+ ```
829
+
830
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
831
+ `true`.
832
+
833
+ *Preconditions:* `other.required_span_size()` is representable as a
834
+ value of type `index_type` [[basic.fundamental]].
835
+
836
+ *Effects:* Direct-non-list-initializes *extents\_* with
837
+ `other.extents()`.
838
+
839
+ ``` cpp
840
+ template<class OtherExtents>
841
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
842
+ mapping(const layout_left::mapping<OtherExtents>& other) noexcept;
843
+ ```
844
+
845
+ *Constraints:*
846
+
847
+ - `extents_type::rank() <= 1` is `true`, and
848
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
849
+
850
+ *Preconditions:* `other.required_span_size()` is representable as a
851
+ value of type `index_type` [[basic.fundamental]].
852
+
853
+ *Effects:* Direct-non-list-initializes *extents\_* with
854
+ `other.extents()`.
855
+
856
+ ``` cpp
857
+ template<class OtherExtents>
858
+ constexpr explicit(extents_type::rank() > 0)
859
+ mapping(const layout_stride::mapping<OtherExtents>& other) noexcept;
860
+ ```
861
+
862
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
863
+ `true`.
864
+
865
+ *Preconditions:*
866
+
867
+ - If `extents_type::rank() > 0` is `true`, then for all r in the range
868
+ [0, `extents_type::rank()`), `other.stride(`r`)` equals
869
+ `other.extents().`*`rev-prod-of-extents`*`(`r`)`.
870
+ - `other.required_span_size()` is representable as a value of type
871
+ `index_type` [[basic.fundamental]].
872
+
873
+ *Effects:* Direct-non-list-initializes *extents\_* with
874
+ `other.extents()`.
875
+
876
+ ###### Observers <a id="mdspan.layout.right.obs">[[mdspan.layout.right.obs]]</a>
877
+
878
+ ``` cpp
879
+ index_type required_span_size() const noexcept;
880
+ ```
881
+
882
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(extents_type::rank())`.
883
+
884
+ ``` cpp
885
+ template<class... Indices>
886
+ constexpr index_type operator()(Indices... i) const noexcept;
887
+ ```
888
+
889
+ *Constraints:*
890
+
891
+ - `sizeof...(Indices) == extents_type::rank()` is `true`,
892
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
893
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
894
+
895
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
896
+ multidimensional index in *extents\_*[[mdspan.overview]].
897
+
898
+ *Effects:* Let `P` be a parameter pack such that
899
+
900
+ ``` cpp
901
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
902
+ ```
903
+
904
+ is `true`. Equivalent to:
905
+
906
+ ``` cpp
907
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
908
+ ```
909
+
910
+ ``` cpp
911
+ constexpr index_type stride(rank_type i) const noexcept;
912
+ ```
913
+
914
+ *Constraints:* `extents_type::rank() > 0` is `true`.
915
+
916
+ *Preconditions:* `i < extents_type::rank()` is `true`.
917
+
918
+ *Returns:* `extents().`*`rev-prod-of-extents`*`(i)`.
919
+
920
+ ``` cpp
921
+ template<class OtherExtents>
922
+ friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
923
+ ```
924
+
925
+ *Constraints:* `extents_type::rank() == OtherExtents::rank()` is `true`.
926
+
927
+ *Effects:* Equivalent to: `return x.extents() == y.extents();`
928
+
929
+ ##### Class template `layout_stride::mapping` <a id="mdspan.layout.stride">[[mdspan.layout.stride]]</a>
930
+
931
+ ###### Overview <a id="mdspan.layout.stride.overview">[[mdspan.layout.stride.overview]]</a>
932
+
933
+ `layout_stride` provides a layout mapping where the strides are
934
+ user-defined.
935
+
936
+ ``` cpp
937
+ namespace std {
938
+ template<class Extents>
939
+ class layout_stride::mapping {
940
+ public:
941
+ using extents_type = Extents;
942
+ using index_type = typename extents_type::index_type;
943
+ using size_type = typename extents_type::size_type;
944
+ using rank_type = typename extents_type::rank_type;
945
+ using layout_type = layout_stride;
946
+
947
+ private:
948
+ static constexpr rank_type rank_ = extents_type::rank(); // exposition only
949
+
950
+ public:
951
+ // [mdspan.layout.stride.cons], constructors
952
+ constexpr mapping() noexcept;
953
+ constexpr mapping(const mapping&) noexcept = default;
954
+ template<class OtherIndexType>
955
+ constexpr mapping(const extents_type&, span<OtherIndexType, rank_>) noexcept;
956
+ template<class OtherIndexType>
957
+ constexpr mapping(const extents_type&, const array<OtherIndexType, rank_>&) noexcept;
958
+
959
+ template<class StridedLayoutMapping>
960
+ constexpr explicit(see below) mapping(const StridedLayoutMapping&) noexcept;
961
+
962
+ constexpr mapping& operator=(const mapping&) noexcept = default;
963
+
964
+ // [mdspan.layout.stride.obs], observers
965
+ constexpr const extents_type& extents() const noexcept { return extents_; }
966
+ constexpr array<index_type, rank_> strides() const noexcept { return strides_; }
967
+
968
+ constexpr index_type required_span_size() const noexcept;
969
+
970
+ template<class... Indices>
971
+ constexpr index_type operator()(Indices...) const noexcept;
972
+
973
+ static constexpr bool is_always_unique() noexcept { return true; }
974
+ static constexpr bool is_always_exhaustive() noexcept { return false; }
975
+ static constexpr bool is_always_strided() noexcept { return true; }
976
+
977
+ static constexpr bool is_unique() noexcept { return true; }
978
+ constexpr bool is_exhaustive() const noexcept;
979
+ static constexpr bool is_strided() noexcept { return true; }
980
+
981
+ constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; }
982
+
983
+ template<class OtherMapping>
984
+ friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;
985
+
986
+ private:
987
+ extents_type extents_{}; // exposition only
988
+ array<index_type, rank_> strides_{}; // exposition only
989
+ };
990
+ }
991
+ ```
992
+
993
+ If `Extents` is not a specialization of `extents`, then the program is
994
+ ill-formed.
995
+
996
+ `layout_stride::mapping<E>` is a trivially copyable type that models
997
+ `regular` for each `E`.
998
+
999
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
1000
+ of the multidimensional index space `Extents()` is representable as a
1001
+ value of type `typename Extents::index_type`.
1002
+
1003
+ ###### Exposition-only helpers <a id="mdspan.layout.stride.expo">[[mdspan.layout.stride.expo]]</a>
1004
+
1005
+ Let `REQUIRED-SPAN-SIZE(e, strides)` be:
1006
+
1007
+ - `1`, if `e.rank() == 0` is `true`,
1008
+ - otherwise `0`, if the size of the multidimensional index space `e` is
1009
+ 0,
1010
+ - otherwise `1` plus the sum of products of `(e.extent(r) - 1)` and
1011
+ `strides[r]` for all r in the range [0, `e.rank()`).
1012
+
1013
+ Let `OFFSET(m)` be:
1014
+
1015
+ - `m()`, if `e.rank() == 0` is `true`,
1016
+ - otherwise `0`, if the size of the multidimensional index space `e` is
1017
+ 0,
1018
+ - otherwise `m(z...)` for a pack of integers `z` that is a
1019
+ multidimensional index in `m.extents()` and each element of `z` equals
1020
+ 0.
1021
+
1022
+ Let *`is-extents`* be the exposition-only variable template defined as
1023
+ follows:
1024
+
1025
+ ``` cpp
1026
+ template<class T>
1027
+ constexpr bool is-extents = false; // exposition only
1028
+ template<class IndexType, size_t... Args>
1029
+ constexpr bool is-extents<extents<IndexType, Args...>> = true; // exposition only
1030
+ ```
1031
+
1032
+ Let `layout-mapping-alike` be the exposition-only concept defined as
1033
+ follows:
1034
+
1035
+ ``` cpp
1036
+ template<class M>
1037
+ concept layout-mapping-alike = requires { // exposition only
1038
+ requires is-extents<typename M::extents_type>;
1039
+ { M::is_always_strided() } -> same_as<bool>;
1040
+ { M::is_always_exhaustive() } -> same_as<bool>;
1041
+ { M::is_always_unique() } -> same_as<bool>;
1042
+ bool_constant<M::is_always_strided()>::value;
1043
+ bool_constant<M::is_always_exhaustive()>::value;
1044
+ bool_constant<M::is_always_unique()>::value;
1045
+ };
1046
+ ```
1047
+
1048
+ [*Note 2*: This concept checks that the functions
1049
+ `M::is_always_strided()`, `M::is_always_exhaustive()`, and
1050
+ `M::is_always_unique()` exist, are constant expressions, and have a
1051
+ return type of `bool`. — *end note*]
1052
+
1053
+ ###### Constructors <a id="mdspan.layout.stride.cons">[[mdspan.layout.stride.cons]]</a>
1054
+
1055
+ ``` cpp
1056
+ constexpr mapping() noexcept;
1057
+ ```
1058
+
1059
+ *Preconditions:*
1060
+ `layout_right::mapping<extents_type>().required_span_size()` is
1061
+ representable as a value of type `index_type` [[basic.fundamental]].
1062
+
1063
+ *Effects:* Direct-non-list-initializes *extents\_* with
1064
+ `extents_type()`, and for all d in the range \[`0`, *`rank_`*),
1065
+ direct-non-list-initializes *`strides_`*`[`d`]` with
1066
+ `layout_right::mapping<extents_type>().stride(`d`)`.
1067
+
1068
+ ``` cpp
1069
+ template<class OtherIndexType>
1070
+ constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
1071
+ template<class OtherIndexType>
1072
+ constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
1073
+ ```
1074
+
1075
+ *Constraints:*
1076
+
1077
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`, and
1078
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
1079
+ `true`.
1080
+
1081
+ *Preconditions:*
1082
+
1083
+ - `s[`i`] > 0` is `true` for all i in the range [0, rank_).
1084
+ - *`REQUIRED-SPAN-SIZE`*`(e, s)` is representable as a value of type
1085
+ `index_type` [[basic.fundamental]].
1086
+ - If *rank\_* is greater than 0, then there exists a permutation P of
1087
+ the integers in the range [0, rank_), such that
1088
+ `s[`pᵢ`] >= s[`pᵢ₋₁`] * e.extent(p`ᵢ₋₁`)` is `true` for all i in the
1089
+ range [1, rank_), where pᵢ is the iᵗʰ element of P. \[*Note 3*: For
1090
+ `layout_stride`, this condition is necessary and sufficient for
1091
+ `is_unique()` to be `true`. — *end note*]
1092
+
1093
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`, and for all
1094
+ d in the range [0, rank_), direct-non-list-initializes `strides_[`d`]`
1095
+ with `as_const(s[`d`])`.
1096
+
1097
+ ``` cpp
1098
+ template<class StridedLayoutMapping>
1099
+ constexpr explicit(see below)
1100
+ mapping(const StridedLayoutMapping& other) noexcept;
1101
+ ```
1102
+
1103
+ *Constraints:*
1104
+
1105
+ - `layout-mapping-alike<StridedLayoutMapping>` is satisfied.
1106
+ - `is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type>`
1107
+ is
1108
+ `true`.
1109
+ - `StridedLayoutMapping::is_always_unique()` is `true`.
1110
+ - `StridedLayoutMapping::is_always_strided()` is `true`.
1111
+
1112
+ *Preconditions:*
1113
+
1114
+ - `StridedLayoutMapping` meets the layout mapping
1115
+ requirements [[mdspan.layout.policy.reqmts]],
1116
+ - `other.stride(`r`) > 0` is `true` for every rank index r of
1117
+ `extents()`,
1118
+ - `other.required_span_size()` is representable as a value of type
1119
+ `index_type` [[basic.fundamental]], and
1120
+ - *`OFFSET`*`(other) == 0` is `true`.
1121
+
1122
+ *Effects:* Direct-non-list-initializes *extents\_* with
1123
+ `other.extents()`, and for all d in the range [0, rank_),
1124
+ direct-non-list-initializes *`strides_`*`[`d`]` with
1125
+ `other.stride(`d`)`.
1126
+
1127
+ Remarks: The expression inside `explicit` is equivalent to:
1128
+
1129
+ ``` cpp
1130
+ !(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&
1131
+ (is-mapping-of<layout_left, LayoutStrideMapping> ||
1132
+ is-mapping-of<layout_right, LayoutStrideMapping> ||
1133
+ is-mapping-of<layout_stride, LayoutStrideMapping>))
1134
+ ```
1135
+
1136
+ ###### Observers <a id="mdspan.layout.stride.obs">[[mdspan.layout.stride.obs]]</a>
1137
+
1138
+ ``` cpp
1139
+ constexpr index_type required_span_size() const noexcept;
1140
+ ```
1141
+
1142
+ *Returns:* *`REQUIRED-SPAN-SIZE`*`(extents(), `*`strides_`*`)`.
1143
+
1144
+ ``` cpp
1145
+ template<class... Indices>
1146
+ constexpr index_type operator()(Indices... i) const noexcept;
1147
+ ```
1148
+
1149
+ *Constraints:*
1150
+
1151
+ - `sizeof...(Indices) == `*`rank_`* is `true`,
1152
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
1153
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
1154
+
1155
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
1156
+ multidimensional index in *extents\_*[[mdspan.overview]].
1157
+
1158
+ *Effects:* Let `P` be a parameter pack such that
1159
+
1160
+ ``` cpp
1161
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
1162
+ ```
1163
+
1164
+ is `true`. Equivalent to:
1165
+
1166
+ ``` cpp
1167
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
1168
+ ```
1169
+
1170
+ ``` cpp
1171
+ constexpr bool is_exhaustive() const noexcept;
1172
+ ```
1173
+
1174
+ *Returns:*
1175
+
1176
+ - `true` if *rank\_* is 0.
1177
+ - Otherwise, `true` if there is a permutation P of the integers in the
1178
+ range [0, rank_) such that `stride(`p₀`)` equals 1, and `stride(`pᵢ`)`
1179
+ equals `stride(`pᵢ₋₁`) * extents().extent(`pᵢ₋₁`)` for i in the range
1180
+ [1, rank_), where pᵢ is the iᵗʰ element of P.
1181
+ - Otherwise, `false`.
1182
+
1183
+ ``` cpp
1184
+ template<class OtherMapping>
1185
+ friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept;
1186
+ ```
1187
+
1188
+ *Constraints:*
1189
+
1190
+ - `layout-mapping-alike<OtherMapping>` is satisfied.
1191
+ - *`rank_`*` == OtherMapping::extents_type::rank()` is `true`.
1192
+ - `OtherMapping::is_always_strided()` is `true`.
1193
+
1194
+ *Preconditions:* `OtherMapping` meets the layout mapping
1195
+ requirements [[mdspan.layout.policy.reqmts]].
1196
+
1197
+ *Returns:* `true` if `x.extents() == y.extents()` is `true`,
1198
+ *`OFFSET`*`(y) == 0` is `true`, and each of
1199
+ `x.stride(`r`) == y.stride(`r`)` is `true` for r in the range
1200
+ [0, `x.extents().rank()`). Otherwise, `false`.
1201
+
1202
+ #### Accessor policy <a id="mdspan.accessor">[[mdspan.accessor]]</a>
1203
+
1204
+ ##### General <a id="mdspan.accessor.general">[[mdspan.accessor.general]]</a>
1205
+
1206
+ An *accessor policy* defines types and operations by which a reference
1207
+ to a single object is created from an abstract data handle to a number
1208
+ of such objects and an index.
1209
+
1210
+ A range of indices [0, N) is an *accessible range* of a given data
1211
+ handle and an accessor if, for each i in the range, the accessor
1212
+ policy’s `access` function produces a valid reference to an object.
1213
+
1214
+ In subclause [[mdspan.accessor.reqmts]],
1215
+
1216
+ - `A` denotes an accessor policy.
1217
+ - `a` denotes a value of type `A` or `const A`.
1218
+ - `p` denotes a value of type `A::data_handle_type` or
1219
+ `const A::data_handle_type`. \[*Note 1*: The type
1220
+ `A::data_handle_type` need not be dereferenceable. — *end note*]
1221
+ - `n`, `i`, and `j` each denote values of type `size_t`.
1222
+
1223
+ ##### Requirements <a id="mdspan.accessor.reqmts">[[mdspan.accessor.reqmts]]</a>
1224
+
1225
+ A type `A` meets the accessor policy requirements if
1226
+
1227
+ - `A` models `copyable`,
1228
+ - `is_nothrow_move_constructible_v<A>` is `true`,
1229
+ - `is_nothrow_move_assignable_v<A>` is `true`,
1230
+ - `is_nothrow_swappable_v<A>` is `true`, and
1231
+ - the following types and expressions are well-formed and have the
1232
+ specified semantics.
1233
+
1234
+ ``` cpp
1235
+ typename A::element_type
1236
+ ```
1237
+
1238
+ *Result:* A complete object type that is not an abstract class type.
1239
+
1240
+ ``` cpp
1241
+ typename A::data_handle_type
1242
+ ```
1243
+
1244
+ *Result:* A type that models `copyable`, and for which
1245
+ `is_nothrow_move_constructible_v<A::data_handle_type>` is `true`,
1246
+ `is_nothrow_move_assignable_v<A::data_handle_type>` is `true`, and
1247
+ `is_nothrow_swappable_v<A::data_handle_type>` is `true`.
1248
+
1249
+ [*Note 1*: The type of `data_handle_type` need not be
1250
+ `element_type*`. — *end note*]
1251
+
1252
+ ``` cpp
1253
+ typename A::reference
1254
+ ```
1255
+
1256
+ *Result:* A type that models
1257
+ `common_reference_with<A::reference&&, A::element_type&>`.
1258
+
1259
+ [*Note 2*: The type of `reference` need not be
1260
+ `element_type&`. — *end note*]
1261
+
1262
+ ``` cpp
1263
+ typename A::offset_policy
1264
+ ```
1265
+
1266
+ *Result:* A type `OP` such that:
1267
+
1268
+ - `OP` meets the accessor policy requirements,
1269
+ - `constructible_from<OP, const A&>` is modeled, and
1270
+ - `is_same_v<typename OP::element_type, typename A::element_type>` is
1271
+ `true`.
1272
+
1273
+ ``` cpp
1274
+ a.access(p, i)
1275
+ ```
1276
+
1277
+ *Result:* `A::reference`
1278
+
1279
+ *Remarks:* The expression is equality preserving.
1280
+
1281
+ [*Note 3*: Concrete accessor policies can impose preconditions for
1282
+ their `access` function. However, they might not. For example, an
1283
+ accessor where `p` is `span<A::element_type, dynamic_extent>` and
1284
+ `access(p, i)` returns `p[i % p.size()]` does not need to impose a
1285
+ precondition on `i`. — *end note*]
1286
+
1287
+ ``` cpp
1288
+ a.offset(p, i)
1289
+ ```
1290
+
1291
+ *Result:* `A::offset_policy::data_handle_type`
1292
+
1293
+ *Returns:* `q` such that for `b` being `A::offset_policy(a)`, and any
1294
+ integer `n` for which [0, `n`) is an accessible range of `p` and `a`:
1295
+
1296
+ - [0, `n` - `i`) is an accessible range of `q` and `b`; and
1297
+ - `b.access(q, j)` provides access to the same element as
1298
+ `a.access(p, i + j)`, for every `j` in the range [0, `n` - `i`).
1299
+
1300
+ *Remarks:* The expression is equality-preserving.
1301
+
1302
+ ##### Class template `default_accessor` <a id="mdspan.accessor.default">[[mdspan.accessor.default]]</a>
1303
+
1304
+ ###### Overview <a id="mdspan.accessor.default.overview">[[mdspan.accessor.default.overview]]</a>
1305
+
1306
+ ``` cpp
1307
+ namespace std {
1308
+ template<class ElementType>
1309
+ struct default_accessor {
1310
+ using offset_policy = default_accessor;
1311
+ using element_type = ElementType;
1312
+ using reference = ElementType&;
1313
+ using data_handle_type = ElementType*;
1314
+
1315
+ constexpr default_accessor() noexcept = default;
1316
+ template<class OtherElementType>
1317
+ constexpr default_accessor(default_accessor<OtherElementType>) noexcept;
1318
+ constexpr reference access(data_handle_type p, size_t i) const noexcept;
1319
+ constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
1320
+ };
1321
+ }
1322
+ ```
1323
+
1324
+ `default_accessor` meets the accessor policy requirements.
1325
+
1326
+ `ElementType` is required to be a complete object type that is neither
1327
+ an abstract class type nor an array type.
1328
+
1329
+ Each specialization of `default_accessor` is a trivially copyable type
1330
+ that models `semiregular`.
1331
+
1332
+ [0, n) is an accessible range for an object `p` of type
1333
+ `data_handle_type` and an object of type `default_accessor` if and only
1334
+ if \[`p`, `p + `n) is a valid range.
1335
+
1336
+ ###### Members <a id="mdspan.accessor.default.members">[[mdspan.accessor.default.members]]</a>
1337
+
1338
+ ``` cpp
1339
+ template<class OtherElementType>
1340
+ constexpr default_accessor(default_accessor<OtherElementType>) noexcept {}
1341
+ ```
1342
+
1343
+ *Constraints:*
1344
+ `is_convertible_v<OtherElementType(*)[], element_type(*)[]>` is `true`.
1345
+
1346
+ ``` cpp
1347
+ constexpr reference access(data_handle_type p, size_t i) const noexcept;
1348
+ ```
1349
+
1350
+ *Effects:* Equivalent to: `return p[i];`
1351
+
1352
+ ``` cpp
1353
+ constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
1354
+ ```
1355
+
1356
+ *Effects:* Equivalent to: `return p + i;`
1357
+
1358
+ #### Class template `mdspan` <a id="mdspan.mdspan">[[mdspan.mdspan]]</a>
1359
+
1360
+ ##### Overview <a id="mdspan.mdspan.overview">[[mdspan.mdspan.overview]]</a>
1361
+
1362
+ `mdspan` is a view of a multidimensional array of elements.
1363
+
1364
+ ``` cpp
1365
+ namespace std {
1366
+ template<class ElementType, class Extents, class LayoutPolicy = layout_right,
1367
+ class AccessorPolicy = default_accessor<ElementType>>
1368
+ class mdspan {
1369
+ public:
1370
+ using extents_type = Extents;
1371
+ using layout_type = LayoutPolicy;
1372
+ using accessor_type = AccessorPolicy;
1373
+ using mapping_type = typename layout_type::template mapping<extents_type>;
1374
+ using element_type = ElementType;
1375
+ using value_type = remove_cv_t<element_type>;
1376
+ using index_type = typename extents_type::index_type;
1377
+ using size_type = typename extents_type::size_type;
1378
+ using rank_type = typename extents_type::rank_type;
1379
+ using data_handle_type = typename accessor_type::data_handle_type;
1380
+ using reference = typename accessor_type::reference;
1381
+
1382
+ static constexpr rank_type rank() noexcept { return extents_type::rank(); }
1383
+ static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
1384
+ static constexpr size_t static_extent(rank_type r) noexcept
1385
+ { return extents_type::static_extent(r); }
1386
+ constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }
1387
+
1388
+ // [mdspan.mdspan.cons], constructors
1389
+ constexpr mdspan();
1390
+ constexpr mdspan(const mdspan& rhs) = default;
1391
+ constexpr mdspan(mdspan&& rhs) = default;
1392
+
1393
+ template<class... OtherIndexTypes>
1394
+ constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts);
1395
+ template<class OtherIndexType, size_t N>
1396
+ constexpr explicit(N != rank_dynamic())
1397
+ mdspan(data_handle_type p, span<OtherIndexType, N> exts);
1398
+ template<class OtherIndexType, size_t N>
1399
+ constexpr explicit(N != rank_dynamic())
1400
+ mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
1401
+ constexpr mdspan(data_handle_type p, const extents_type& ext);
1402
+ constexpr mdspan(data_handle_type p, const mapping_type& m);
1403
+ constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
1404
+
1405
+ template<class OtherElementType, class OtherExtents,
1406
+ class OtherLayoutPolicy, class OtherAccessorPolicy>
1407
+ constexpr explicit(see below)
1408
+ mdspan(const mdspan<OtherElementType, OtherExtents,
1409
+ OtherLayoutPolicy, OtherAccessorPolicy>& other);
1410
+
1411
+ constexpr mdspan& operator=(const mdspan& rhs) = default;
1412
+ constexpr mdspan& operator=(mdspan&& rhs) = default;
1413
+
1414
+ // [mdspan.mdspan.members], members
1415
+ template<class... OtherIndexTypes>
1416
+ constexpr reference operator[](OtherIndexTypes... indices) const;
1417
+ template<class OtherIndexType>
1418
+ constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
1419
+ template<class OtherIndexType>
1420
+ constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
1421
+
1422
+ constexpr size_type size() const noexcept;
1423
+ [[nodiscard]] constexpr bool empty() const noexcept;
1424
+
1425
+ friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
1426
+
1427
+ constexpr const extents_type& extents() const noexcept { return map_.extents(); }
1428
+ constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
1429
+ constexpr const mapping_type& mapping() const noexcept { return map_; }
1430
+ constexpr const accessor_type& accessor() const noexcept { return acc_; }
1431
+
1432
+ static constexpr bool is_always_unique()
1433
+ { return mapping_type::is_always_unique(); }
1434
+ static constexpr bool is_always_exhaustive()
1435
+ { return mapping_type::is_always_exhaustive(); }
1436
+ static constexpr bool is_always_strided()
1437
+ { return mapping_type::is_always_strided(); }
1438
+
1439
+ constexpr bool is_unique() const
1440
+ { return map_.is_unique(); }
1441
+ constexpr bool is_exhaustive() const
1442
+ { return map_.is_exhaustive(); }
1443
+ constexpr bool is_strided() const
1444
+ { return map_.is_strided(); }
1445
+ constexpr index_type stride(rank_type r) const
1446
+ { return map_.stride(r); }
1447
+
1448
+ private:
1449
+ accessor_type acc_; // exposition only
1450
+ mapping_type map_; // exposition only
1451
+ data_handle_type ptr_; // exposition only
1452
+ };
1453
+
1454
+ template<class CArray>
1455
+ requires(is_array_v<CArray> && rank_v<CArray> == 1)
1456
+ mdspan(CArray&)
1457
+ -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
1458
+
1459
+ template<class Pointer>
1460
+ requires(is_pointer_v<remove_reference_t<Pointer>>)
1461
+ mdspan(Pointer&&)
1462
+ -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
1463
+
1464
+ template<class ElementType, class... Integrals>
1465
+ requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)
1466
+ explicit mdspan(ElementType*, Integrals...)
1467
+ -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
1468
+
1469
+ template<class ElementType, class OtherIndexType, size_t N>
1470
+ mdspan(ElementType*, span<OtherIndexType, N>)
1471
+ -> mdspan<ElementType, dextents<size_t, N>>;
1472
+
1473
+ template<class ElementType, class OtherIndexType, size_t N>
1474
+ mdspan(ElementType*, const array<OtherIndexType, N>&)
1475
+ -> mdspan<ElementType, dextents<size_t, N>>;
1476
+
1477
+ template<class ElementType, class IndexType, size_t... ExtentsPack>
1478
+ mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)
1479
+ -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
1480
+
1481
+ template<class ElementType, class MappingType>
1482
+ mdspan(ElementType*, const MappingType&)
1483
+ -> mdspan<ElementType, typename MappingType::extents_type,
1484
+ typename MappingType::layout_type>;
1485
+
1486
+ template<class MappingType, class AccessorType>
1487
+ mdspan(const typename AccessorType::data_handle_type&, const MappingType&,
1488
+ const AccessorType&)
1489
+ -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type,
1490
+ typename MappingType::layout_type, AccessorType>;
1491
+ }
1492
+ ```
1493
+
1494
+ *Mandates:*
1495
+
1496
+ - `ElementType` is a complete object type that is neither an abstract
1497
+ class type nor an array type,
1498
+ - `Extents` is a specialization of `extents`, and
1499
+ - `is_same_v<ElementType, typename AccessorPolicy::element_type>` is
1500
+ `true`.
1501
+
1502
+ `LayoutPolicy` shall meet the layout mapping policy requirements
1503
+ [[mdspan.layout.policy.reqmts]], and `AccessorPolicy` shall meet the
1504
+ accessor policy requirements [[mdspan.accessor.reqmts]].
1505
+
1506
+ Each specialization `MDS` of `mdspan` models `copyable` and
1507
+
1508
+ - `is_nothrow_move_constructible_v<MDS>` is `true`,
1509
+ - `is_nothrow_move_assignable_v<MDS>` is `true`, and
1510
+ - `is_nothrow_swappable_v<MDS>` is `true`.
1511
+
1512
+ A specialization of `mdspan` is a trivially copyable type if its
1513
+ `accessor_type`, `mapping_type`, and `data_handle_type` are trivially
1514
+ copyable types.
1515
+
1516
+ ##### Constructors <a id="mdspan.mdspan.cons">[[mdspan.mdspan.cons]]</a>
1517
+
1518
+ ``` cpp
1519
+ constexpr mdspan();
1520
+ ```
1521
+
1522
+ *Constraints:*
1523
+
1524
+ - `rank_dynamic() > 0` is `true`.
1525
+ - `is_default_constructible_v<data_handle_type>` is `true`.
1526
+ - `is_default_constructible_v<mapping_type>` is `true`.
1527
+ - `is_default_constructible_v<accessor_type>` is `true`.
1528
+
1529
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
1530
+ an accessible range of *ptr\_* and *acc\_* for the values of *map\_* and
1531
+ *acc\_* after the invocation of this constructor.
1532
+
1533
+ *Effects:* Value-initializes *ptr\_*, *map\_*, and *acc\_*.
1534
+
1535
+ ``` cpp
1536
+ template<class... OtherIndexTypes>
1537
+ constexpr explicit mdspan(data_handle_type p, OtherIndexTypes... exts);
1538
+ ```
1539
+
1540
+ Let `N` be `sizeof...(OtherIndexTypes)`.
1541
+
1542
+ *Constraints:*
1543
+
1544
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
1545
+ - `(is_nothrow_constructible<index_type, OtherIndexTypes> && ...)` is
1546
+ `true`,
1547
+ - `N == rank() || N == rank_dynamic()` is `true`,
1548
+ - `is_constructible_v<mapping_type, extents_type>` is `true`, and
1549
+ - `is_default_constructible_v<accessor_type>` is `true`.
1550
+
1551
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
1552
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
1553
+ *acc\_* after the invocation of this constructor.
1554
+
1555
+ *Effects:*
1556
+
1557
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
1558
+ - direct-non-list-initializes *map\_* with
1559
+ `extents_type(static_cast<index_type>(std::move(exts))...)`, and
1560
+ - value-initializes *acc\_*.
1561
+
1562
+ ``` cpp
1563
+ template<class OtherIndexType, size_t N>
1564
+ constexpr explicit(N != rank_dynamic())
1565
+ mdspan(data_handle_type p, span<OtherIndexType, N> exts);
1566
+ template<class OtherIndexType, size_t N>
1567
+ constexpr explicit(N != rank_dynamic())
1568
+ mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
1569
+ ```
1570
+
1571
+ *Constraints:*
1572
+
1573
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
1574
+ - `(is_nothrow_constructible<index_type, const OtherIndexType&> && ...)`
1575
+ is `true`,
1576
+ - `N == rank() || N == rank_dynamic()` is `true`,
1577
+ - `is_constructible_v<mapping_type, extents_type>` is `true`, and
1578
+ - `is_default_constructible_v<accessor_type>` is `true`.
1579
+
1580
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
1581
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
1582
+ *acc\_* after the invocation of this constructor.
1583
+
1584
+ *Effects:*
1585
+
1586
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
1587
+ - direct-non-list-initializes *map\_* with `extents_type(exts)`, and
1588
+ - value-initializes *acc\_*.
1589
+
1590
+ ``` cpp
1591
+ constexpr mdspan(data_handle_type p, const extents_type& ext);
1592
+ ```
1593
+
1594
+ *Constraints:*
1595
+
1596
+ - `is_constructible_v<mapping_type, const extents_type&>` is `true`, and
1597
+ - `is_default_constructible_v<accessor_type>` is `true`.
1598
+
1599
+ *Preconditions:* $[0, \texttt{\textit{map_}.required_span_size()})$ is
1600
+ an accessible range of `p` and *acc\_* for the values of *map\_* and
1601
+ *acc\_* after the invocation of this constructor.
1602
+
1603
+ *Effects:*
1604
+
1605
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
1606
+ - direct-non-list-initializes *map\_* with `ext`, and
1607
+ - value-initializes *acc\_*.
1608
+
1609
+ ``` cpp
1610
+ constexpr mdspan(data_handle_type p, const mapping_type& m);
1611
+ ```
1612
+
1613
+ *Constraints:* `is_default_constructible_v<accessor_type>` is `true`.
1614
+
1615
+ *Preconditions:* [0, `m.required_span_size()`) is an accessible range of
1616
+ `p` and *acc\_* for the value of *acc\_* after the invocation of this
1617
+ constructor.
1618
+
1619
+ *Effects:*
1620
+
1621
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
1622
+ - direct-non-list-initializes *map\_* with `m`, and
1623
+ - value-initializes *acc\_*.
1624
+
1625
+ ``` cpp
1626
+ constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
1627
+ ```
1628
+
1629
+ *Preconditions:* [0, `m.required_span_size()`) is an accessible range of
1630
+ `p` and `a`.
1631
+
1632
+ *Effects:*
1633
+
1634
+ - Direct-non-list-initializes *ptr\_* with `std::move(p)`,
1635
+ - direct-non-list-initializes *map\_* with `m`, and
1636
+ - direct-non-list-initializes *acc\_* with `a`.
1637
+
1638
+ ``` cpp
1639
+ template<class OtherElementType, class OtherExtents,
1640
+ class OtherLayoutPolicy, class OtherAccessor>
1641
+ constexpr explicit(see below)
1642
+ mdspan(const mdspan<OtherElementType, OtherExtents,
1643
+ OtherLayoutPolicy, OtherAccessor>& other);
1644
+ ```
1645
+
1646
+ *Constraints:*
1647
+
1648
+ - `is_constructible_v<mapping_type, const OtherLayoutPolicy::template mapping<Oth- erExtents>&>`
1649
+ is `true`, and
1650
+ - `is_constructible_v<accessor_type, const OtherAccessor&>` is `true`.
1651
+
1652
+ *Mandates:*
1653
+
1654
+ - `is_constructible_v<data_handle_type, const OtherAccessor::data_handle_type&>`
1655
+ is `true`, and
1656
+ - `is_constructible_v<extents_type, OtherExtents>` is `true`.
1657
+
1658
+ *Preconditions:*
1659
+
1660
+ - For each rank index `r` of `extents_type`,
1661
+ `static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)`
1662
+ is `true`.
1663
+ - $[0, \texttt{\textit{map_}.required_span_size()})$ is an accessible
1664
+ range of *ptr\_* and *acc\_* for values of *ptr\_*, *map\_*, and
1665
+ *acc\_* after the invocation of this constructor.
1666
+
1667
+ *Effects:*
1668
+
1669
+ - Direct-non-list-initializes *ptr\_* with `other.`*`ptr_`*,
1670
+ - direct-non-list-initializes *map\_* with `other.`*`map_`*, and
1671
+ - direct-non-list-initializes *acc\_* with `other.`*`acc_`*.
1672
+
1673
+ *Remarks:* The expression inside `explicit` is equivalent to:
1674
+
1675
+ ``` cpp
1676
+ !is_convertible_v<const OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type>
1677
+ || !is_convertible_v<const OtherAccessor&, accessor_type>
1678
+ ```
1679
+
1680
+ ##### Members <a id="mdspan.mdspan.members">[[mdspan.mdspan.members]]</a>
1681
+
1682
+ ``` cpp
1683
+ template<class... OtherIndexTypes>
1684
+ constexpr reference operator[](OtherIndexTypes... indices) const;
1685
+ ```
1686
+
1687
+ *Constraints:*
1688
+
1689
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
1690
+ - `(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)` is
1691
+ `true`, and
1692
+ - `sizeof...(OtherIndexTypes) == rank()` is `true`.
1693
+
1694
+ Let `I` be `extents_type::`*`index-cast`*`(std::move(indices))`.
1695
+
1696
+ *Preconditions:* `I` is a multidimensional index in `extents()`.
1697
+
1698
+ [*Note 1*: This implies that
1699
+ *`map_`*`(I) < `*`map_`*`.required_span_size()` is
1700
+ `true`. — *end note*]
1701
+
1702
+ *Effects:* Equivalent to:
1703
+
1704
+ ``` cpp
1705
+ return acc_.access(ptr_, map_(static_cast<index_type>(std::move(indices))...));
1706
+ ```
1707
+
1708
+ ``` cpp
1709
+ template<class OtherIndexType>
1710
+ constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
1711
+ template<class OtherIndexType>
1712
+ constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
1713
+ ```
1714
+
1715
+ *Constraints:*
1716
+
1717
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`, and
1718
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
1719
+ `true`.
1720
+
1721
+ *Effects:* Let `P` be a parameter pack such that
1722
+
1723
+ ``` cpp
1724
+ is_same_v<make_index_sequence<rank()>, index_sequence<P...>>
1725
+ ```
1726
+
1727
+ is `true`. Equivalent to:
1728
+
1729
+ ``` cpp
1730
+ return operator[](as_const(indices[P])...);
1731
+ ```
1732
+
1733
+ ``` cpp
1734
+ constexpr size_type size() const noexcept;
1735
+ ```
1736
+
1737
+ *Preconditions:* The size of the multidimensional index space
1738
+ `extents()` is representable as a value of type `size_type`
1739
+ [[basic.fundamental]].
1740
+
1741
+ *Returns:* `extents().`*`fwd-prod-of-extents`*`(rank())`.
1742
+
1743
+ ``` cpp
1744
+ [[nodiscard]] constexpr bool empty() const noexcept;
1745
+ ```
1746
+
1747
+ *Returns:* `true` if the size of the multidimensional index space
1748
+ `extents()` is 0, otherwise `false`.
1749
+
1750
+ ``` cpp
1751
+ friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
1752
+ ```
1753
+
1754
+ *Effects:* Equivalent to:
1755
+
1756
+ ``` cpp
1757
+ swap(x.ptr_, y.ptr_);
1758
+ swap(x.map_, y.map_);
1759
+ swap(x.acc_, y.acc_);
1760
+ ```
1761
+
1762
+ <!-- Link reference definitions -->
1763
+ [alg.equal]: algorithms.md#alg.equal
1764
+ [alg.sorting]: algorithms.md#alg.sorting
1765
+ [algorithm.stable]: library.md#algorithm.stable
1766
+ [algorithms]: algorithms.md#algorithms
1767
+ [algorithms.requirements]: algorithms.md#algorithms.requirements
1768
+ [allocator.requirements]: library.md#allocator.requirements
1769
+ [allocator.requirements.completeness]: library.md#allocator.requirements.completeness
1770
+ [allocator.traits.members]: mem.md#allocator.traits.members
1771
+ [allocator.uses.construction]: mem.md#allocator.uses.construction
1772
+ [array]: #array
1773
+ [array.cons]: #array.cons
1774
+ [array.creation]: #array.creation
1775
+ [array.members]: #array.members
1776
+ [array.overview]: #array.overview
1777
+ [array.special]: #array.special
1778
+ [array.syn]: #array.syn
1779
+ [array.tuple]: #array.tuple
1780
+ [array.zero]: #array.zero
1781
+ [associative]: #associative
1782
+ [associative.general]: #associative.general
1783
+ [associative.map.syn]: #associative.map.syn
1784
+ [associative.reqmts]: #associative.reqmts
1785
+ [associative.reqmts.except]: #associative.reqmts.except
1786
+ [associative.reqmts.general]: #associative.reqmts.general
1787
+ [associative.set.syn]: #associative.set.syn
1788
+ [basic.fundamental]: basic.md#basic.fundamental
1789
+ [basic.string]: strings.md#basic.string
1790
+ [class.copy.ctor]: class.md#class.copy.ctor
1791
+ [class.default.ctor]: class.md#class.default.ctor
1792
+ [class.dtor]: class.md#class.dtor
1793
+ [container.adaptors]: #container.adaptors
1794
+ [container.adaptors.format]: #container.adaptors.format
1795
+ [container.adaptors.general]: #container.adaptors.general
1796
+ [container.alloc.reqmts]: #container.alloc.reqmts
1797
+ [container.gen.reqmts]: #container.gen.reqmts
1798
+ [container.insert.return]: #container.insert.return
1799
+ [container.node]: #container.node
1800
+ [container.node.compat]: #container.node.compat
1801
+ [container.node.cons]: #container.node.cons
1802
+ [container.node.dtor]: #container.node.dtor
1803
+ [container.node.modifiers]: #container.node.modifiers
1804
+ [container.node.observers]: #container.node.observers
1805
+ [container.node.overview]: #container.node.overview
1806
+ [container.opt.reqmts]: #container.opt.reqmts
1807
+ [container.reqmts]: #container.reqmts
1808
+ [container.requirements]: #container.requirements
1809
+ [container.requirements.dataraces]: #container.requirements.dataraces
1810
+ [container.requirements.general]: #container.requirements.general
1811
+ [container.requirements.pre]: #container.requirements.pre
1812
+ [container.rev.reqmts]: #container.rev.reqmts
1813
+ [containers]: #containers
1814
+ [containers.general]: #containers.general
1815
+ [containers.summary]: #containers.summary
1816
+ [dcl.init.aggr]: dcl.md#dcl.init.aggr
1817
+ [defns.valid]: intro.md#defns.valid
1818
+ [deque]: #deque
1819
+ [deque.capacity]: #deque.capacity
1820
+ [deque.cons]: #deque.cons
1821
+ [deque.erasure]: #deque.erasure
1822
+ [deque.modifiers]: #deque.modifiers
1823
+ [deque.overview]: #deque.overview
1824
+ [deque.syn]: #deque.syn
1825
+ [expr.const]: expr.md#expr.const
1826
+ [flat.map]: #flat.map
1827
+ [flat.map.access]: #flat.map.access
1828
+ [flat.map.capacity]: #flat.map.capacity
1829
+ [flat.map.cons]: #flat.map.cons
1830
+ [flat.map.defn]: #flat.map.defn
1831
+ [flat.map.erasure]: #flat.map.erasure
1832
+ [flat.map.modifiers]: #flat.map.modifiers
1833
+ [flat.map.overview]: #flat.map.overview
1834
+ [flat.map.syn]: #flat.map.syn
1835
+ [flat.multimap]: #flat.multimap
1836
+ [flat.multimap.cons]: #flat.multimap.cons
1837
+ [flat.multimap.defn]: #flat.multimap.defn
1838
+ [flat.multimap.erasure]: #flat.multimap.erasure
1839
+ [flat.multimap.overview]: #flat.multimap.overview
1840
+ [flat.multiset]: #flat.multiset
1841
+ [flat.multiset.cons]: #flat.multiset.cons
1842
+ [flat.multiset.defn]: #flat.multiset.defn
1843
+ [flat.multiset.erasure]: #flat.multiset.erasure
1844
+ [flat.multiset.modifiers]: #flat.multiset.modifiers
1845
+ [flat.multiset.overview]: #flat.multiset.overview
1846
+ [flat.set]: #flat.set
1847
+ [flat.set.cons]: #flat.set.cons
1848
+ [flat.set.defn]: #flat.set.defn
1849
+ [flat.set.erasure]: #flat.set.erasure
1850
+ [flat.set.modifiers]: #flat.set.modifiers
1851
+ [flat.set.overview]: #flat.set.overview
1852
+ [flat.set.syn]: #flat.set.syn
1853
+ [forward.iterators]: iterators.md#forward.iterators
1854
+ [forward.list]: #forward.list
1855
+ [forward.list.access]: #forward.list.access
1856
+ [forward.list.cons]: #forward.list.cons
1857
+ [forward.list.erasure]: #forward.list.erasure
1858
+ [forward.list.iter]: #forward.list.iter
1859
+ [forward.list.modifiers]: #forward.list.modifiers
1860
+ [forward.list.ops]: #forward.list.ops
1861
+ [forward.list.overview]: #forward.list.overview
1862
+ [forward.list.syn]: #forward.list.syn
1863
+ [hash.requirements]: library.md#hash.requirements
1864
+ [iterator.concept.contiguous]: iterators.md#iterator.concept.contiguous
1865
+ [iterator.concept.random.access]: iterators.md#iterator.concept.random.access
1866
+ [iterator.requirements]: iterators.md#iterator.requirements
1867
+ [iterator.requirements.general]: iterators.md#iterator.requirements.general
1868
+ [list]: #list
1869
+ [list.capacity]: #list.capacity
1870
+ [list.cons]: #list.cons
1871
+ [list.erasure]: #list.erasure
1872
+ [list.modifiers]: #list.modifiers
1873
+ [list.ops]: #list.ops
1874
+ [list.overview]: #list.overview
1875
+ [list.syn]: #list.syn
1876
+ [map]: #map
1877
+ [map.access]: #map.access
1878
+ [map.cons]: #map.cons
1879
+ [map.erasure]: #map.erasure
1880
+ [map.modifiers]: #map.modifiers
1881
+ [map.overview]: #map.overview
1882
+ [mdspan.accessor]: #mdspan.accessor
1883
+ [mdspan.accessor.default]: #mdspan.accessor.default
1884
+ [mdspan.accessor.default.members]: #mdspan.accessor.default.members
1885
+ [mdspan.accessor.default.overview]: #mdspan.accessor.default.overview
1886
+ [mdspan.accessor.general]: #mdspan.accessor.general
1887
+ [mdspan.accessor.reqmts]: #mdspan.accessor.reqmts
1888
+ [mdspan.extents]: #mdspan.extents
1889
+ [mdspan.extents.cmp]: #mdspan.extents.cmp
1890
+ [mdspan.extents.cons]: #mdspan.extents.cons
1891
+ [mdspan.extents.dextents]: #mdspan.extents.dextents
1892
+ [mdspan.extents.expo]: #mdspan.extents.expo
1893
+ [mdspan.extents.obs]: #mdspan.extents.obs
1894
+ [mdspan.extents.overview]: #mdspan.extents.overview
1895
+ [mdspan.layout]: #mdspan.layout
1896
+ [mdspan.layout.general]: #mdspan.layout.general
1897
+ [mdspan.layout.left]: #mdspan.layout.left
1898
+ [mdspan.layout.left.cons]: #mdspan.layout.left.cons
1899
+ [mdspan.layout.left.obs]: #mdspan.layout.left.obs
1900
+ [mdspan.layout.left.overview]: #mdspan.layout.left.overview
1901
+ [mdspan.layout.policy.overview]: #mdspan.layout.policy.overview
1902
+ [mdspan.layout.policy.reqmts]: #mdspan.layout.policy.reqmts
1903
+ [mdspan.layout.reqmts]: #mdspan.layout.reqmts
1904
+ [mdspan.layout.right]: #mdspan.layout.right
1905
+ [mdspan.layout.right.cons]: #mdspan.layout.right.cons
1906
+ [mdspan.layout.right.obs]: #mdspan.layout.right.obs
1907
+ [mdspan.layout.right.overview]: #mdspan.layout.right.overview
1908
+ [mdspan.layout.stride]: #mdspan.layout.stride
1909
+ [mdspan.layout.stride.cons]: #mdspan.layout.stride.cons
1910
+ [mdspan.layout.stride.expo]: #mdspan.layout.stride.expo
1911
+ [mdspan.layout.stride.obs]: #mdspan.layout.stride.obs
1912
+ [mdspan.layout.stride.overview]: #mdspan.layout.stride.overview
1913
+ [mdspan.mdspan]: #mdspan.mdspan
1914
+ [mdspan.mdspan.cons]: #mdspan.mdspan.cons
1915
+ [mdspan.mdspan.members]: #mdspan.mdspan.members
1916
+ [mdspan.mdspan.overview]: #mdspan.mdspan.overview
1917
+ [mdspan.overview]: #mdspan.overview
1918
+ [mdspan.syn]: #mdspan.syn
1919
+ [multimap]: #multimap
1920
+ [multimap.cons]: #multimap.cons
1921
+ [multimap.erasure]: #multimap.erasure
1922
+ [multimap.modifiers]: #multimap.modifiers
1923
+ [multimap.overview]: #multimap.overview
1924
+ [multiset]: #multiset
1925
+ [multiset.cons]: #multiset.cons
1926
+ [multiset.erasure]: #multiset.erasure
1927
+ [multiset.overview]: #multiset.overview
1928
+ [priority.queue]: #priority.queue
1929
+ [priqueue.cons]: #priqueue.cons
1930
+ [priqueue.cons.alloc]: #priqueue.cons.alloc
1931
+ [priqueue.members]: #priqueue.members
1932
+ [priqueue.overview]: #priqueue.overview
1933
+ [priqueue.special]: #priqueue.special
1934
+ [queue]: #queue
1935
+ [queue.cons]: #queue.cons
1936
+ [queue.cons.alloc]: #queue.cons.alloc
1937
+ [queue.defn]: #queue.defn
1938
+ [queue.mod]: #queue.mod
1939
+ [queue.ops]: #queue.ops
1940
+ [queue.special]: #queue.special
1941
+ [queue.syn]: #queue.syn
1942
+ [random.access.iterators]: iterators.md#random.access.iterators
1943
+ [res.on.data.races]: library.md#res.on.data.races
1944
+ [sequence.reqmts]: #sequence.reqmts
1945
+ [sequences]: #sequences
1946
+ [sequences.general]: #sequences.general
1947
+ [set]: #set
1948
+ [set.cons]: #set.cons
1949
+ [set.erasure]: #set.erasure
1950
+ [set.overview]: #set.overview
1951
+ [span.cons]: #span.cons
1952
+ [span.deduct]: #span.deduct
1953
+ [span.elem]: #span.elem
1954
+ [span.iterators]: #span.iterators
1955
+ [span.objectrep]: #span.objectrep
1956
+ [span.obs]: #span.obs
1957
+ [span.overview]: #span.overview
1958
+ [span.sub]: #span.sub
1959
+ [span.syn]: #span.syn
1960
+ [stack]: #stack
1961
+ [stack.cons]: #stack.cons
1962
+ [stack.cons.alloc]: #stack.cons.alloc
1963
+ [stack.defn]: #stack.defn
1964
+ [stack.general]: #stack.general
1965
+ [stack.mod]: #stack.mod
1966
+ [stack.ops]: #stack.ops
1967
+ [stack.special]: #stack.special
1968
+ [stack.syn]: #stack.syn
1969
+ [strings]: strings.md#strings
1970
+ [swappable.requirements]: library.md#swappable.requirements
1971
+ [temp.deduct]: temp.md#temp.deduct
1972
+ [temp.param]: temp.md#temp.param
1973
+ [temp.type]: temp.md#temp.type
1974
+ [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
1975
+ [unord]: #unord
1976
+ [unord.general]: #unord.general
1977
+ [unord.hash]: utilities.md#unord.hash
1978
+ [unord.map]: #unord.map
1979
+ [unord.map.cnstr]: #unord.map.cnstr
1980
+ [unord.map.elem]: #unord.map.elem
1981
+ [unord.map.erasure]: #unord.map.erasure
1982
+ [unord.map.modifiers]: #unord.map.modifiers
1983
+ [unord.map.overview]: #unord.map.overview
1984
+ [unord.map.syn]: #unord.map.syn
1985
+ [unord.multimap]: #unord.multimap
1986
+ [unord.multimap.cnstr]: #unord.multimap.cnstr
1987
+ [unord.multimap.erasure]: #unord.multimap.erasure
1988
+ [unord.multimap.modifiers]: #unord.multimap.modifiers
1989
+ [unord.multimap.overview]: #unord.multimap.overview
1990
+ [unord.multiset]: #unord.multiset
1991
+ [unord.multiset.cnstr]: #unord.multiset.cnstr
1992
+ [unord.multiset.erasure]: #unord.multiset.erasure
1993
+ [unord.multiset.overview]: #unord.multiset.overview
1994
+ [unord.req]: #unord.req
1995
+ [unord.req.except]: #unord.req.except
1996
+ [unord.req.general]: #unord.req.general
1997
+ [unord.set]: #unord.set
1998
+ [unord.set.cnstr]: #unord.set.cnstr
1999
+ [unord.set.erasure]: #unord.set.erasure
2000
+ [unord.set.overview]: #unord.set.overview
2001
+ [unord.set.syn]: #unord.set.syn
2002
+ [vector]: #vector
2003
+ [vector.bool]: #vector.bool
2004
+ [vector.bool.fmt]: #vector.bool.fmt
2005
+ [vector.bool.pspc]: #vector.bool.pspc
2006
+ [vector.capacity]: #vector.capacity
2007
+ [vector.cons]: #vector.cons
2008
+ [vector.data]: #vector.data
2009
+ [vector.erasure]: #vector.erasure
2010
+ [vector.modifiers]: #vector.modifiers
2011
+ [vector.overview]: #vector.overview
2012
+ [vector.syn]: #vector.syn
2013
+ [views]: #views
2014
+ [views.contiguous]: #views.contiguous
2015
+ [views.general]: #views.general
2016
+ [views.multidim]: #views.multidim
2017
+ [views.span]: #views.span
2018
+
2019
+ [^1]: Equality comparison is a refinement of partitioning if no two
2020
+ objects that compare equal fall into different partitions.
2021
+
2022
+ [^2]: These member functions are only provided by containers whose
2023
+ iterators are random access iterators.
2024
+
2025
+ [^3]: As specified in  [[allocator.requirements]], the requirements in
2026
+ this Clause apply only to lists whose allocators compare equal.
2027
+
2028
+ [^4]: `reserve()` uses `Allocator::allocate()` which can throw an
2029
+ appropriate exception.