From Jason Turner

[simd.class]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp8jts43pb/{from.md → to.md} +398 -0
tmp/tmp8jts43pb/{from.md → to.md} RENAMED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Class template `basic_vec` <a id="simd.class">[[simd.class]]</a>
2
+
3
+ #### Overview <a id="simd.overview">[[simd.overview]]</a>
4
+
5
+ ``` cpp
6
+ namespace std::simd {
7
+ template<class T, class Abi> class basic_vec {
8
+ public:
9
+ using value_type = T;
10
+ using mask_type = basic_mask<sizeof(T), Abi>;
11
+ using abi_type = Abi;
12
+ using iterator = simd-iterator<basic_vec>;
13
+ using const_iterator = simd-iterator<const basic_vec>;
14
+
15
+ constexpr iterator begin() noexcept { return {*this, 0}; }
16
+ constexpr const_iterator begin() const noexcept { return {*this, 0}; }
17
+ constexpr const_iterator cbegin() const noexcept { return {*this, 0}; }
18
+ constexpr default_sentinel_t end() const noexcept { return {}; }
19
+ constexpr default_sentinel_t cend() const noexcept { return {}; }
20
+
21
+ static constexpr integral_constant<simd-size-type, simd-size-v<T, Abi>> size {};
22
+
23
+ constexpr basic_vec() noexcept = default;
24
+
25
+ // [simd.ctor], basic_vec constructors
26
+ template<class U>
27
+ constexpr explicit(see below) basic_vec(U&& value) noexcept;
28
+ template<class U, class UAbi>
29
+ constexpr explicit(see below) basic_vec(const basic_vec<U, UAbi>&) noexcept;
30
+ template<class G>
31
+ constexpr explicit basic_vec(G&& gen);
32
+ template<class R, class... Flags>
33
+ constexpr basic_vec(R&& range, flags<Flags...> = {});
34
+ template<class R, class... Flags>
35
+ constexpr basic_vec(R&& range, const mask_type& mask, flags<Flags...> = {});
36
+ template<simd-floating-point V>
37
+ constexpr explicit(see below) basic_vec(const V& reals, const V& imags = {}) noexcept;
38
+
39
+ // [simd.subscr], basic_vec subscript operators
40
+ constexpr value_type operator[](simd-size-type) const;
41
+ template<simd-integral I>
42
+ constexpr resize_t<I::size(), basic_vec> operator[](const I& indices) const;
43
+
44
+ // [simd.complex.access], basic_vec complex accessors
45
+ constexpr auto real() const noexcept;
46
+ constexpr auto imag() const noexcept;
47
+ template<simd-floating-point V>
48
+ constexpr void real(const V& v) noexcept;
49
+ template<simd-floating-point V>
50
+ constexpr void imag(const V& v) noexcept;
51
+
52
+ // [simd.unary], basic_vec unary operators
53
+ constexpr basic_vec& operator++() noexcept;
54
+ constexpr basic_vec operator++(int) noexcept;
55
+ constexpr basic_vec& operator--() noexcept;
56
+ constexpr basic_vec operator--(int) noexcept;
57
+ constexpr mask_type operator!() const noexcept;
58
+ constexpr basic_vec operator~() const noexcept;
59
+ constexpr basic_vec operator+() const noexcept;
60
+ constexpr basic_vec operator-() const noexcept;
61
+
62
+ // [simd.binary], basic_vec binary operators
63
+ friend constexpr basic_vec operator+(const basic_vec&, const basic_vec&) noexcept;
64
+ friend constexpr basic_vec operator-(const basic_vec&, const basic_vec&) noexcept;
65
+ friend constexpr basic_vec operator*(const basic_vec&, const basic_vec&) noexcept;
66
+ friend constexpr basic_vec operator/(const basic_vec&, const basic_vec&) noexcept;
67
+ friend constexpr basic_vec operator%(const basic_vec&, const basic_vec&) noexcept;
68
+ friend constexpr basic_vec operator&(const basic_vec&, const basic_vec&) noexcept;
69
+ friend constexpr basic_vec operator|(const basic_vec&, const basic_vec&) noexcept;
70
+ friend constexpr basic_vec operator^(const basic_vec&, const basic_vec&) noexcept;
71
+ friend constexpr basic_vec operator<<(const basic_vec&, const basic_vec&) noexcept;
72
+ friend constexpr basic_vec operator>>(const basic_vec&, const basic_vec&) noexcept;
73
+ friend constexpr basic_vec operator<<(const basic_vec&, simd-size-type) noexcept;
74
+ friend constexpr basic_vec operator>>(const basic_vec&, simd-size-type) noexcept;
75
+
76
+ // [simd.cassign], basic_vec compound assignment
77
+ friend constexpr basic_vec& operator+=(basic_vec&, const basic_vec&) noexcept;
78
+ friend constexpr basic_vec& operator-=(basic_vec&, const basic_vec&) noexcept;
79
+ friend constexpr basic_vec& operator*=(basic_vec&, const basic_vec&) noexcept;
80
+ friend constexpr basic_vec& operator/=(basic_vec&, const basic_vec&) noexcept;
81
+ friend constexpr basic_vec& operator%=(basic_vec&, const basic_vec&) noexcept;
82
+ friend constexpr basic_vec& operator&=(basic_vec&, const basic_vec&) noexcept;
83
+ friend constexpr basic_vec& operator|=(basic_vec&, const basic_vec&) noexcept;
84
+ friend constexpr basic_vec& operator^=(basic_vec&, const basic_vec&) noexcept;
85
+ friend constexpr basic_vec& operator<<=(basic_vec&, const basic_vec&) noexcept;
86
+ friend constexpr basic_vec& operator>>=(basic_vec&, const basic_vec&) noexcept;
87
+ friend constexpr basic_vec& operator<<=(basic_vec&, simd-size-type) noexcept;
88
+ friend constexpr basic_vec& operator>>=(basic_vec&, simd-size-type) noexcept;
89
+
90
+ // [simd.comparison], basic_vec compare operators
91
+ friend constexpr mask_type operator==(const basic_vec&, const basic_vec&) noexcept;
92
+ friend constexpr mask_type operator!=(const basic_vec&, const basic_vec&) noexcept;
93
+ friend constexpr mask_type operator>=(const basic_vec&, const basic_vec&) noexcept;
94
+ friend constexpr mask_type operator<=(const basic_vec&, const basic_vec&) noexcept;
95
+ friend constexpr mask_type operator>(const basic_vec&, const basic_vec&) noexcept;
96
+ friend constexpr mask_type operator<(const basic_vec&, const basic_vec&) noexcept;
97
+
98
+ // [simd.cond], basic_vec exposition only conditional operators
99
+ friend constexpr basic_vec simd-select-impl( // exposition only
100
+ const mask_type&, const basic_vec&, const basic_vec&) noexcept;
101
+ };
102
+
103
+ template<class R, class... Ts>
104
+ basic_vec(R&& r, Ts...) -> see below;
105
+ }
106
+ ```
107
+
108
+ Every specialization of `basic_vec` is a complete type. The
109
+ specialization of `basic_vec<T, Abi>` is
110
+
111
+ - enabled, if `T` is a vectorizable type, and there exists value `N` in
112
+ the range \[`1`, `64`\], such that `Abi` is `deduce-abi-t<T, N>`,
113
+ - otherwise, disabled, if `T` is not a vectorizable type,
114
+ - otherwise, it is *implementation-defined* if such a specialization is
115
+ enabled.
116
+
117
+ If `basic_vec<T, Abi>` is disabled, then the specialization has a
118
+ deleted default constructor, deleted destructor, deleted copy
119
+ constructor, and deleted copy assignment. In addition only the
120
+ `value_type`, `abi_type`, and `mask_type` members are present.
121
+
122
+ If `basic_vec<T, Abi>` is enabled, then `basic_vec<T, Abi>` is trivially
123
+ copyable, default-initialization of an object of such a type
124
+ default-initializes all elements, and value-initialization
125
+ value-initializes all elements [[dcl.init.general]].
126
+
127
+ *Recommended practice:* Implementations should support implicit
128
+ conversions between specializations of `basic_vec` and appropriate
129
+ *implementation-defined* types.
130
+
131
+ [*Note 1*: Appropriate types are non-standard vector types which are
132
+ available in the implementation. — *end note*]
133
+
134
+ #### Constructors <a id="simd.ctor">[[simd.ctor]]</a>
135
+
136
+ ``` cpp
137
+ template<class U> constexpr explicit(see below) basic_vec(U&& value) noexcept;
138
+ ```
139
+
140
+ Let `From` denote the type `remove_cvref_t<U>`.
141
+
142
+ *Constraints:* `value_type` satisfies `constructible_from<U>`.
143
+
144
+ *Effects:* Initializes each element to the value of the argument after
145
+ conversion to `value_type`.
146
+
147
+ *Remarks:* The expression inside `explicit` evaluates to `false` if and
148
+ only if `U` satisfies `convertible_to<value_type>`, and either
149
+
150
+ - `From` is not an arithmetic type and does not satisfy
151
+ `constexpr-wrapper-like`,
152
+ - `From` is an arithmetic type and the conversion from `From` to
153
+ `value_type` is value-preserving [[simd.general]], or
154
+ - `From` satisfies `constexpr-wrapper-like`,
155
+ `remove_const_t<decltype(From::value)>` is an arithmetic type, and
156
+ `From::value` is representable by `value_type`.
157
+
158
+ ``` cpp
159
+ template<class U, class UAbi>
160
+ constexpr explicit(see below) basic_vec(const basic_vec<U, UAbi>& x) noexcept;
161
+ ```
162
+
163
+ *Constraints:* *`simd-size-v`*`<U, UAbi> == size()` is `true`.
164
+
165
+ *Effects:* Initializes the iᵗʰ element with `static_cast<T>(x[`i`])` for
166
+ all i in the range of \[`0`, `size()`).
167
+
168
+ *Remarks:* The expression inside `explicit` evaluates to `true` if
169
+ either
170
+
171
+ - the conversion from `U` to `value_type` is not value-preserving, or
172
+ - both `U` and `value_type` are integral types and the integer
173
+ conversion rank [[conv.rank]] of `U` is greater than the integer
174
+ conversion rank of `value_type`, or
175
+ - both `U` and `value_type` are floating-point types and the
176
+ floating-point conversion rank [[conv.rank]] of `U` is greater than
177
+ the floating-point conversion rank of `value_type`.
178
+
179
+ ``` cpp
180
+ template<class G> constexpr explicit basic_vec(G&& gen);
181
+ ```
182
+
183
+ Let `From`ᵢ denote the type
184
+ `decltype(gen(integral_constant<`*`simd-size-type`*`, `i`>()))`.
185
+
186
+ *Constraints:* `From`ᵢ satisfies `convertible_to<value_type>` for all i
187
+ in the range of \[`0`, `size()`). In addition, for all i in the range of
188
+ \[`0`, `size()`), if `From`ᵢ is an arithmetic type, conversion from
189
+ `From`ᵢ to `value_type` is value-preserving.
190
+
191
+ *Effects:* Initializes the iᵗʰ element with
192
+ `static_cast<value_type>(gen(integral_constant<`*`simd-size-type`*`, i>()))`
193
+ for all i in the range of \[`0`, `size()`).
194
+
195
+ *Remarks:* `gen` is invoked exactly once for each i, in increasing order
196
+ of i.
197
+
198
+ ``` cpp
199
+ template<class R, class... Flags>
200
+ constexpr basic_vec(R&& r, flags<Flags...> = {});
201
+ template<class R, class... Flags>
202
+ constexpr basic_vec(R&& r, const mask_type& mask, flags<Flags...> = {});
203
+ ```
204
+
205
+ Let `mask` be `mask_type(true)` for the overload with no `mask`
206
+ parameter.
207
+
208
+ *Constraints:*
209
+
210
+ - `R` models `ranges::contiguous_range` and `ranges::sized_range`,
211
+ - `ranges::size(r)` is a constant expression, and
212
+ - `ranges::size(r)` is equal to `size()`.
213
+
214
+ *Mandates:*
215
+
216
+ - `ranges::range_value_t<R>` is a vectorizable type, and
217
+ - if the template parameter pack `Flags` does not contain
218
+ *`convert-flag`*, then the conversion from `ranges::range_value_t<R>`
219
+ to `value_type` is value-preserving.
220
+
221
+ *Preconditions:*
222
+
223
+ - If the template parameter pack `Flags` contains *`aligned-flag`*,
224
+ `ranges::data(r)` points to storage aligned by
225
+ `alignment_v<basic_vec, ranges::range_value_t<R>>`.
226
+ - If the template parameter pack `Flags` contains
227
+ *`overaligned-flag`*`<N>`, `ranges::data(r)` points to storage aligned
228
+ by `N`.
229
+
230
+ *Effects:* Initializes the iᵗʰ element with
231
+ `mask[`i`] ? static_cast<T>(ranges::data(r)[`i`]) : T()` for all i in
232
+ the range of \[`0`, `size()`).
233
+
234
+ ``` cpp
235
+ template<class R, class... Ts>
236
+ basic_vec(R&& r, Ts...) -> see below;
237
+ ```
238
+
239
+ *Constraints:*
240
+
241
+ - `R` models `ranges::contiguous_range` and `ranges::sized_range`, and
242
+ - `ranges::size(r)` is a constant expression.
243
+
244
+ *Remarks:* The deduced type is equivalent to
245
+ `vec<ranges::range_value_t<R>, ranges::size(r)>`.
246
+
247
+ ``` cpp
248
+ template<simd-floating-point V>
249
+ constexpr explicit(see below)
250
+ basic_vec(const V& reals, const V& imags = {}) noexcept;
251
+ ```
252
+
253
+ *Constraints:*
254
+
255
+ - `simd-complex<basic_vec>` is modeled, and
256
+ - `V::size() == size()` is `true`.
257
+
258
+ *Effects:* Initializes the iᵗʰ element with
259
+ `value_type(reals[`i`], imags[`i`])` for all i in the range \[`0`,
260
+ `size()`).
261
+
262
+ *Remarks:* The expression inside `explicit` evaluates to `false` if and
263
+ only if the floating-point conversion rank of `T::value_type` is greater
264
+ than or equal to the floating-point conversion rank of `V::value_type`.
265
+
266
+ #### Subscript operator <a id="simd.subscr">[[simd.subscr]]</a>
267
+
268
+ ``` cpp
269
+ constexpr value_type operator[](simd-size-type i) const;
270
+ ```
271
+
272
+ *Preconditions:* `i >= 0 && i < size()` is `true`.
273
+
274
+ *Returns:* The value of the iᵗʰ element.
275
+
276
+ *Throws:* Nothing.
277
+
278
+ ``` cpp
279
+ template<simd-integral I>
280
+ constexpr resize_t<I::size(), basic_vec> operator[](const I& indices) const;
281
+ ```
282
+
283
+ *Effects:* Equivalent to: `return permute(*this, indices);`
284
+
285
+ #### Complex accessors <a id="simd.complex.access">[[simd.complex.access]]</a>
286
+
287
+ ``` cpp
288
+ constexpr auto real() const noexcept;
289
+ constexpr auto imag() const noexcept;
290
+ ```
291
+
292
+ *Constraints:* `simd-complex<basic_vec>` is modeled.
293
+
294
+ *Returns:* An object of type
295
+ `rebind_t<typename T::value_type, basic_vec>` where the iᵗʰ element is
296
+ initialized to the result of *`cmplx-func`*`(operator[](`i`))` for all i
297
+ in the range \[`0`, `size()`), where *`cmplx-func`* is the corresponding
298
+ function from `<complex>`.
299
+
300
+ ``` cpp
301
+ template<simd-floating-point V>
302
+ constexpr void real(const V& v) noexcept;
303
+ template<simd-floating-point V>
304
+ constexpr void imag(const V& v) noexcept;
305
+ ```
306
+
307
+ *Constraints:*
308
+
309
+ - `simd-complex<basic_vec>` is modeled,
310
+ - `same_as<typename V::value_type, typename T::value_type>` is modeled,
311
+ and
312
+ - `V::size() == size()` is `true`.
313
+
314
+ *Effects:* Replaces each element of the `basic_vec` object such that the
315
+ iᵗʰ element is replaced with
316
+ `value_type(v[`i`], operator[](`i`).imag())` or
317
+ `value_type(operator[](`i`).real(), v[`i`])` for `real` and `imag`
318
+ respectively, for all i in the range \[`0`, `size()`).
319
+
320
+ #### Unary operators <a id="simd.unary">[[simd.unary]]</a>
321
+
322
+ Effects in [[simd.unary]] are applied as unary element-wise operations.
323
+
324
+ ``` cpp
325
+ constexpr basic_vec& operator++() noexcept;
326
+ ```
327
+
328
+ *Constraints:* `requires (value_type a) { ++a; }` is `true`.
329
+
330
+ *Effects:* Increments every element by one.
331
+
332
+ *Returns:* `*this`.
333
+
334
+ ``` cpp
335
+ constexpr basic_vec operator++(int) noexcept;
336
+ ```
337
+
338
+ *Constraints:* `requires (value_type a) { a++; }` is `true`.
339
+
340
+ *Effects:* Increments every element by one.
341
+
342
+ *Returns:* A copy of `*this` before incrementing.
343
+
344
+ ``` cpp
345
+ constexpr basic_vec& operator--() noexcept;
346
+ ```
347
+
348
+ *Constraints:* `requires (value_type a) { –a; }` is `true`.
349
+
350
+ *Effects:* Decrements every element by one.
351
+
352
+ *Returns:* `*this`.
353
+
354
+ ``` cpp
355
+ constexpr basic_vec operator--(int) noexcept;
356
+ ```
357
+
358
+ *Constraints:* `requires (value_type a) { a–; }` is `true`.
359
+
360
+ *Effects:* Decrements every element by one.
361
+
362
+ *Returns:* A copy of `*this` before decrementing.
363
+
364
+ ``` cpp
365
+ constexpr mask_type operator!() const noexcept;
366
+ ```
367
+
368
+ *Constraints:* `requires (const value_type a) { !a; }` is `true`.
369
+
370
+ *Returns:* A `basic_mask` object with the iᵗʰ element set to
371
+ `!operator[](`i`)` for all i in the range of \[`0`, `size()`).
372
+
373
+ ``` cpp
374
+ constexpr basic_vec operator~() const noexcept;
375
+ ```
376
+
377
+ *Constraints:* `requires (const value_type a) { ~a; }` is `true`.
378
+
379
+ *Returns:* A `basic_vec` object with the iᵗʰ element set to
380
+ `~operator[](`i`)` for all i in the range of \[`0`, `size()`).
381
+
382
+ ``` cpp
383
+ constexpr basic_vec operator+() const noexcept;
384
+ ```
385
+
386
+ *Constraints:* `requires (const value_type a) { +a; }` is `true`.
387
+
388
+ *Returns:* `*this`.
389
+
390
+ ``` cpp
391
+ constexpr basic_vec operator-() const noexcept;
392
+ ```
393
+
394
+ *Constraints:* `requires (const value_type a) { -a; }` is `true`.
395
+
396
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
397
+ `-operator[](`i`)` for all i in the range of \[`0`, `size()`).
398
+