From Jason Turner

[mdspan.layout.leftpad]

Diff to HTML by rtfpessoa

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