From Jason Turner

[mdspan.sub]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpqlvqd31s/{from.md → to.md} +910 -0
tmp/tmpqlvqd31s/{from.md → to.md} RENAMED
@@ -0,0 +1,910 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### `submdspan` <a id="mdspan.sub">[[mdspan.sub]]</a>
2
+
3
+ ##### Overview <a id="mdspan.sub.overview">[[mdspan.sub.overview]]</a>
4
+
5
+ The `submdspan` facilities create a new `mdspan` viewing a subset of
6
+ elements of an existing input `mdspan`. The subset viewed by the created
7
+ `mdspan` is determined by the `SliceSpecifier` arguments.
8
+
9
+ For each function defined in [[mdspan.sub]] that takes a parameter pack
10
+ named `slices` as an argument:
11
+
12
+ - let `index_type` be
13
+ - `M::index_type` if the function is a member of a class `M`,
14
+ - otherwise, `remove_reference_t<decltype(src)>::index_type` if the
15
+ function has a parameter named `src`,
16
+ - otherwise, the same type as the function’s template argument
17
+ `IndexType`;
18
+ - let `rank` be the number of elements in `slices`;
19
+ - let sₖ be the kᵗʰ element of `slices`;
20
+ - let Sₖ be the type of sₖ; and
21
+ - let `map-rank` be an `array<size_t, rank>` such that for each k in the
22
+ range \[`0`, `rank`), `map-rank[k]` equals:
23
+ - `dynamic_extent` if Sₖ models `convertible_to<index_type>`,
24
+ - otherwise, the number of types Sⱼ with j < k that do not model
25
+ `convertible_to<index_type>`.
26
+
27
+ ##### `strided_slice` <a id="mdspan.sub.strided.slice">[[mdspan.sub.strided.slice]]</a>
28
+
29
+ `strided_slice` represents a set of `extent` regularly spaced integer
30
+ indices. The indices start at `offset`, and increase by increments of
31
+ `stride`.
32
+
33
+ ``` cpp
34
+ namespace std {
35
+ template<class OffsetType, class ExtentType, class StrideType>
36
+ struct strided_slice {
37
+ using offset_type = OffsetType;
38
+ using extent_type = ExtentType;
39
+ using stride_type = StrideType;
40
+
41
+ [[no_unique_address]] offset_type offset{};
42
+ [[no_unique_address]] extent_type extent{};
43
+ [[no_unique_address]] stride_type stride{};
44
+ };
45
+ }
46
+ ```
47
+
48
+ `strided_slice` has the data members and special members specified
49
+ above. It has no base classes or members other than those specified.
50
+
51
+ *Mandates:* `OffsetType`, `ExtentType`, and `StrideType` are signed or
52
+ unsigned integer types, or model `integral-constant-like`.
53
+
54
+ [*Note 1*:
55
+
56
+ `strided_slice{.offset = 1, .extent = 10, .stride = 3}`
57
+
58
+ indicates the indices `1`, `4`, `7`, and `10`. Indices are selected from
59
+ the half-open interval \[`1`, `1 + 10`).
60
+
61
+ — *end note*]
62
+
63
+ ##### `submdspan_mapping_result` <a id="mdspan.sub.map.result">[[mdspan.sub.map.result]]</a>
64
+
65
+ Specializations of `submdspan_mapping_result` are returned by overloads
66
+ of `submdspan_mapping`.
67
+
68
+ ``` cpp
69
+ namespace std {
70
+ template<class LayoutMapping>
71
+ struct submdspan_mapping_result {
72
+ [[no_unique_address]] LayoutMapping mapping = LayoutMapping();
73
+ size_t offset{};
74
+ };
75
+ }
76
+ ```
77
+
78
+ `submdspan_mapping_result` has the data members and special members
79
+ specified above. It has no base classes or members other than those
80
+ specified.
81
+
82
+ `LayoutMapping` shall meet the layout mapping requirements
83
+ [[mdspan.layout.policy.reqmts]].
84
+
85
+ ##### Exposition-only helpers <a id="mdspan.sub.helpers">[[mdspan.sub.helpers]]</a>
86
+
87
+ ``` cpp
88
+ template<class T>
89
+ constexpr T de-ice(T val) { return val; }
90
+ template<integral-constant-like T>
91
+ constexpr auto de-ice(T) { return T::value; }
92
+
93
+ template<class IndexType, size_t k, class... SliceSpecifiers>
94
+ constexpr IndexType first_(SliceSpecifiers... slices);
95
+ ```
96
+
97
+ *Mandates:* `IndexType` is a signed or unsigned integer type.
98
+
99
+ Let φₖ denote the following value:
100
+
101
+ - sₖ if Sₖ models `convertible_to<IndexType>`;
102
+ - otherwise, `get<0>(`sₖ`)` if Sₖ models `index-pair-like<IndexType>`;
103
+ - otherwise, *`de-ice`*`(`sₖ`.offset)` if Sₖ is a specialization of
104
+ `strided_slice`;
105
+ - otherwise, `0`.
106
+
107
+ *Preconditions:* φₖ is representable as a value of type `IndexType`.
108
+
109
+ *Returns:* `extents<IndexType>::`*`index-cast`*`(`φₖ`)`.
110
+
111
+ ``` cpp
112
+ template<size_t k, class Extents, class... SliceSpecifiers>
113
+ constexpr auto last_(const Extents& src, SliceSpecifiers... slices);
114
+ ```
115
+
116
+ *Mandates:* `Extents` is a specialization of `extents`.
117
+
118
+ Let `index_type` be `typename Extents::index_type`.
119
+
120
+ Let λₖ denote the following value:
121
+
122
+ - *`de-ice`*`(`sₖ`) + 1` if Sₖ models `convertible_to<index_type>`;
123
+ otherwise
124
+ - `get<1>(`sₖ`)` if Sₖ models `index-pair-like<index_type>`; otherwise
125
+ - *`de-ice`*`(`sₖ`.offset)` `+` *`de-ice`*`(`sₖ`.extent)` if Sₖ is a
126
+ specialization of `strided_slice`; otherwise
127
+ - `src.extent(k)`.
128
+
129
+ *Preconditions:* λₖ is representable as a value of type `index_type`.
130
+
131
+ *Returns:* `Extents::`*`index-cast`*`(`λₖ`)`.
132
+
133
+ ``` cpp
134
+ template<class IndexType, size_t N, class... SliceSpecifiers>
135
+ constexpr array<IndexType, sizeof...(SliceSpecifiers)>
136
+ src-indices(const array<IndexType, N>& indices, SliceSpecifiers... slices);
137
+ ```
138
+
139
+ *Mandates:* `IndexType` is a signed or unsigned integer type.
140
+
141
+ *Returns:* An `array<IndexType, sizeof...(SliceSpecifiers)> src_idx`
142
+ such that for each k in the range \[`0`, `sizeof...(SliceSpecifiers)`),
143
+ `src_idx[`k`]` equals
144
+
145
+ - *`first_`*`<IndexType, `k`>(slices...)` for each k where
146
+ *`map-rank`*`[`k`]` equals `dynamic_extent`,
147
+ - otherwise, *`first_`*`<IndexType, `k`>(slices...)` `+`
148
+ `indices[`*`map-rank`*`[`k`]]`.
149
+
150
+ ##### `submdspan_extents` function <a id="mdspan.sub.extents">[[mdspan.sub.extents]]</a>
151
+
152
+ ``` cpp
153
+ template<class IndexType, size_t... Extents, class... SliceSpecifiers>
154
+ constexpr auto submdspan_extents(const extents<IndexType, Extents...>& src,
155
+ SliceSpecifiers... slices);
156
+ ```
157
+
158
+ *Constraints:* `sizeof...(slices)` equals `sizeof...(Extents)`.
159
+
160
+ *Mandates:* For each rank index k of `src.extents()`, exactly one of the
161
+ following is true:
162
+
163
+ - Sₖ models `convertible_to<IndexType>`,
164
+ - Sₖ models `index-pair-like<IndexType>`,
165
+ - `is_convertible_v<`Sₖ`, full_extent_t>` is `true`, or
166
+ - Sₖ is a specialization of `strided_slice`.
167
+
168
+ *Preconditions:* For each rank index k of `src.extents()`, all of the
169
+ following are `true`:
170
+
171
+ - if Sₖ is a specialization of `strided_slice`
172
+ - `$s_k$.extent` = 0, or
173
+ - `$s_k$.stride` > 0
174
+ - $0 \le \texttt{\textit{first_}<IndexType, $k$>(slices...)}$
175
+ $\le \texttt{\textit{last_}<$k$>(src, slices...)}$ ≤ `src.extent($k$)`
176
+
177
+ Let `SubExtents` be a specialization of `extents` such that:
178
+
179
+ - `SubExtents::rank()` equals the number of k such that Sₖ does not
180
+ model `convertible_to<IndexType>`; and
181
+ - for each rank index k of `Extents` such that
182
+ *`map-rank`*`[`k`] != dynamic_extent` is `true`,
183
+ `SubExtents::static_extent(`*`map-rank`*`[`k`])` equals:
184
+ - `Extents::static_extent(`k`)` if
185
+ `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; otherwise
186
+ - *`de-ice`*`(tuple_element_t<1, `Sₖ`>()) -`
187
+ *`de-ice`*`(tuple_element_t<0, `Sₖ`>())` if Sₖ models
188
+ `index-pair-like<IndexType>`, and both `tuple_element_t<0, `Sₖ`>`
189
+ and `tuple_element_t<1, `Sₖ`>` model `integral-constant-like`;
190
+ otherwise
191
+ - `0`, if Sₖ is a specialization of `strided_slice`, whose
192
+ `extent_type` models *`integral-constant-like`*, for which
193
+ `extent_type()` equals zero; otherwise
194
+ - `1 + (`*`de-ice`*`(`Sₖ`::extent_type()) - 1) /`
195
+ *`de-ice`*`(`Sₖ`::stride_type())`, if Sₖ is a specialization of
196
+ `strided_slice` whose `extent_type` and `stride_type` model
197
+ *`integral-constant-like`*;
198
+ - otherwise, `dynamic_extent`.
199
+
200
+ *Returns:* A value `ext` of type `SubExtents` such that for each k for
201
+ which *`map-rank`*`[`k`] != dynamic_extent` is `true`,
202
+ `ext.extent(`*`map-rank`*`[`k`])` equals:
203
+
204
+ - sₖ`.extent == 0 ? 0 : 1 + (`*`de-ice`*`(`sₖ`.extent) - 1) / `*`de-ice`*`(`sₖ`.stride)`
205
+ if Sₖ is a specialization of `strided_slice`,
206
+ - otherwise,
207
+ *`last_`*`<`k`>(src, slices...) - `*`first_`*`<IndexType, `k`>(slices...)`.
208
+
209
+ ##### Specializations of `submdspan_mapping` <a id="mdspan.sub.map">[[mdspan.sub.map]]</a>
210
+
211
+ ###### Common <a id="mdspan.sub.map.common">[[mdspan.sub.map.common]]</a>
212
+
213
+ The following elements apply to all functions in [[mdspan.sub.map]].
214
+
215
+ *Constraints:* `sizeof...(slices)` equals `extents_type::rank()`.
216
+
217
+ *Mandates:* For each rank index k of `extents()`, exactly one of the
218
+ following is true:
219
+
220
+ - Sₖ models `convertible_to<index_type>`,
221
+ - Sₖ models `index-pair-like<index_type>`,
222
+ - `is_convertible_v<Sₖ, full_extent_t>` is `true`, or
223
+ - Sₖ is a specialization of `strided_slice`.
224
+
225
+ *Preconditions:* For each rank index k of `extents()`, all of the
226
+ following are `true`:
227
+
228
+ - if Sₖ is a specialization of `strided_slice`, `sₖ.extent` is equal to
229
+ zero or `sₖ.stride` is greater than zero; and
230
+ - $0 \leq \tcode{\exposid{first_}<index_type, $k$>(slices...)} \\
231
+ \hphantom{0 } \leq \tcode{\exposid{last_}<$k$>(extents(), slices...)} \\
232
+ \hphantom{0 } \leq \tcode{extents().extent($k$)}$
233
+
234
+ Let `sub_ext` be the result of `submdspan_extents(extents(), slices...)`
235
+ and let `SubExtents` be `decltype(sub_ext)`.
236
+
237
+ Let `sub_strides` be an
238
+ `array<SubExtents::index_type, SubExtents::rank()>` such that for each
239
+ rank index k of `extents()` for which `map-rank[k]` is not
240
+ `dynamic_extent`, `sub_strides[map-rank[k]]` equals:
241
+
242
+ - `stride(k) * de-ice(sₖ.stride)` if Sₖ is a specialization of
243
+ `strided_slice` and `sₖ.stride < sₖ.extent` is `true`;
244
+ - otherwise, `stride(k)`.
245
+
246
+ Let `P` be a parameter pack such that
247
+ `is_same_v<make_index_sequence<rank()>, index_sequence<P...>>` is
248
+ `true`.
249
+
250
+ If `first_<index_type, k>(slices...)` equals `extents().extent(k)` for
251
+ any rank index k of `extents()`, then let `offset` be a value of type
252
+ `size_t` equal to `(*this).required_span_size()`. Otherwise, let
253
+ `offset` be a value of type `size_t` equal to
254
+ `(*this)(first_<index_type, P>(slices...)...)`.
255
+
256
+ Given a layout mapping type `M`, a type `S` is a *unit-stride slice for
257
+ `M`* if
258
+
259
+ - `S` is a specialization of `strided_slice` where `S::stride_type`
260
+ models `integral-constant-like` and `S::stride_type::value` equals
261
+ `1`,
262
+ - `S` models `index-pair-like<M::index_type>`, or
263
+ - `is_convertible_v<S, full_extent_t>` is `true`.
264
+
265
+ ###### `layout_left` specialization of `submdspan_mapping` <a id="mdspan.sub.map.left">[[mdspan.sub.map.left]]</a>
266
+
267
+ ``` cpp
268
+ template<class Extents>
269
+ template<class... SliceSpecifiers>
270
+ constexpr auto layout_left::mapping<Extents>::submdspan-mapping-impl(
271
+ SliceSpecifiers... slices) const -> see below;
272
+ ```
273
+
274
+ *Returns:*
275
+
276
+ - `submdspan_mapping_result{*this, 0}`, if `Extents::rank() == 0` is
277
+ `true`;
278
+ - otherwise,
279
+ `submdspan_mapping_result{layout_left::mapping(sub_ext), offset}`, if
280
+ `SubExtents::rank() == 0` is `true`;
281
+ - otherwise,
282
+ `submdspan_mapping_result{layout_left::mapping(sub_ext), offset}`, if
283
+ - for each k in the range \[`0`, `SubExtents::rank() - 1)`),
284
+ `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; and
285
+ - for k equal to `SubExtents::rank() - 1`, Sₖ is a unit-stride slice
286
+ for `mapping`;
287
+
288
+ \[*Note 2*: If the above conditions are true, all Sₖ with k larger
289
+ than `SubExtents::rank() - 1` are convertible to
290
+ `index_type`. — *end note*]
291
+ - otherwise,
292
+ ``` cpp
293
+ submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
294
+ offset}
295
+ ```
296
+
297
+ if for a value u for which u+1 is the smallest value p larger than
298
+ zero for which Sₚ is a unit-stride slice for `mapping`, the following
299
+ conditions are met:
300
+ - S₀ is a unit-stride slice for `mapping`; and
301
+ - for each k in the range \[u` + 1`, u` + SubExtents::rank() - 1`),
302
+ `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; and
303
+ - for k equal to u` + SubExtents::rank() - 1`, Sₖ is a unit-stride
304
+ slice for `mapping`;
305
+
306
+ and where `S_static` is:
307
+ - `dynamic_extent`, if `static_extent(`k`)` is `dynamic_extent` for
308
+ any k in the range \[`0`, u` + 1`),
309
+ - otherwise, the product of all values `static_extent(`k`)` for k in
310
+ the range \[`0`, u` + 1`);
311
+ - otherwise,
312
+ ``` cpp
313
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
314
+ ```
315
+
316
+ ###### `layout_right` specialization of `submdspan_mapping` <a id="mdspan.sub.map.right">[[mdspan.sub.map.right]]</a>
317
+
318
+ ``` cpp
319
+ template<class Extents>
320
+ template<class... SliceSpecifiers>
321
+ constexpr auto layout_right::mapping<Extents>::submdspan-mapping-impl(
322
+ SliceSpecifiers... slices) const -> see below;
323
+ ```
324
+
325
+ *Returns:*
326
+
327
+ - `submdspan_mapping_result{*this, 0}`, if `Extents::rank() == 0` is
328
+ `true`;
329
+ - otherwise,
330
+ `submdspan_mapping_result{layout_right::mapping(sub_ext), offset}`, if
331
+ `SubExtents::rank() == 0` is `true`;
332
+ - otherwise,
333
+ `submdspan_mapping_result{layout_right::mapping(sub_ext), offset}`, if
334
+ - for each k in the range \[*`rank_`*` - SubExtents::rank() + 1`,
335
+ *`rank_`*), `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; and
336
+ - for k equal to *rank\_* - `SubExtents::rank()`, Sₖ is a unit-stride
337
+ slice for `mapping`;
338
+
339
+ \[*Note 3*: If the above conditions are true, all Sₖ with
340
+ $k < \texttt{\textit{rank_} - SubExtents::rank()}$ are convertible to
341
+ `index_type`. — *end note*]
342
+ - otherwise,
343
+ ``` cpp
344
+ submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
345
+ stride(rank_ - u - 2)), offset}
346
+ ```
347
+
348
+ if for a value u for which rank_ - u - 2 is the largest value p
349
+ smaller than *`rank_`*` - 1` for which Sₚ is a unit-stride slice for
350
+ `mapping`, the following conditions are met:
351
+ - for k equal to *`rank_`*` - 1`, Sₖ is a unit-stride slice for
352
+ `mapping`; and
353
+ - for each k in the range
354
+ \[*`rank_`*` - SubExtents::rank() - `u` + 1`,
355
+ *`rank_`*` - `u` - 1`), `is_convertible_v<`Sₖ`, full_extent_t>` is
356
+ `true`; and
357
+ - for k equal to *`rank_`*` - SubExtents::rank() - `u, Sₖ is a
358
+ unit-stride slice for `mapping`;
359
+
360
+ and where `S_static` is:
361
+ - `dynamic_extent`, if `static_extent(`k`)` is `dynamic_extent` for
362
+ any k in the range \[*`rank_`*` - `u` - 1`, *`rank_`*),
363
+ - otherwise, the product of all values `static_extent(`k`)` for k in
364
+ the range \[*`rank_`*` - `u` - 1`, *`rank_`*);
365
+ - otherwise,
366
+ ``` cpp
367
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
368
+ ```
369
+
370
+ ###### `layout_stride` specialization of `submdspan_mapping` <a id="mdspan.sub.map.stride">[[mdspan.sub.map.stride]]</a>
371
+
372
+ ``` cpp
373
+ template<class Extents>
374
+ template<class... SliceSpecifiers>
375
+ constexpr auto layout_stride::mapping<Extents>::submdspan-mapping-impl(
376
+ SliceSpecifiers... slices) const -> see below;
377
+ ```
378
+
379
+ *Returns:*
380
+
381
+ - `submdspan_mapping_result{*this, 0}`, if `Extents::rank() == 0` is
382
+ `true`;
383
+ - otherwise,
384
+ ``` cpp
385
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
386
+ ```
387
+
388
+ ###### `layout_left_padded` specialization of `submdspan_mapping` <a id="mdspan.sub.map.leftpad">[[mdspan.sub.map.leftpad]]</a>
389
+
390
+ ``` cpp
391
+ template<class Extents>
392
+ template<class... SliceSpecifiers>
393
+ constexpr auto layout_left_padded::mapping<Extents>::submdspan-mapping-impl(
394
+ SliceSpecifiers... slices) const -> see below;
395
+ ```
396
+
397
+ *Returns:*
398
+
399
+ - `submdspan_mapping_result{*this, 0}`, if `Extents::rank() == 0` is
400
+ `true`;
401
+ - otherwise,
402
+ `submdspan_mapping_result{layout_left::mapping(sub_ext), offset}`, if
403
+ *`rank_`*` == 1` is `true` or `SubExtents::rank() == 0` is `true`;
404
+ - otherwise,
405
+ `submdspan_mapping_result{layout_left::mapping(sub_ext), offset}`, if
406
+ - `SubExtents::rank() == 1` is `true` and
407
+ - S₀ is a unit-stride slice for `mapping`;
408
+ - otherwise,
409
+ ``` cpp
410
+ submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
411
+ offset}
412
+ ```
413
+
414
+ if for a value u for which u` + 1` is the smallest value p larger than
415
+ zero for which Sₚ is a unit-stride slice for `mapping`, the following
416
+ conditions are met:
417
+ - S₀ is a unit-stride slice for `mapping`; and
418
+ - for each k in the range \[u` + 1`, u` + SubExtents::rank() - 1`),
419
+ `is_convertible_v<`Sₖ`, full_extent_t>` is `true`; and
420
+ - for k equal to u` + SubExtents::rank() - 1`, Sₖ is a unit-stride
421
+ slice for `mapping`;
422
+
423
+ where `S_static` is:
424
+ - `dynamic_extent`, if *static-padding-stride* is `dynamic_extent` or
425
+ `static_extent(`k`)` is `dynamic_extent` for any k in the range
426
+ \[`1`, u` + 1`),
427
+ - otherwise, the product of *static-padding-stride* and all values
428
+ `static_extent(`k`)` for k in the range \[`1`, u` + 1`);
429
+ - otherwise,
430
+ ``` cpp
431
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
432
+ ```
433
+
434
+ ###### `layout_right_padded` specialization of `submdspan_mapping` <a id="mdspan.sub.map.rightpad">[[mdspan.sub.map.rightpad]]</a>
435
+
436
+ ``` cpp
437
+ template<class Extents>
438
+ template<class... SliceSpecifiers>
439
+ constexpr auto layout_right_padded::mapping<Extents>::submdspan-mapping-impl(
440
+ SliceSpecifiers... slices) const -> see below;
441
+ ```
442
+
443
+ *Returns:*
444
+
445
+ - `submdspan_mapping_result{*this, 0}`, if *`rank_`*` == 0` is `true`;
446
+ - otherwise,
447
+ `submdspan_mapping_result{layout_right::mapping(sub_ext), offset}`, if
448
+ *`rank_`*` == 1` is `true` or `SubExtents::rank() == 0` is `true`;
449
+ - otherwise,
450
+ `submdspan_mapping_result{layout_right::mapping(sub_ext), offset}`, if
451
+ - `SubExtents::rank() == 1` is `true` and
452
+ - for k equal to *`rank_`*` - 1`, Sₖ is a unit-stride slice for
453
+ `mapping`;
454
+ - otherwise,
455
+ ``` cpp
456
+ submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
457
+ stride(rank_ - u - 2)), offset}
458
+ ```
459
+
460
+ if for a value u for which *`rank_`*` - `u` - 2` is the largest value
461
+ p smaller than *`rank_`*` - 1` for which Sₚ is a unit-stride slice for
462
+ `mapping`, the following conditions are met:
463
+ - for k equal to *`rank_`*` - 1`, Sₖ is a unit-stride slice for
464
+ `mapping`; and
465
+ - for each k in the range
466
+ \[*`rank_`*` - SubExtents::rank() - `u` + 1`,
467
+ *`rank_`*` - `u` - 1)`), `is_convertible_v<`Sₖ`, full_extent_t>` is
468
+ `true`; and
469
+ - for k equal to *`rank_`*` - SubExtents::rank() - `u, Sₖ is a
470
+ unit-stride slice for `mapping`;
471
+
472
+ and where `S_static` is:
473
+ - `dynamic_extent` if *static-padding-stride* is `dynamic_extent` or
474
+ for any k in the range \[*`rank_`*` - `u` - 1`, *`rank_`*` - 1`)
475
+ `static_extent(`k`)` is `dynamic_extent`,
476
+ - otherwise, the product of *static-padding-stride* and all values
477
+ `static_extent(`k`)` with k in the range \[*`rank_`*` - `u` - 1`,
478
+ *`rank_`*` - 1`);
479
+ - otherwise,
480
+ ``` cpp
481
+ submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
482
+ ```
483
+
484
+ ##### `submdspan` function template <a id="mdspan.sub.sub">[[mdspan.sub.sub]]</a>
485
+
486
+ ``` cpp
487
+ template<class ElementType, class Extents, class LayoutPolicy,
488
+ class AccessorPolicy, class... SliceSpecifiers>
489
+ constexpr auto submdspan(
490
+ const mdspan<ElementType, Extents, LayoutPolicy, AccessorPolicy>& src,
491
+ SliceSpecifiers... slices) -> see below;
492
+ ```
493
+
494
+ Let `index_type` be `typename Extents::index_type`.
495
+
496
+ Let `sub_map_offset` be the result of
497
+ `submdspan_mapping(src.mapping(), slices...)`.
498
+
499
+ [*Note 1*: This invocation of `submdspan_mapping` selects a function
500
+ call via overload resolution on a candidate set that includes the lookup
501
+ set found by argument-dependent
502
+ lookup [[basic.lookup.argdep]]. — *end note*]
503
+
504
+ *Constraints:*
505
+
506
+ - `sizeof...(slices)` equals `Extents::rank()`, and
507
+ - the expression `submdspan_mapping(src.mapping(), slices...)` is
508
+ well-formed when treated as an unevaluated operand.
509
+
510
+ *Mandates:*
511
+
512
+ - `decltype(submdspan_mapping(src.mapping(), slices...))` is a
513
+ specialization of `submd-span_mapping_result`.
514
+ - `is_same_v<remove_cvref_t<decltype(sub_map_offset.mapping.extents())>,`
515
+ `decltype(submdspan_extents(src.mapping(), slices...))>` is `true`.
516
+ - For each rank index k of `src.extents()`, exactly one of the following
517
+ is true:
518
+ - Sₖ models `convertible_to<index_type>`,
519
+ - Sₖ models `index-pair-like<index_type>`,
520
+ - `is_convertible_v<`Sₖ`, full_extent_t>` is `true`, or
521
+ - Sₖ is a specialization of `strided_slice`.
522
+
523
+ *Preconditions:*
524
+
525
+ - For each rank index k of `src.extents()`, all of the following are
526
+ `true`:
527
+ - if Sₖ is a specialization of `strided_slice`
528
+ - `$s_k$.extent` = 0, or
529
+ - `$s_k$.stride` > 0
530
+ - $0 \le \texttt{\textit{first_}<index_type, $k$>(slices...)}$
531
+ $\le \texttt{\textit{last_}<$k$>(src.extents(), slices...)}$
532
+ ≤ `{}src.extent($k$)`
533
+ - `sub_map_offset.mapping.extents() == submdspan_extents(src.mapping(), slices...)`
534
+ is `true`; and
535
+ - for each integer pack `I` which is a multidimensional index in
536
+ `sub_map_offset.mapping.extents()`,
537
+ ``` cpp
538
+ sub_map_offset.mapping(I...) + sub_map_offset.offset ==
539
+ src.mapping()(src-indices(array{I...}, slices...))
540
+ ```
541
+
542
+ is `true`.
543
+
544
+ [*Note 2*: These conditions ensure that the mapping returned by
545
+ `submdspan_mapping` matches the algorithmically expected index-mapping
546
+ given the slice specifiers. — *end note*]
547
+
548
+ *Effects:* Equivalent to:
549
+
550
+ ``` cpp
551
+ auto sub_map_result = submdspan_mapping(src.mapping(), slices...);
552
+ return mdspan(src.accessor().offset(src.data_handle(), sub_map_result.offset),
553
+ sub_map_result.mapping,
554
+ typename AccessorPolicy::offset_policy(src.accessor()));
555
+ ```
556
+
557
+ [*Example 1*:
558
+
559
+ Given a rank-3 `mdspan grid3d` representing a three-dimensional grid of
560
+ regularly spaced points in a rectangular prism, the function
561
+ `zero_surface` sets all elements on the surface of the 3-dimensional
562
+ shape to zero. It does so by reusing a function `zero_2d` that takes a
563
+ rank-2 `mdspan`.
564
+
565
+ ``` cpp
566
+ // zero out all elements in an mdspan
567
+ template<class T, class E, class L, class A>
568
+ void zero_2d(mdspan<T, E, L, A> a) {
569
+ static_assert(a.rank() == 2);
570
+ for (int i = 0; i < a.extent(0); i++)
571
+ for (int j = 0; j < a.extent(1); j++)
572
+ a[i, j] = 0;
573
+ }
574
+
575
+ // zero out just the surface
576
+ template<class T, class E, class L, class A>
577
+ void zero_surface(mdspan<T, E, L, A> grid3d) {
578
+ static_assert(grid3d.rank() == 3);
579
+ zero_2d(submdspan(grid3d, 0, full_extent, full_extent));
580
+ zero_2d(submdspan(grid3d, full_extent, 0, full_extent));
581
+ zero_2d(submdspan(grid3d, full_extent, full_extent, 0));
582
+ zero_2d(submdspan(grid3d, grid3d.extent(0) - 1, full_extent, full_extent));
583
+ zero_2d(submdspan(grid3d, full_extent, grid3d.extent(1) - 1, full_extent));
584
+ zero_2d(submdspan(grid3d, full_extent, full_extent, grid3d.extent(2) - 1));
585
+ }
586
+ ```
587
+
588
+ — *end example*]
589
+
590
+ <!-- Link reference definitions -->
591
+ [alg.equal]: algorithms.md#alg.equal
592
+ [alg.sorting]: algorithms.md#alg.sorting
593
+ [algorithm.stable]: library.md#algorithm.stable
594
+ [algorithms]: algorithms.md#algorithms
595
+ [algorithms.requirements]: algorithms.md#algorithms.requirements
596
+ [allocator.requirements]: library.md#allocator.requirements
597
+ [allocator.requirements.completeness]: library.md#allocator.requirements.completeness
598
+ [allocator.traits.members]: mem.md#allocator.traits.members
599
+ [allocator.uses.construction]: mem.md#allocator.uses.construction
600
+ [array]: #array
601
+ [array.cons]: #array.cons
602
+ [array.creation]: #array.creation
603
+ [array.members]: #array.members
604
+ [array.overview]: #array.overview
605
+ [array.special]: #array.special
606
+ [array.syn]: #array.syn
607
+ [array.tuple]: #array.tuple
608
+ [array.zero]: #array.zero
609
+ [associative]: #associative
610
+ [associative.general]: #associative.general
611
+ [associative.map.syn]: #associative.map.syn
612
+ [associative.reqmts]: #associative.reqmts
613
+ [associative.reqmts.except]: #associative.reqmts.except
614
+ [associative.reqmts.general]: #associative.reqmts.general
615
+ [associative.set.syn]: #associative.set.syn
616
+ [basic.fundamental]: basic.md#basic.fundamental
617
+ [basic.lookup.argdep]: basic.md#basic.lookup.argdep
618
+ [basic.string]: strings.md#basic.string
619
+ [class.copy.ctor]: class.md#class.copy.ctor
620
+ [class.default.ctor]: class.md#class.default.ctor
621
+ [class.dtor]: class.md#class.dtor
622
+ [container.adaptors]: #container.adaptors
623
+ [container.adaptors.format]: #container.adaptors.format
624
+ [container.adaptors.general]: #container.adaptors.general
625
+ [container.alloc.reqmts]: #container.alloc.reqmts
626
+ [container.insert.return]: #container.insert.return
627
+ [container.intro.reqmts]: #container.intro.reqmts
628
+ [container.node]: #container.node
629
+ [container.node.compat]: #container.node.compat
630
+ [container.node.cons]: #container.node.cons
631
+ [container.node.dtor]: #container.node.dtor
632
+ [container.node.modifiers]: #container.node.modifiers
633
+ [container.node.observers]: #container.node.observers
634
+ [container.node.overview]: #container.node.overview
635
+ [container.opt.reqmts]: #container.opt.reqmts
636
+ [container.reqmts]: #container.reqmts
637
+ [container.requirements]: #container.requirements
638
+ [container.requirements.dataraces]: #container.requirements.dataraces
639
+ [container.requirements.general]: #container.requirements.general
640
+ [container.requirements.pre]: #container.requirements.pre
641
+ [container.rev.reqmts]: #container.rev.reqmts
642
+ [containers]: #containers
643
+ [containers.general]: #containers.general
644
+ [containers.summary]: #containers.summary
645
+ [dcl.init.aggr]: dcl.md#dcl.init.aggr
646
+ [defns.valid]: intro.md#defns.valid
647
+ [deque]: #deque
648
+ [deque.capacity]: #deque.capacity
649
+ [deque.cons]: #deque.cons
650
+ [deque.erasure]: #deque.erasure
651
+ [deque.modifiers]: #deque.modifiers
652
+ [deque.overview]: #deque.overview
653
+ [deque.syn]: #deque.syn
654
+ [expr.const]: expr.md#expr.const
655
+ [flat.map]: #flat.map
656
+ [flat.map.access]: #flat.map.access
657
+ [flat.map.capacity]: #flat.map.capacity
658
+ [flat.map.cons]: #flat.map.cons
659
+ [flat.map.cons.alloc]: #flat.map.cons.alloc
660
+ [flat.map.defn]: #flat.map.defn
661
+ [flat.map.erasure]: #flat.map.erasure
662
+ [flat.map.modifiers]: #flat.map.modifiers
663
+ [flat.map.overview]: #flat.map.overview
664
+ [flat.map.syn]: #flat.map.syn
665
+ [flat.multimap]: #flat.multimap
666
+ [flat.multimap.cons]: #flat.multimap.cons
667
+ [flat.multimap.cons.alloc]: #flat.multimap.cons.alloc
668
+ [flat.multimap.defn]: #flat.multimap.defn
669
+ [flat.multimap.erasure]: #flat.multimap.erasure
670
+ [flat.multimap.overview]: #flat.multimap.overview
671
+ [flat.multiset]: #flat.multiset
672
+ [flat.multiset.cons]: #flat.multiset.cons
673
+ [flat.multiset.cons.alloc]: #flat.multiset.cons.alloc
674
+ [flat.multiset.defn]: #flat.multiset.defn
675
+ [flat.multiset.erasure]: #flat.multiset.erasure
676
+ [flat.multiset.modifiers]: #flat.multiset.modifiers
677
+ [flat.multiset.overview]: #flat.multiset.overview
678
+ [flat.set]: #flat.set
679
+ [flat.set.cons]: #flat.set.cons
680
+ [flat.set.cons.alloc]: #flat.set.cons.alloc
681
+ [flat.set.defn]: #flat.set.defn
682
+ [flat.set.erasure]: #flat.set.erasure
683
+ [flat.set.modifiers]: #flat.set.modifiers
684
+ [flat.set.overview]: #flat.set.overview
685
+ [flat.set.syn]: #flat.set.syn
686
+ [forward.iterators]: iterators.md#forward.iterators
687
+ [forward.list]: #forward.list
688
+ [forward.list.access]: #forward.list.access
689
+ [forward.list.cons]: #forward.list.cons
690
+ [forward.list.erasure]: #forward.list.erasure
691
+ [forward.list.iter]: #forward.list.iter
692
+ [forward.list.modifiers]: #forward.list.modifiers
693
+ [forward.list.ops]: #forward.list.ops
694
+ [forward.list.overview]: #forward.list.overview
695
+ [forward.list.syn]: #forward.list.syn
696
+ [hash.requirements]: library.md#hash.requirements
697
+ [hive]: #hive
698
+ [hive.capacity]: #hive.capacity
699
+ [hive.cons]: #hive.cons
700
+ [hive.erasure]: #hive.erasure
701
+ [hive.modifiers]: #hive.modifiers
702
+ [hive.operations]: #hive.operations
703
+ [hive.overview]: #hive.overview
704
+ [hive.syn]: #hive.syn
705
+ [inplace.vector]: #inplace.vector
706
+ [inplace.vector.capacity]: #inplace.vector.capacity
707
+ [inplace.vector.cons]: #inplace.vector.cons
708
+ [inplace.vector.data]: #inplace.vector.data
709
+ [inplace.vector.erasure]: #inplace.vector.erasure
710
+ [inplace.vector.modifiers]: #inplace.vector.modifiers
711
+ [inplace.vector.overview]: #inplace.vector.overview
712
+ [inplace.vector.syn]: #inplace.vector.syn
713
+ [iterator.concept.contiguous]: iterators.md#iterator.concept.contiguous
714
+ [iterator.concept.random.access]: iterators.md#iterator.concept.random.access
715
+ [iterator.requirements]: iterators.md#iterator.requirements
716
+ [iterator.requirements.general]: iterators.md#iterator.requirements.general
717
+ [list]: #list
718
+ [list.capacity]: #list.capacity
719
+ [list.cons]: #list.cons
720
+ [list.erasure]: #list.erasure
721
+ [list.modifiers]: #list.modifiers
722
+ [list.ops]: #list.ops
723
+ [list.overview]: #list.overview
724
+ [list.syn]: #list.syn
725
+ [map]: #map
726
+ [map.access]: #map.access
727
+ [map.cons]: #map.cons
728
+ [map.erasure]: #map.erasure
729
+ [map.modifiers]: #map.modifiers
730
+ [map.overview]: #map.overview
731
+ [mdspan.accessor]: #mdspan.accessor
732
+ [mdspan.accessor.aligned]: #mdspan.accessor.aligned
733
+ [mdspan.accessor.aligned.members]: #mdspan.accessor.aligned.members
734
+ [mdspan.accessor.aligned.overview]: #mdspan.accessor.aligned.overview
735
+ [mdspan.accessor.default]: #mdspan.accessor.default
736
+ [mdspan.accessor.default.members]: #mdspan.accessor.default.members
737
+ [mdspan.accessor.default.overview]: #mdspan.accessor.default.overview
738
+ [mdspan.accessor.general]: #mdspan.accessor.general
739
+ [mdspan.accessor.reqmts]: #mdspan.accessor.reqmts
740
+ [mdspan.extents]: #mdspan.extents
741
+ [mdspan.extents.cmp]: #mdspan.extents.cmp
742
+ [mdspan.extents.cons]: #mdspan.extents.cons
743
+ [mdspan.extents.dextents]: #mdspan.extents.dextents
744
+ [mdspan.extents.dims]: #mdspan.extents.dims
745
+ [mdspan.extents.expo]: #mdspan.extents.expo
746
+ [mdspan.extents.obs]: #mdspan.extents.obs
747
+ [mdspan.extents.overview]: #mdspan.extents.overview
748
+ [mdspan.layout]: #mdspan.layout
749
+ [mdspan.layout.general]: #mdspan.layout.general
750
+ [mdspan.layout.left]: #mdspan.layout.left
751
+ [mdspan.layout.left.cons]: #mdspan.layout.left.cons
752
+ [mdspan.layout.left.obs]: #mdspan.layout.left.obs
753
+ [mdspan.layout.left.overview]: #mdspan.layout.left.overview
754
+ [mdspan.layout.leftpad]: #mdspan.layout.leftpad
755
+ [mdspan.layout.leftpad.cons]: #mdspan.layout.leftpad.cons
756
+ [mdspan.layout.leftpad.expo]: #mdspan.layout.leftpad.expo
757
+ [mdspan.layout.leftpad.obs]: #mdspan.layout.leftpad.obs
758
+ [mdspan.layout.leftpad.overview]: #mdspan.layout.leftpad.overview
759
+ [mdspan.layout.policy.overview]: #mdspan.layout.policy.overview
760
+ [mdspan.layout.policy.reqmts]: #mdspan.layout.policy.reqmts
761
+ [mdspan.layout.reqmts]: #mdspan.layout.reqmts
762
+ [mdspan.layout.right]: #mdspan.layout.right
763
+ [mdspan.layout.right.cons]: #mdspan.layout.right.cons
764
+ [mdspan.layout.right.obs]: #mdspan.layout.right.obs
765
+ [mdspan.layout.right.overview]: #mdspan.layout.right.overview
766
+ [mdspan.layout.rightpad]: #mdspan.layout.rightpad
767
+ [mdspan.layout.rightpad.cons]: #mdspan.layout.rightpad.cons
768
+ [mdspan.layout.rightpad.expo]: #mdspan.layout.rightpad.expo
769
+ [mdspan.layout.rightpad.obs]: #mdspan.layout.rightpad.obs
770
+ [mdspan.layout.rightpad.overview]: #mdspan.layout.rightpad.overview
771
+ [mdspan.layout.stride]: #mdspan.layout.stride
772
+ [mdspan.layout.stride.cons]: #mdspan.layout.stride.cons
773
+ [mdspan.layout.stride.expo]: #mdspan.layout.stride.expo
774
+ [mdspan.layout.stride.obs]: #mdspan.layout.stride.obs
775
+ [mdspan.layout.stride.overview]: #mdspan.layout.stride.overview
776
+ [mdspan.mdspan]: #mdspan.mdspan
777
+ [mdspan.mdspan.cons]: #mdspan.mdspan.cons
778
+ [mdspan.mdspan.members]: #mdspan.mdspan.members
779
+ [mdspan.mdspan.overview]: #mdspan.mdspan.overview
780
+ [mdspan.overview]: #mdspan.overview
781
+ [mdspan.sub]: #mdspan.sub
782
+ [mdspan.sub.extents]: #mdspan.sub.extents
783
+ [mdspan.sub.helpers]: #mdspan.sub.helpers
784
+ [mdspan.sub.map]: #mdspan.sub.map
785
+ [mdspan.sub.map.common]: #mdspan.sub.map.common
786
+ [mdspan.sub.map.left]: #mdspan.sub.map.left
787
+ [mdspan.sub.map.leftpad]: #mdspan.sub.map.leftpad
788
+ [mdspan.sub.map.result]: #mdspan.sub.map.result
789
+ [mdspan.sub.map.right]: #mdspan.sub.map.right
790
+ [mdspan.sub.map.rightpad]: #mdspan.sub.map.rightpad
791
+ [mdspan.sub.map.stride]: #mdspan.sub.map.stride
792
+ [mdspan.sub.overview]: #mdspan.sub.overview
793
+ [mdspan.sub.strided.slice]: #mdspan.sub.strided.slice
794
+ [mdspan.sub.sub]: #mdspan.sub.sub
795
+ [mdspan.syn]: #mdspan.syn
796
+ [multimap]: #multimap
797
+ [multimap.cons]: #multimap.cons
798
+ [multimap.erasure]: #multimap.erasure
799
+ [multimap.modifiers]: #multimap.modifiers
800
+ [multimap.overview]: #multimap.overview
801
+ [multiset]: #multiset
802
+ [multiset.cons]: #multiset.cons
803
+ [multiset.erasure]: #multiset.erasure
804
+ [multiset.overview]: #multiset.overview
805
+ [priority.queue]: #priority.queue
806
+ [priqueue.cons]: #priqueue.cons
807
+ [priqueue.cons.alloc]: #priqueue.cons.alloc
808
+ [priqueue.members]: #priqueue.members
809
+ [priqueue.overview]: #priqueue.overview
810
+ [priqueue.special]: #priqueue.special
811
+ [queue]: #queue
812
+ [queue.cons]: #queue.cons
813
+ [queue.cons.alloc]: #queue.cons.alloc
814
+ [queue.defn]: #queue.defn
815
+ [queue.mod]: #queue.mod
816
+ [queue.ops]: #queue.ops
817
+ [queue.special]: #queue.special
818
+ [queue.syn]: #queue.syn
819
+ [random.access.iterators]: iterators.md#random.access.iterators
820
+ [re.results]: text.md#re.results
821
+ [res.on.data.races]: library.md#res.on.data.races
822
+ [sequence.reqmts]: #sequence.reqmts
823
+ [sequences]: #sequences
824
+ [sequences.general]: #sequences.general
825
+ [set]: #set
826
+ [set.cons]: #set.cons
827
+ [set.erasure]: #set.erasure
828
+ [set.modifiers]: #set.modifiers
829
+ [set.overview]: #set.overview
830
+ [span.cons]: #span.cons
831
+ [span.deduct]: #span.deduct
832
+ [span.elem]: #span.elem
833
+ [span.iterators]: #span.iterators
834
+ [span.objectrep]: #span.objectrep
835
+ [span.obs]: #span.obs
836
+ [span.overview]: #span.overview
837
+ [span.sub]: #span.sub
838
+ [span.syn]: #span.syn
839
+ [stack]: #stack
840
+ [stack.cons]: #stack.cons
841
+ [stack.cons.alloc]: #stack.cons.alloc
842
+ [stack.defn]: #stack.defn
843
+ [stack.general]: #stack.general
844
+ [stack.mod]: #stack.mod
845
+ [stack.ops]: #stack.ops
846
+ [stack.special]: #stack.special
847
+ [stack.syn]: #stack.syn
848
+ [stacktrace.basic]: diagnostics.md#stacktrace.basic
849
+ [strings]: strings.md#strings
850
+ [swappable.requirements]: library.md#swappable.requirements
851
+ [temp.deduct]: temp.md#temp.deduct
852
+ [temp.type]: temp.md#temp.type
853
+ [term.structural.type]: temp.md#term.structural.type
854
+ [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
855
+ [unord]: #unord
856
+ [unord.general]: #unord.general
857
+ [unord.hash]: utilities.md#unord.hash
858
+ [unord.map]: #unord.map
859
+ [unord.map.cnstr]: #unord.map.cnstr
860
+ [unord.map.elem]: #unord.map.elem
861
+ [unord.map.erasure]: #unord.map.erasure
862
+ [unord.map.modifiers]: #unord.map.modifiers
863
+ [unord.map.overview]: #unord.map.overview
864
+ [unord.map.syn]: #unord.map.syn
865
+ [unord.multimap]: #unord.multimap
866
+ [unord.multimap.cnstr]: #unord.multimap.cnstr
867
+ [unord.multimap.erasure]: #unord.multimap.erasure
868
+ [unord.multimap.modifiers]: #unord.multimap.modifiers
869
+ [unord.multimap.overview]: #unord.multimap.overview
870
+ [unord.multiset]: #unord.multiset
871
+ [unord.multiset.cnstr]: #unord.multiset.cnstr
872
+ [unord.multiset.erasure]: #unord.multiset.erasure
873
+ [unord.multiset.overview]: #unord.multiset.overview
874
+ [unord.req]: #unord.req
875
+ [unord.req.except]: #unord.req.except
876
+ [unord.req.general]: #unord.req.general
877
+ [unord.set]: #unord.set
878
+ [unord.set.cnstr]: #unord.set.cnstr
879
+ [unord.set.erasure]: #unord.set.erasure
880
+ [unord.set.modifiers]: #unord.set.modifiers
881
+ [unord.set.overview]: #unord.set.overview
882
+ [unord.set.syn]: #unord.set.syn
883
+ [vector]: #vector
884
+ [vector.bool]: #vector.bool
885
+ [vector.bool.fmt]: #vector.bool.fmt
886
+ [vector.bool.pspc]: #vector.bool.pspc
887
+ [vector.capacity]: #vector.capacity
888
+ [vector.cons]: #vector.cons
889
+ [vector.data]: #vector.data
890
+ [vector.erasure]: #vector.erasure
891
+ [vector.modifiers]: #vector.modifiers
892
+ [vector.overview]: #vector.overview
893
+ [vector.syn]: #vector.syn
894
+ [views]: #views
895
+ [views.contiguous]: #views.contiguous
896
+ [views.general]: #views.general
897
+ [views.multidim]: #views.multidim
898
+ [views.span]: #views.span
899
+
900
+ [^1]: Equality comparison is a refinement of partitioning if no two
901
+ objects that compare equal fall into different partitions.
902
+
903
+ [^2]: These member functions are only provided by containers whose
904
+ iterators are random access iterators.
905
+
906
+ [^3]: As specified in  [[allocator.requirements]], the requirements in
907
+ this Clause apply only to lists whose allocators compare equal.
908
+
909
+ [^4]: `reserve()` uses `Allocator::allocate()` which can throw an
910
+ appropriate exception.