From Jason Turner

[mdspan.extents]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp4kb19jvg/{from.md → to.md} +279 -0
tmp/tmp4kb19jvg/{from.md → to.md} RENAMED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### Class template `extents` <a id="mdspan.extents">[[mdspan.extents]]</a>
2
+
3
+ ##### Overview <a id="mdspan.extents.overview">[[mdspan.extents.overview]]</a>
4
+
5
+ The class template `extents` represents a multidimensional index space
6
+ of rank equal to `sizeof...(Extents)`. In subclause [[views]], `extents`
7
+ is used synonymously with multidimensional index space.
8
+
9
+ ``` cpp
10
+ namespace std {
11
+ template<class IndexType, size_t... Extents>
12
+ class extents {
13
+ public:
14
+ using index_type = IndexType;
15
+ using size_type = make_unsigned_t<index_type>;
16
+ using rank_type = size_t;
17
+
18
+ // [mdspan.extents.obs], observers of the multidimensional index space
19
+ static constexpr rank_type rank() noexcept { return sizeof...(Extents); }
20
+ static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
21
+ static constexpr size_t static_extent(rank_type) noexcept;
22
+ constexpr index_type extent(rank_type) const noexcept;
23
+
24
+ // [mdspan.extents.cons], constructors
25
+ constexpr extents() noexcept = default;
26
+
27
+ template<class OtherIndexType, size_t... OtherExtents>
28
+ constexpr explicit(see below)
29
+ extents(const extents<OtherIndexType, OtherExtents...>&) noexcept;
30
+ template<class... OtherIndexTypes>
31
+ constexpr explicit extents(OtherIndexTypes...) noexcept;
32
+ template<class OtherIndexType, size_t N>
33
+ constexpr explicit(N != rank_dynamic())
34
+ extents(span<OtherIndexType, N>) noexcept;
35
+ template<class OtherIndexType, size_t N>
36
+ constexpr explicit(N != rank_dynamic())
37
+ extents(const array<OtherIndexType, N>&) noexcept;
38
+
39
+ // [mdspan.extents.cmp], comparison operators
40
+ template<class OtherIndexType, size_t... OtherExtents>
41
+ friend constexpr bool operator==(const extents&,
42
+ const extents<OtherIndexType, OtherExtents...>&) noexcept;
43
+
44
+ // [mdspan.extents.expo], exposition-only helpers
45
+ constexpr size_t fwd-prod-of-extents(rank_type) const noexcept; // exposition only
46
+ constexpr size_t rev-prod-of-extents(rank_type) const noexcept; // exposition only
47
+ template<class OtherIndexType>
48
+ static constexpr auto index-cast(OtherIndexType&&) noexcept; // exposition only
49
+
50
+ private:
51
+ static constexpr rank_type dynamic-index(rank_type) noexcept; // exposition only
52
+ static constexpr rank_type dynamic-index-inv(rank_type) noexcept; // exposition only
53
+ array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only
54
+ };
55
+
56
+ template<class... Integrals>
57
+ explicit extents(Integrals...)
58
+ -> see below;
59
+ }
60
+ ```
61
+
62
+ *Mandates:*
63
+
64
+ - `IndexType` is a signed or unsigned integer type, and
65
+ - each element of `Extents` is either equal to `dynamic_extent`, or is
66
+ representable as a value of type `IndexType`.
67
+
68
+ Each specialization of `extents` models `regular` and is trivially
69
+ copyable.
70
+
71
+ Let Eᵣ be the rᵗʰ element of `Extents`. Eᵣ is a *dynamic extent* if it
72
+ is equal to `dynamic_extent`, otherwise Eᵣ is a *static extent*. Let Dᵣ
73
+ be the value of `dynamic-extents[dynamic-index(r)]` if Eᵣ is a dynamic
74
+ extent, otherwise Eᵣ.
75
+
76
+ The rᵗʰ interval of the multidimensional index space represented by an
77
+ `extents` object is [0, Dᵣ).
78
+
79
+ ##### Exposition-only helpers <a id="mdspan.extents.expo">[[mdspan.extents.expo]]</a>
80
+
81
+ ``` cpp
82
+ static constexpr rank_type dynamic-index(rank_type i) noexcept;
83
+ ```
84
+
85
+ *Preconditions:* `i <= rank()` is `true`.
86
+
87
+ *Returns:* The number of Eᵣ with r < `i` for which Eᵣ is a dynamic
88
+ extent.
89
+
90
+ ``` cpp
91
+ static constexpr rank_type dynamic-index-inv(rank_type i) noexcept;
92
+ ```
93
+
94
+ *Preconditions:* `i < rank_dynamic()` is `true`.
95
+
96
+ *Returns:* The minimum value of r such that
97
+ *`dynamic-index`*`(`r` + 1) == i + 1` is `true`.
98
+
99
+ ``` cpp
100
+ constexpr size_t fwd-prod-of-extents(rank_type i) const noexcept;
101
+ ```
102
+
103
+ *Preconditions:* `i <= rank()` is `true`.
104
+
105
+ *Returns:* If `i > 0` is `true`, the product of `extent(`k`)` for all k
106
+ in the range [0, `i`), otherwise `1`.
107
+
108
+ ``` cpp
109
+ constexpr size_t rev-prod-of-extents(rank_type i) const noexcept;
110
+ ```
111
+
112
+ *Preconditions:* `i < rank()` is `true`.
113
+
114
+ *Returns:* If `i + 1 < rank()` is `true`, the product of `extent(`k`)`
115
+ for all k in the range [`i + 1`, `rank()`), otherwise `1`.
116
+
117
+ ``` cpp
118
+ template<class OtherIndexType>
119
+ static constexpr auto index-cast(OtherIndexType&& i) noexcept;
120
+ ```
121
+
122
+ *Effects:*
123
+
124
+ - If `OtherIndexType` is an integral type other than `bool`, then
125
+ equivalent to `return i;`,
126
+ - otherwise, equivalent to `return static_cast<index_type>(i);`.
127
+
128
+ [*Note 1*: This function will always return an integral type other than
129
+ `bool`. Since this function’s call sites are constrained on
130
+ convertibility of `OtherIndexType` to `index_type`, integer-class types
131
+ can use the `static_cast` branch without loss of
132
+ precision. — *end note*]
133
+
134
+ ##### Constructors <a id="mdspan.extents.cons">[[mdspan.extents.cons]]</a>
135
+
136
+ ``` cpp
137
+ template<class OtherIndexType, size_t... OtherExtents>
138
+ constexpr explicit(see below)
139
+ extents(const extents<OtherIndexType, OtherExtents...>& other) noexcept;
140
+ ```
141
+
142
+ *Constraints:*
143
+
144
+ - `sizeof...(OtherExtents) == rank()` is `true`.
145
+ - `((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents == Extents) && ...)`
146
+ is `true`.
147
+
148
+ *Preconditions:*
149
+
150
+ - `other.extent(`r`)` equals Eᵣ for each r for which Eᵣ is a static
151
+ extent, and
152
+ - either
153
+ - `sizeof...(OtherExtents)` is zero, or
154
+ - `other.extent(`r`)` is representable as a value of type `index_type`
155
+ for every rank index r of `other`.
156
+
157
+ *Ensures:* `*this == other` is `true`.
158
+
159
+ *Remarks:* The expression inside `explicit` is equivalent to:
160
+
161
+ ``` cpp
162
+ (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||
163
+ (numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
164
+ ```
165
+
166
+ ``` cpp
167
+ template<class... OtherIndexTypes>
168
+ constexpr explicit extents(OtherIndexTypes... exts) noexcept;
169
+ ```
170
+
171
+ Let `N` be `sizeof...(OtherIndexTypes)`, and let `exts_arr` be
172
+ `array<index_type, N>{static_cast<`
173
+ `index_type>(std::move(exts))...}`.
174
+
175
+ *Constraints:*
176
+
177
+ - `(is_convertible_v<OtherIndexTypes, index_type> && ...)` is `true`,
178
+ - `(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...)` is
179
+ `true`, and
180
+ - `N == rank_dynamic() || N == rank()` is `true`. \[*Note 1*: One can
181
+ construct `extents` from just dynamic extents, which are all the
182
+ values getting stored, or from all the extents with a
183
+ precondition. — *end note*]
184
+
185
+ *Preconditions:*
186
+
187
+ - If `N != rank_dynamic()` is `true`, `exts_arr[`r`]` equals Eᵣ for each
188
+ r for which Eᵣ is a static extent, and
189
+ - either
190
+ - `sizeof...(exts) == 0` is `true`, or
191
+ - each element of `exts` is nonnegative and is representable as a
192
+ value of type `index_type`.
193
+
194
+ *Ensures:* `*this == extents(exts_arr)` is `true`.
195
+
196
+ ``` cpp
197
+ template<class OtherIndexType, size_t N>
198
+ constexpr explicit(N != rank_dynamic())
199
+ extents(span<OtherIndexType, N> exts) noexcept;
200
+ template<class OtherIndexType, size_t N>
201
+ constexpr explicit(N != rank_dynamic())
202
+ extents(const array<OtherIndexType, N>& exts) noexcept;
203
+ ```
204
+
205
+ *Constraints:*
206
+
207
+ - `is_convertible_v<const OtherIndexType&, index_type>` is `true`,
208
+ - `is_nothrow_constructible_v<index_type, const OtherIndexType&>` is
209
+ `true`, and
210
+ - `N == rank_dynamic() || N == rank()` is `true`.
211
+
212
+ *Preconditions:*
213
+
214
+ - If `N != rank_dynamic()` is `true`, `exts[`r`]` equals Eᵣ for each r
215
+ for which Eᵣ is a static extent, and
216
+ - either
217
+ - `N` is zero, or
218
+ - `exts[`r`]` is nonnegative and is representable as a value of type
219
+ `index_type` for every rank index r.
220
+
221
+ *Effects:*
222
+
223
+ - If `N` equals `dynamic_rank()`, for all d in the range
224
+ [0, `rank_dynamic()`), direct-non-list-initializes
225
+ *`dynamic-extents`*`[`d`]` with `as_const(exts[`d`])`.
226
+ - Otherwise, for all d in the range [0, `rank_dynamic()`),
227
+ direct-non-list-initializes *`dynamic-extents`*`[`d`]` with
228
+ `as_const(exts[`*`dynamic-index-inv`*`(`d`)])`.
229
+
230
+ ``` cpp
231
+ template<class... Integrals>
232
+ explicit extents(Integrals...) -> see below;
233
+ ```
234
+
235
+ *Constraints:* `(is_convertible_v<Integrals, size_t> && ...)` is `true`.
236
+
237
+ *Remarks:* The deduced type is `dextents<size_t, sizeof...(Integrals)>`.
238
+
239
+ ##### Observers of the multidimensional index space <a id="mdspan.extents.obs">[[mdspan.extents.obs]]</a>
240
+
241
+ ``` cpp
242
+ static constexpr size_t static_extent(rank_type i) noexcept;
243
+ ```
244
+
245
+ *Preconditions:* `i < rank()` is `true`.
246
+
247
+ *Returns:* E_`i`.
248
+
249
+ ``` cpp
250
+ constexpr index_type extent(rank_type i) const noexcept;
251
+ ```
252
+
253
+ *Preconditions:* `i < rank()` is `true`.
254
+
255
+ *Returns:* D_`i`.
256
+
257
+ ##### Comparison operators <a id="mdspan.extents.cmp">[[mdspan.extents.cmp]]</a>
258
+
259
+ ``` cpp
260
+ template<class OtherIndexType, size_t... OtherExtents>
261
+ friend constexpr bool operator==(const extents& lhs,
262
+ const extents<OtherIndexType, OtherExtents...>& rhs) noexcept;
263
+ ```
264
+
265
+ *Returns:* `true` if `lhs.rank()` equals `rhs.rank()` and if
266
+ `lhs.extent(r)` equals `rhs.extent(r)` for every rank index `r` of
267
+ `rhs`, otherwise `false`.
268
+
269
+ ##### Alias template `dextents` <a id="mdspan.extents.dextents">[[mdspan.extents.dextents]]</a>
270
+
271
+ ``` cpp
272
+ template<class IndexType, size_t Rank>
273
+ using dextents = see below;
274
+ ```
275
+
276
+ *Result:* A type `E` that is a specialization of `extents` such that
277
+ `E::rank() == Rank && E::rank() == E::rank_dynamic()` is `true`, and
278
+ `E::index_type` denotes `IndexType`.
279
+