From Jason Turner

[mdspan.layout.rightpad]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpfnro412u/{from.md → to.md} +449 -0
tmp/tmpfnro412u/{from.md → to.md} RENAMED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##### Class template `layout_right_padded::mapping` <a id="mdspan.layout.rightpad">[[mdspan.layout.rightpad]]</a>
2
+
3
+ ###### Overview <a id="mdspan.layout.rightpad.overview">[[mdspan.layout.rightpad.overview]]</a>
4
+
5
+ `layout_right_padded` provides a layout mapping that behaves like
6
+ `layout_right::mapping`, except that the padding stride
7
+ `stride(extents_type::rank() - 2)` can be greater than or equal to
8
+ `extents_type::extent(extents_type::rank() - 1)`.
9
+
10
+ ``` cpp
11
+ namespace std {
12
+ template<size_t PaddingValue>
13
+ template<class Extents>
14
+ class layout_right_padded<PaddingValue>::mapping {
15
+ public:
16
+ static constexpr size_t padding_value = PaddingValue;
17
+
18
+ using extents_type = Extents;
19
+ using index_type = extents_type::index_type;
20
+ using size_type = extents_type::size_type;
21
+ using rank_type = extents_type::rank_type;
22
+ using layout_type = layout_right_padded<PaddingValue>;
23
+
24
+ private:
25
+ static constexpr size_t rank_ = extents_type::rank(); // exposition only
26
+ static constexpr size_t last-static-extent = // exposition only
27
+ extents_type::static_extent(rank_ - 1);
28
+
29
+ // [mdspan.layout.rightpad.expo], exposition-only members
30
+ static constexpr size_t static-padding-stride = see below; // exposition only
31
+
32
+ public:
33
+ // [mdspan.layout.rightpad.cons], constructors
34
+ constexpr mapping() noexcept : mapping(extents_type{}) {}
35
+ constexpr mapping(const mapping&) noexcept = default;
36
+ constexpr mapping(const extents_type&);
37
+ template<class OtherIndexType>
38
+ constexpr mapping(const extents_type&, OtherIndexType);
39
+
40
+ template<class OtherExtents>
41
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
42
+ mapping(const layout_right::mapping<OtherExtents>&);
43
+ template<class OtherExtents>
44
+ constexpr explicit(rank_ > 0)
45
+ mapping(const layout_stride::mapping<OtherExtents>&);
46
+ template<class LayoutRightPaddedMapping>
47
+ constexpr explicit(see below)
48
+ mapping(const LayoutRightPaddedMapping&);
49
+ template<class LayoutLeftPaddedMapping>
50
+ constexpr explicit(see below)
51
+ mapping(const LayoutLeftPaddedMapping&) noexcept;
52
+
53
+ constexpr mapping& operator=(const mapping&) noexcept = default;
54
+
55
+ // [mdspan.layout.rightpad.obs], observers
56
+ constexpr const extents_type& extents() const noexcept { return extents_; }
57
+ constexpr array<index_type, rank_> strides() const noexcept;
58
+
59
+ constexpr index_type required_span_size() const noexcept;
60
+
61
+ template<class... Indices>
62
+ constexpr index_type operator()(Indices...) const noexcept;
63
+
64
+ static constexpr bool is_always_unique() noexcept { return true; }
65
+ static constexpr bool is_always_exhaustive() noexcept;
66
+ static constexpr bool is_always_strided() noexcept { return true; }
67
+
68
+ static constexpr bool is_unique() noexcept { return true; }
69
+ constexpr bool is_exhaustive() const noexcept;
70
+ static constexpr bool is_strided() noexcept { return true; }
71
+
72
+ constexpr index_type stride(rank_type) const noexcept;
73
+
74
+ template<class LayoutRightPaddedMapping>
75
+ friend constexpr bool operator==(const mapping&, const LayoutRightPaddedMapping&) noexcept;
76
+
77
+ private:
78
+ // [mdspan.layout.rightpad.expo], exposition-only members
79
+ index_type stride-rm2 = static-padding-stride; // exposition only
80
+ extents_type extents_{}; // exposition only
81
+
82
+ // [mdspan.sub.map], submdspan mapping specialization
83
+ template<class... SliceSpecifiers>
84
+ constexpr auto submdspan-mapping-impl(SliceSpecifiers...) const // exposition only
85
+ -> see below;
86
+
87
+ template<class... SliceSpecifiers>
88
+ friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {
89
+ return src.submdspan-mapping-impl(slices...);
90
+ }
91
+ };
92
+ }
93
+ ```
94
+
95
+ If `Extents` is not a specialization of `extents`, then the program is
96
+ ill-formed.
97
+
98
+ `layout_right_padded::mapping<E>` is a trivially copyable type that
99
+ models `regular` for each `E`.
100
+
101
+ Throughout [[mdspan.layout.rightpad]], let `P_rank` be the following
102
+ size *`rank_`* parameter pack of `size_`t values:
103
+
104
+ - the empty parameter pack, if *`rank_`* equals zero;
105
+ - otherwise, `0zu`, if *`rank_`* equals one;
106
+ - otherwise, the parameter pack `0zu`, `1zu`, …, `rank_- 1`.
107
+
108
+ *Mandates:*
109
+
110
+ - If `rank_dynamic() == 0` is `true`, then the size of the
111
+ multidimensional index space `Extents()` is representable as a value
112
+ of type `index_type`.
113
+ - `padding_value` is representable as a value of type `index_type`.
114
+ - If
115
+ - *`rank_`* is greater than one,
116
+ - `padding_value` does not equal `dynamic_extent`, and
117
+ - *`last-static-extent`* does not equal `dynamic_extent`,
118
+
119
+ then `LEAST-MULTIPLE-AT-LEAST(padding_value, last-static-extent)` is
120
+ representable as a value of type `size_t`, and is representable as a
121
+ value of type `index_type`.
122
+ - If
123
+ - *`rank_`* is greater than one,
124
+ - `padding_value` does not equal `dynamic_extent`, and
125
+ - `extents_type::static_extent(k)` does not equal `dynamic_extent` for
126
+ all k in the range \[`0`, *`rank_`*),
127
+
128
+ then the product of
129
+ `LEAST-MULTIPLE-AT-LEAST(padding_value, ext.static_extent(rank_ - 1))`
130
+ and all values `ext.static_extent(k)` with k in the range of \[`0`,
131
+ *`rank_`*` - 1`) is representable as a value of type `size_t`, and is
132
+ representable as a value of type `index_type`.
133
+
134
+ ###### Exposition-only members <a id="mdspan.layout.rightpad.expo">[[mdspan.layout.rightpad.expo]]</a>
135
+
136
+ ``` cpp
137
+ static constexpr size_t static-padding-stride = see below;
138
+ ```
139
+
140
+ The value is
141
+
142
+ - `0`, if *rank\_* equals zero or one;
143
+ - otherwise, `dynamic_extent`, if `padding_value` or
144
+ *last-static-extent* equals `dynamic_extent`;
145
+ - otherwise, the `size_t` value which is
146
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, `*`last-static-extent`*`)`.
147
+
148
+ ``` cpp
149
+ index_type stride-rm2 = static-padding-stride;
150
+ ```
151
+
152
+ *Recommended practice:* Implementations should not store this value if
153
+ *static-padding-stride* is not `dynamic_extent`.
154
+
155
+ [*Note 11*: Using `extents<index_type, `*`static-padding-stride`*`>`
156
+ instead of `index_type` as the type of *stride-rm2* would achieve
157
+ this. — *end note*]
158
+
159
+ ###### Constructors <a id="mdspan.layout.rightpad.cons">[[mdspan.layout.rightpad.cons]]</a>
160
+
161
+ ``` cpp
162
+ constexpr mapping(const extents_type& ext);
163
+ ```
164
+
165
+ *Preconditions:*
166
+
167
+ - The size of the multidimensional index space `ext` is representable as
168
+ a value of type `index_type`.
169
+ - If *rank\_* is greater than one and `padding_value` does not equal
170
+ `dynamic_extent`, then
171
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(`*`rank_`*` - 1))`
172
+ is representable as a value of type *index_type*.
173
+ - If *rank\_* is greater than one and `padding_value` does not equal
174
+ `dynamic_extent`, then the product of
175
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(`*`rank_`*` - 1))`
176
+ and all values `ext.extent(`k`)` with k in the range of \[`0`,
177
+ *`rank_`*` - 1`) is representable as a value of type `index_type`.
178
+
179
+ *Effects:*
180
+
181
+ - Direct-non-list-initializes *extents\_* with `ext`; and
182
+ - if *rank\_* is greater than one, direct-non-list-initializes
183
+ *stride-rm2*
184
+ - with `ext.extent(`*`rank_`*` - 1)` if `padding_value` is
185
+ `dynamic_extent`,
186
+ - otherwise with
187
+ *`LEAST-MULTIPLE-AT-LEAST`*`(padding_value, ext.extent(`*`rank_`*` - 1))`.
188
+
189
+ ``` cpp
190
+ template<class OtherIndexType>
191
+ constexpr mapping(const extents_type& ext, OtherIndexType pad);
192
+ ```
193
+
194
+ *Constraints:*
195
+
196
+ - `is_convertible_v<OtherIndexType, index_type>` is `true`.
197
+ - `is_nothrow_constructible_v<index_type, OtherIndexType>` is `true`.
198
+
199
+ *Preconditions:*
200
+
201
+ - `pad` is representable as a value of type `index_type`.
202
+ - `extents_type::`*`index-cast`*`(pad)` is greater than zero.
203
+ - If *rank\_* is greater than one, then
204
+ *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(`*`rank_`*` - 1))` is
205
+ representable as a value of type `index_type`.
206
+ - If *rank\_* is greater than one, then the product of
207
+ *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(`*`rank_`*` - 1))` and
208
+ all values `ext.extent(`k`)` with k in the range of \[`0`,
209
+ *`rank_`*` - 1`) is representable as a value of type `index_type`.
210
+ - If `padding_value` is not equal to `dynamic_extent`, `padding_value`
211
+ equals `extents_type::`*`index-cast`*`(pad)`.
212
+
213
+ *Effects:* Direct-non-list-initializes *extents\_* with `ext`, and if
214
+ *rank\_* is greater than one, direct-non-list-initializes *stride-rm2*
215
+ with *`LEAST-MULTIPLE-AT-LEAST`*`(pad, ext.extent(`*`rank_`*` - 1))`.
216
+
217
+ ``` cpp
218
+ template<class OtherExtents>
219
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
220
+ mapping(const layout_right::mapping<OtherExtents>& other);
221
+ ```
222
+
223
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
224
+ `true`.
225
+
226
+ *Mandates:* If `OtherExtents::rank()` is greater than 1, then
227
+
228
+ ``` cpp
229
+ (static-padding-stride == dynamic_extent) ||
230
+ (OtherExtents::static_extent(rank_ - 1) == dynamic_extent) ||
231
+ (static-padding-stride == OtherExtents::static_extent(rank_ - 1))
232
+ ```
233
+
234
+ is `true`.
235
+
236
+ *Preconditions:*
237
+
238
+ - If *`rank_`*` > 1` is `true` and `padding_value == dynamic_extent` is
239
+ `false`, then `other.stride( `*`rank_`*` - 2)` equals
240
+ ``` cpp
241
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
242
+ extents_type::index-cast(other.extents().extent(rank_ - 1)))
243
+ ```
244
+
245
+ and
246
+ - `other.required_span_size()` is representable as a value of type
247
+ `index_type`.
248
+
249
+ *Effects:* Equivalent to `mapping(other.extents())`.
250
+
251
+ ``` cpp
252
+ template<class OtherExtents>
253
+ constexpr explicit(rank_ > 0)
254
+ mapping(const layout_stride::mapping<OtherExtents>& other);
255
+ ```
256
+
257
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
258
+ `true`.
259
+
260
+ *Preconditions:*
261
+
262
+ - If *rank\_* is greater than 1 and `padding_value` does not equal
263
+ `dynamic_extent`, then `other.stride(`*`rank_`*` - 2)` equals
264
+ ``` cpp
265
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
266
+ extents_type::index-cast(other.extents().extent(rank_ - 1)))
267
+ ```
268
+ - If *rank\_* is greater than 0, then other.stride(*rank\_* - 1) equals
269
+ 1.
270
+ - If *rank\_* is greater than 2, then for all r in the range \[`0`,
271
+ *`rank_`*` - 2`), `other.stride(`r`)` equals
272
+ ``` cpp
273
+ (other.extents().rev-prod-of-extents(r) / other.extents().extent(rank_ - 1)) *
274
+ other.stride(rank_ - 2)
275
+ ```
276
+ - `other.required_span_size()` is representable as a value of type
277
+ `index_type`.
278
+
279
+ *Effects:*
280
+
281
+ - Direct-non-list-initializes *extents\_* with `other.extents()`; and
282
+ - if *rank\_* is greater than one, direct-non-list-initializes
283
+ *stride-rm2* with `other.stride(`*`rank_`*` - 2)`.
284
+
285
+ ``` cpp
286
+ template<class LayoutRightPaddedMapping>
287
+ constexpr explicit(see below)
288
+ mapping(const LayoutRightPaddedMapping& other);
289
+ ```
290
+
291
+ *Constraints:*
292
+
293
+ - *`is-layout-right-padded-mapping-of`*`<LayoutRightPaddedMapping>` is
294
+ `true`.
295
+ - `is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_- type>`
296
+ is `true`.
297
+
298
+ *Mandates:* If *rank\_* is greater than 1, then
299
+
300
+ ``` cpp
301
+ padding_value == dynamic_extent ||
302
+ LayoutRightPaddedMapping::padding_value == dynamic_extent ||
303
+ padding_value == LayoutRightPaddedMapping::padding_value
304
+ ```
305
+
306
+ is `true`.
307
+
308
+ *Preconditions:*
309
+
310
+ - If *rank\_* is greater than 1 and `padding_value` does not equal
311
+ `dynamic_extent`, then `other.stride(`*`rank_`*` - 2)` equals
312
+ ``` cpp
313
+ LEAST-MULTIPLE-AT-LEAST(padding_value,
314
+ extents_type::index-cast(other.extent(rank_ - 1)))
315
+ ```
316
+ - `other.required_span_size()` is representable as a value of type
317
+ `index_type`.
318
+
319
+ *Effects:*
320
+
321
+ - Direct-non-list-initializes *extents\_* with `other.extents()`; and
322
+ - if *rank\_* is greater than one, direct-non-list-initializes
323
+ *stride-rm2* with `other.stride(rank_ - 2)`.
324
+
325
+ *Remarks:* The expression inside `explicit` is equivalent to:
326
+
327
+ ``` cpp
328
+ rank_ > 1 &&
329
+ (padding_value != dynamic_extent ||
330
+ LayoutRightPaddedMapping::padding_value == dynamic_extent)
331
+ ```
332
+
333
+ ``` cpp
334
+ template<class LayoutLeftPaddedMapping>
335
+ constexpr explicit(see below)
336
+ mapping(const LayoutLeftPaddedMapping& other) noexcept;
337
+ ```
338
+
339
+ *Constraints:*
340
+
341
+ - *`is-layout-left-padded-mapping-of`*`<LayoutLeftPaddedMapping>` is
342
+ `true` or *`is-mapping-of`*`<layout_left, LayoutLeftPaddedMapping>` is
343
+ `true`.
344
+ - *rank\_* equals zero or one.
345
+ - `is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>`
346
+ is `true`.
347
+
348
+ *Preconditions:* `other.required_span_size()` is representable as a
349
+ value of type `index_type`.
350
+
351
+ *Effects:* Direct-non-list-initializes *extents\_* with
352
+ `other.extents()`.
353
+
354
+ *Remarks:* The expression inside `explicit` is equivalent to:
355
+
356
+ ``` cpp
357
+ !is_convertible_v<typename LayoutLeftPaddedMapping::extents_type, extents_type>
358
+ ```
359
+
360
+ [*Note 12*: Neither the input mapping nor the mapping to be constructed
361
+ uses the padding stride in the rank-0 or rank-1 case, so the padding
362
+ stride affects neither the constraints nor the
363
+ preconditions. — *end note*]
364
+
365
+ ###### Observers <a id="mdspan.layout.rightpad.obs">[[mdspan.layout.rightpad.obs]]</a>
366
+
367
+ ``` cpp
368
+ constexpr array<index_type, rank_> strides() const noexcept;
369
+ ```
370
+
371
+ *Returns:* `array<index_type, `*`rank_`*`>(``stride(P_rank)...``)`.
372
+
373
+ ``` cpp
374
+ constexpr index_type required_span_size() const noexcept;
375
+ ```
376
+
377
+ *Returns:* `0` if the multidimensional index space *extents\_* is empty,
378
+ otherwise
379
+ `(*this)(`*`extents_`*`.extent(P_rank) - index_type(1)...) + 1`.
380
+
381
+ ``` cpp
382
+ template<class... Indices>
383
+ constexpr size_t operator()(Indices... idxs) const noexcept;
384
+ ```
385
+
386
+ *Constraints:*
387
+
388
+ - `sizeof...(Indices) == `*`rank_`* is `true`.
389
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`.
390
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
391
+
392
+ *Preconditions:* `extents_type::`*`index-cast`*`(idxs)` is a
393
+ multidimensional index in `extents()` [[mdspan.overview]].
394
+
395
+ *Returns:*
396
+ `((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)`.
397
+
398
+ ``` cpp
399
+ static constexpr bool is_always_exhaustive() noexcept;
400
+ ```
401
+
402
+ *Returns:*
403
+
404
+ - If *rank\_* equals zero or one, then `true`;
405
+ - otherwise, if neither *static-padding-stride* nor *last-static-extent*
406
+ equal `dynamic_extent`, then
407
+ *`static-padding-stride`*` == `*`last-static-extent`*;
408
+ - otherwise, `false`.
409
+
410
+ ``` cpp
411
+ constexpr bool is_exhaustive() const noexcept;
412
+ ```
413
+
414
+ *Returns:* `true` if *rank\_* equals zero or one; otherwise,
415
+
416
+ ``` cpp
417
+ extents_.extent(rank_ - 1) == stride(rank_ - 2)
418
+ ```
419
+
420
+ ``` cpp
421
+ constexpr index_type stride(rank_type r) const noexcept;
422
+ ```
423
+
424
+ *Preconditions:* `r` is smaller than *rank\_*.
425
+
426
+ *Returns:*
427
+
428
+ - If `r` equals *`rank_`*` - 1`: `1`;
429
+ - otherwise, if `r` equals *`rank_`*` - 2`: *stride-rm2*;
430
+ - otherwise, the product of *stride-rm2* and all values
431
+ `extents_.extent(`k`)` with k in the range of \[`r + 1`,
432
+ *`rank_`*` - 1`).
433
+
434
+ ``` cpp
435
+ template<class LayoutRightPaddedMapping>
436
+ friend constexpr bool operator==(const mapping& x, const LayoutRightPaddedMapping& y) noexcept;
437
+ ```
438
+
439
+ *Constraints:*
440
+
441
+ - *`is-layout-right-padded-mapping-of`*`<LayoutRightPaddedMapping>` is
442
+ `true`.
443
+ - `LayoutRightPaddedMapping::extents_type::rank() == `*`rank_`* is
444
+ `true`.
445
+
446
+ *Returns:* `true` if `x.extents() == y.extents()` is `true` and
447
+ *`rank_`*` < 2 || x.stride(`*`rank_`*` - 2) == y.stride(`*`rank_`*` - 2)`
448
+ is `true`. Otherwise, `false`.
449
+