From Jason Turner

[mdspan.layout.stride]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpa6ea6qiq/{from.md → to.md} +273 -0
tmp/tmpa6ea6qiq/{from.md → to.md} RENAMED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##### Class template `layout_stride::mapping` <a id="mdspan.layout.stride">[[mdspan.layout.stride]]</a>
2
+
3
+ ###### Overview <a id="mdspan.layout.stride.overview">[[mdspan.layout.stride.overview]]</a>
4
+
5
+ `layout_stride` provides a layout mapping where the strides are
6
+ user-defined.
7
+
8
+ ``` cpp
9
+ namespace std {
10
+ template<class Extents>
11
+ class layout_stride::mapping {
12
+ public:
13
+ using extents_type = Extents;
14
+ using index_type = typename extents_type::index_type;
15
+ using size_type = typename extents_type::size_type;
16
+ using rank_type = typename extents_type::rank_type;
17
+ using layout_type = layout_stride;
18
+
19
+ private:
20
+ static constexpr rank_type rank_ = extents_type::rank(); // exposition only
21
+
22
+ public:
23
+ // [mdspan.layout.stride.cons], constructors
24
+ constexpr mapping() noexcept;
25
+ constexpr mapping(const mapping&) noexcept = default;
26
+ template<class OtherIndexType>
27
+ constexpr mapping(const extents_type&, span<OtherIndexType, rank_>) noexcept;
28
+ template<class OtherIndexType>
29
+ constexpr mapping(const extents_type&, const array<OtherIndexType, rank_>&) noexcept;
30
+
31
+ template<class StridedLayoutMapping>
32
+ constexpr explicit(see below) mapping(const StridedLayoutMapping&) noexcept;
33
+
34
+ constexpr mapping& operator=(const mapping&) noexcept = default;
35
+
36
+ // [mdspan.layout.stride.obs], observers
37
+ constexpr const extents_type& extents() const noexcept { return extents_; }
38
+ constexpr array<index_type, rank_> strides() const noexcept { return strides_; }
39
+
40
+ constexpr index_type required_span_size() const noexcept;
41
+
42
+ template<class... Indices>
43
+ constexpr index_type operator()(Indices...) const noexcept;
44
+
45
+ static constexpr bool is_always_unique() noexcept { return true; }
46
+ static constexpr bool is_always_exhaustive() noexcept { return false; }
47
+ static constexpr bool is_always_strided() noexcept { return true; }
48
+
49
+ static constexpr bool is_unique() noexcept { return true; }
50
+ constexpr bool is_exhaustive() const noexcept;
51
+ static constexpr bool is_strided() noexcept { return true; }
52
+
53
+ constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; }
54
+
55
+ template<class OtherMapping>
56
+ friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept;
57
+
58
+ private:
59
+ extents_type extents_{}; // exposition only
60
+ array<index_type, rank_> strides_{}; // exposition only
61
+ };
62
+ }
63
+ ```
64
+
65
+ If `Extents` is not a specialization of `extents`, then the program is
66
+ ill-formed.
67
+
68
+ `layout_stride::mapping<E>` is a trivially copyable type that models
69
+ `regular` for each `E`.
70
+
71
+ *Mandates:* If `Extents::rank_dynamic() == 0` is `true`, then the size
72
+ of the multidimensional index space `Extents()` is representable as a
73
+ value of type `typename Extents::index_type`.
74
+
75
+ ###### Exposition-only helpers <a id="mdspan.layout.stride.expo">[[mdspan.layout.stride.expo]]</a>
76
+
77
+ Let `REQUIRED-SPAN-SIZE(e, strides)` be:
78
+
79
+ - `1`, if `e.rank() == 0` is `true`,
80
+ - otherwise `0`, if the size of the multidimensional index space `e` is
81
+ 0,
82
+ - otherwise `1` plus the sum of products of `(e.extent(r) - 1)` and
83
+ `strides[r]` for all r in the range [0, `e.rank()`).
84
+
85
+ Let `OFFSET(m)` be:
86
+
87
+ - `m()`, if `e.rank() == 0` is `true`,
88
+ - otherwise `0`, if the size of the multidimensional index space `e` is
89
+ 0,
90
+ - otherwise `m(z...)` for a pack of integers `z` that is a
91
+ multidimensional index in `m.extents()` and each element of `z` equals
92
+ 0.
93
+
94
+ Let *`is-extents`* be the exposition-only variable template defined as
95
+ follows:
96
+
97
+ ``` cpp
98
+ template<class T>
99
+ constexpr bool is-extents = false; // exposition only
100
+ template<class IndexType, size_t... Args>
101
+ constexpr bool is-extents<extents<IndexType, Args...>> = true; // exposition only
102
+ ```
103
+
104
+ Let `layout-mapping-alike` be the exposition-only concept defined as
105
+ follows:
106
+
107
+ ``` cpp
108
+ template<class M>
109
+ concept layout-mapping-alike = requires { // exposition only
110
+ requires is-extents<typename M::extents_type>;
111
+ { M::is_always_strided() } -> same_as<bool>;
112
+ { M::is_always_exhaustive() } -> same_as<bool>;
113
+ { M::is_always_unique() } -> same_as<bool>;
114
+ bool_constant<M::is_always_strided()>::value;
115
+ bool_constant<M::is_always_exhaustive()>::value;
116
+ bool_constant<M::is_always_unique()>::value;
117
+ };
118
+ ```
119
+
120
+ [*Note 2*: This concept checks that the functions
121
+ `M::is_always_strided()`, `M::is_always_exhaustive()`, and
122
+ `M::is_always_unique()` exist, are constant expressions, and have a
123
+ return type of `bool`. — *end note*]
124
+
125
+ ###### Constructors <a id="mdspan.layout.stride.cons">[[mdspan.layout.stride.cons]]</a>
126
+
127
+ ``` cpp
128
+ constexpr mapping() noexcept;
129
+ ```
130
+
131
+ *Preconditions:*
132
+ `layout_right::mapping<extents_type>().required_span_size()` is
133
+ representable as a value of type `index_type` [[basic.fundamental]].
134
+
135
+ *Effects:* Direct-non-list-initializes *extents\_* with
136
+ `extents_type()`, and for all d in the range \[`0`, *`rank_`*),
137
+ direct-non-list-initializes *`strides_`*`[`d`]` with
138
+ `layout_right::mapping<extents_type>().stride(`d`)`.
139
+
140
+ ``` cpp
141
+ template<class OtherIndexType>
142
+ constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
143
+ template<class OtherIndexType>
144
+ constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
145
+ ```
146
+
147
+ *Constraints:*
148
+
149
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`, and
150
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
151
+ `true`.
152
+
153
+ *Preconditions:*
154
+
155
+ - `s[`i`] > 0` is `true` for all i in the range [0, rank_).
156
+ - *`REQUIRED-SPAN-SIZE`*`(e, s)` is representable as a value of type
157
+ `index_type` [[basic.fundamental]].
158
+ - If *rank\_* is greater than 0, then there exists a permutation P of
159
+ the integers in the range [0, rank_), such that
160
+ `s[`pᵢ`] >= s[`pᵢ₋₁`] * e.extent(p`ᵢ₋₁`)` is `true` for all i in the
161
+ range [1, rank_), where pᵢ is the iᵗʰ element of P. \[*Note 3*: For
162
+ `layout_stride`, this condition is necessary and sufficient for
163
+ `is_unique()` to be `true`. — *end note*]
164
+
165
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`, and for all
166
+ d in the range [0, rank_), direct-non-list-initializes `strides_[`d`]`
167
+ with `as_const(s[`d`])`.
168
+
169
+ ``` cpp
170
+ template<class StridedLayoutMapping>
171
+ constexpr explicit(see below)
172
+ mapping(const StridedLayoutMapping& other) noexcept;
173
+ ```
174
+
175
+ *Constraints:*
176
+
177
+ - `layout-mapping-alike<StridedLayoutMapping>` is satisfied.
178
+ - `is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type>`
179
+ is
180
+ `true`.
181
+ - `StridedLayoutMapping::is_always_unique()` is `true`.
182
+ - `StridedLayoutMapping::is_always_strided()` is `true`.
183
+
184
+ *Preconditions:*
185
+
186
+ - `StridedLayoutMapping` meets the layout mapping
187
+ requirements [[mdspan.layout.policy.reqmts]],
188
+ - `other.stride(`r`) > 0` is `true` for every rank index r of
189
+ `extents()`,
190
+ - `other.required_span_size()` is representable as a value of type
191
+ `index_type` [[basic.fundamental]], and
192
+ - *`OFFSET`*`(other) == 0` is `true`.
193
+
194
+ *Effects:* Direct-non-list-initializes *extents\_* with
195
+ `other.extents()`, and for all d in the range [0, rank_),
196
+ direct-non-list-initializes *`strides_`*`[`d`]` with
197
+ `other.stride(`d`)`.
198
+
199
+ Remarks: The expression inside `explicit` is equivalent to:
200
+
201
+ ``` cpp
202
+ !(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&
203
+ (is-mapping-of<layout_left, LayoutStrideMapping> ||
204
+ is-mapping-of<layout_right, LayoutStrideMapping> ||
205
+ is-mapping-of<layout_stride, LayoutStrideMapping>))
206
+ ```
207
+
208
+ ###### Observers <a id="mdspan.layout.stride.obs">[[mdspan.layout.stride.obs]]</a>
209
+
210
+ ``` cpp
211
+ constexpr index_type required_span_size() const noexcept;
212
+ ```
213
+
214
+ *Returns:* *`REQUIRED-SPAN-SIZE`*`(extents(), `*`strides_`*`)`.
215
+
216
+ ``` cpp
217
+ template<class... Indices>
218
+ constexpr index_type operator()(Indices... i) const noexcept;
219
+ ```
220
+
221
+ *Constraints:*
222
+
223
+ - `sizeof...(Indices) == `*`rank_`* is `true`,
224
+ - `(is_convertible_v<Indices, index_type> && ...)` is `true`, and
225
+ - `(is_nothrow_constructible_v<index_type, Indices> && ...)` is `true`.
226
+
227
+ *Preconditions:* `extents_type::`*`index-cast`*`(i)` is a
228
+ multidimensional index in *extents\_*[[mdspan.overview]].
229
+
230
+ *Effects:* Let `P` be a parameter pack such that
231
+
232
+ ``` cpp
233
+ is_same_v<index_sequence_for<Indices...>, index_sequence<P...>>
234
+ ```
235
+
236
+ is `true`. Equivalent to:
237
+
238
+ ``` cpp
239
+ return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
240
+ ```
241
+
242
+ ``` cpp
243
+ constexpr bool is_exhaustive() const noexcept;
244
+ ```
245
+
246
+ *Returns:*
247
+
248
+ - `true` if *rank\_* is 0.
249
+ - Otherwise, `true` if there is a permutation P of the integers in the
250
+ range [0, rank_) such that `stride(`p₀`)` equals 1, and `stride(`pᵢ`)`
251
+ equals `stride(`pᵢ₋₁`) * extents().extent(`pᵢ₋₁`)` for i in the range
252
+ [1, rank_), where pᵢ is the iᵗʰ element of P.
253
+ - Otherwise, `false`.
254
+
255
+ ``` cpp
256
+ template<class OtherMapping>
257
+ friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept;
258
+ ```
259
+
260
+ *Constraints:*
261
+
262
+ - `layout-mapping-alike<OtherMapping>` is satisfied.
263
+ - *`rank_`*` == OtherMapping::extents_type::rank()` is `true`.
264
+ - `OtherMapping::is_always_strided()` is `true`.
265
+
266
+ *Preconditions:* `OtherMapping` meets the layout mapping
267
+ requirements [[mdspan.layout.policy.reqmts]].
268
+
269
+ *Returns:* `true` if `x.extents() == y.extents()` is `true`,
270
+ *`OFFSET`*`(y) == 0` is `true`, and each of
271
+ `x.stride(`r`) == y.stride(`r`)` is `true` for r in the range
272
+ [0, `x.extents().rank()`). Otherwise, `false`.
273
+