From Jason Turner

[simd.nonmembers]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpw_aid4ts/{from.md → to.md} +1282 -0
tmp/tmpw_aid4ts/{from.md → to.md} RENAMED
@@ -0,0 +1,1282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### `basic_vec` non-member operations <a id="simd.nonmembers">[[simd.nonmembers]]</a>
2
+
3
+ #### Binary operators <a id="simd.binary">[[simd.binary]]</a>
4
+
5
+ ``` cpp
6
+ friend constexpr basic_vec operator+(const basic_vec& lhs, const basic_vec& rhs) noexcept;
7
+ friend constexpr basic_vec operator-(const basic_vec& lhs, const basic_vec& rhs) noexcept;
8
+ friend constexpr basic_vec operator*(const basic_vec& lhs, const basic_vec& rhs) noexcept;
9
+ friend constexpr basic_vec operator/(const basic_vec& lhs, const basic_vec& rhs) noexcept;
10
+ friend constexpr basic_vec operator%(const basic_vec& lhs, const basic_vec& rhs) noexcept;
11
+ friend constexpr basic_vec operator&(const basic_vec& lhs, const basic_vec& rhs) noexcept;
12
+ friend constexpr basic_vec operator|(const basic_vec& lhs, const basic_vec& rhs) noexcept;
13
+ friend constexpr basic_vec operator^(const basic_vec& lhs, const basic_vec& rhs) noexcept;
14
+ friend constexpr basic_vec operator<<(const basic_vec& lhs, const basic_vec& rhs) noexcept;
15
+ friend constexpr basic_vec operator>>(const basic_vec& lhs, const basic_vec& rhs) noexcept;
16
+ ```
17
+
18
+ Let *op* be the operator.
19
+
20
+ *Constraints:* `requires (value_type a, value_type b) { a `*`op`*` b; }`
21
+ is `true`.
22
+
23
+ *Returns:* A `basic_vec` object initialized with the results of applying
24
+ *op* to `lhs` and `rhs` as a binary element-wise operation.
25
+
26
+ ``` cpp
27
+ friend constexpr basic_vec operator<<(const basic_vec& v, simd-size-type n) noexcept;
28
+ friend constexpr basic_vec operator>>(const basic_vec& v, simd-size-type n) noexcept;
29
+ ```
30
+
31
+ Let *op* be the operator.
32
+
33
+ *Constraints:*
34
+ `requires (value_type a, `*`simd-size-type`*` b) { a `*`op`*` b; }` is
35
+ `true`.
36
+
37
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
38
+ the result of applying *op* to `v[`i`]` and `n` for all i in the range
39
+ of \[`0`, `size()`).
40
+
41
+ #### Compound assignment <a id="simd.cassign">[[simd.cassign]]</a>
42
+
43
+ ``` cpp
44
+ friend constexpr basic_vec& operator+=(basic_vec& lhs, const basic_vec& rhs) noexcept;
45
+ friend constexpr basic_vec& operator-=(basic_vec& lhs, const basic_vec& rhs) noexcept;
46
+ friend constexpr basic_vec& operator*=(basic_vec& lhs, const basic_vec& rhs) noexcept;
47
+ friend constexpr basic_vec& operator/=(basic_vec& lhs, const basic_vec& rhs) noexcept;
48
+ friend constexpr basic_vec& operator%=(basic_vec& lhs, const basic_vec& rhs) noexcept;
49
+ friend constexpr basic_vec& operator&=(basic_vec& lhs, const basic_vec& rhs) noexcept;
50
+ friend constexpr basic_vec& operator|=(basic_vec& lhs, const basic_vec& rhs) noexcept;
51
+ friend constexpr basic_vec& operator^=(basic_vec& lhs, const basic_vec& rhs) noexcept;
52
+ friend constexpr basic_vec& operator<<=(basic_vec& lhs, const basic_vec& rhs) noexcept;
53
+ friend constexpr basic_vec& operator>>=(basic_vec& lhs, const basic_vec& rhs) noexcept;
54
+ ```
55
+
56
+ Let *op* be the operator.
57
+
58
+ *Constraints:* `requires (value_type a, value_type b) { a `*`op`*` b; }`
59
+ is `true`.
60
+
61
+ *Effects:* These operators apply the indicated operator to `lhs` and
62
+ `rhs` as an element-wise operation.
63
+
64
+ *Returns:* `lhs`.
65
+
66
+ ``` cpp
67
+ friend constexpr basic_vec& operator<<=(basic_vec& lhs, simd-size-type n) noexcept;
68
+ friend constexpr basic_vec& operator>>=(basic_vec& lhs, simd-size-type n) noexcept;
69
+ ```
70
+
71
+ Let *op* be the operator.
72
+
73
+ *Constraints:*
74
+ `requires (value_type a, `*`simd-size-type`*` b) { a `*`op`*` b; }` is
75
+ `true`.
76
+
77
+ *Effects:* Equivalent to:
78
+ `return operator `*`op`*` (lhs, basic_vec(n));`
79
+
80
+ #### Comparison operators <a id="simd.comparison">[[simd.comparison]]</a>
81
+
82
+ ``` cpp
83
+ friend constexpr mask_type operator==(const basic_vec& lhs, const basic_vec& rhs) noexcept;
84
+ friend constexpr mask_type operator!=(const basic_vec& lhs, const basic_vec& rhs) noexcept;
85
+ friend constexpr mask_type operator>=(const basic_vec& lhs, const basic_vec& rhs) noexcept;
86
+ friend constexpr mask_type operator<=(const basic_vec& lhs, const basic_vec& rhs) noexcept;
87
+ friend constexpr mask_type operator>(const basic_vec& lhs, const basic_vec& rhs) noexcept;
88
+ friend constexpr mask_type operator<(const basic_vec& lhs, const basic_vec& rhs) noexcept;
89
+ ```
90
+
91
+ Let *op* be the operator.
92
+
93
+ *Constraints:* `requires (value_type a, value_type b) { a `*`op`*` b; }`
94
+ is `true`.
95
+
96
+ *Returns:* A `basic_mask` object initialized with the results of
97
+ applying *op* to `lhs` and `rhs` as a binary element-wise operation.
98
+
99
+ #### Exposition-only conditional operators <a id="simd.cond">[[simd.cond]]</a>
100
+
101
+ ``` cpp
102
+ friend constexpr basic_vec
103
+ simd-select-impl(const mask_type& mask, const basic_vec& a, const basic_vec& b) noexcept;
104
+ ```
105
+
106
+ *Returns:* A `basic_vec` object where the iᵗʰ element equals
107
+ `mask[`i`] ? a[`i`] : b[`i`]` for all i in the range of \[`0`,
108
+ `size()`).
109
+
110
+ #### Reductions <a id="simd.reductions">[[simd.reductions]]</a>
111
+
112
+ ``` cpp
113
+ template<class T, class Abi, class BinaryOperation = plus<>>
114
+ constexpr T reduce(const basic_vec<T, Abi>& x, BinaryOperation binary_op = {});
115
+ ```
116
+
117
+ *Constraints:* `BinaryOperation` models `reduction-binary-operation<T>`.
118
+
119
+ *Preconditions:* `binary_op` does not modify `x`.
120
+
121
+ *Returns:* *GENERALIZED_SUM*(binary_op, vec\<T, 1\>(x\[0\]), …, vec\<T,
122
+ 1\>(x\[x.size() - 1\]))\[0\] [[numerics.defns]].
123
+
124
+ *Throws:* Any exception thrown from `binary_op`.
125
+
126
+ ``` cpp
127
+ template<class T, class Abi, class BinaryOperation = plus<>>
128
+ constexpr T reduce(
129
+ const basic_vec<T, Abi>& x, const typename basic_vec<T, Abi>::mask_type& mask,
130
+ BinaryOperation binary_op = {}, type_identity_t<T> identity_element = see below);
131
+ ```
132
+
133
+ *Constraints:*
134
+
135
+ - `BinaryOperation` models `reduction-binary-operation<T>`.
136
+ - An argument for `identity_element` is provided for the invocation,
137
+ unless `BinaryOperation` is one of `plus<>`, `multiplies<>`,
138
+ `bit_and<>`, `bit_or<>`, or `bit_xor<>`.
139
+
140
+ *Preconditions:*
141
+
142
+ - `binary_op` does not modify `x`.
143
+ - For all finite values `y` representable by `T`, the results of
144
+ `y == binary_op(vec<T, 1>(identity_element), vec<T, 1>(y))[0]` and
145
+ `y == binary_op(vec<T, 1>(y), vec<T, 1>(identity_element))[0]` are
146
+ `true`.
147
+
148
+ *Returns:* If `none_of(mask)` is `true`, returns `identity_element`.
149
+ Otherwise, returns *GENERALIZED_SUM*(binary_op, vec\<T, 1\>(x\[k₀\]), …,
150
+ vec\<T, 1\>(x\[kₙ\]))\[0\] where k₀, …, kₙ are the selected indices of
151
+ `mask`.
152
+
153
+ *Throws:* Any exception thrown from `binary_op`.
154
+
155
+ *Remarks:* The default argument for `identity_element` is equal to
156
+
157
+ - `T()` if `BinaryOperation` is `plus<>`,
158
+ - `T(1)` if `BinaryOperation` is `multiplies<>`,
159
+ - `T(~T())` if `BinaryOperation` is `bit_and<>`,
160
+ - `T()` if `BinaryOperation` is `bit_or<>`, or
161
+ - `T()` if `BinaryOperation` is `bit_xor<>`.
162
+
163
+ ``` cpp
164
+ template<class T, class Abi> constexpr T reduce_min(const basic_vec<T, Abi>& x) noexcept;
165
+ ```
166
+
167
+ *Constraints:* `T` models `totally_ordered`.
168
+
169
+ *Returns:* The value of an element `x[`j`]` for which `x[`i`] < x[`j`]`
170
+ is `false` for all i in the range of \[`0`,
171
+ `basic_vec<T, Abi>::size()`).
172
+
173
+ ``` cpp
174
+ template<class T, class Abi>
175
+ constexpr T reduce_min(
176
+ const basic_vec<T, Abi>&, const typename basic_vec<T, Abi>::mask_type&) noexcept;
177
+ ```
178
+
179
+ *Constraints:* `T` models `totally_ordered`.
180
+
181
+ *Returns:* If `none_of(mask)` is `true`, returns
182
+ `numeric_limits<T>::max()`. Otherwise, returns the value of a selected
183
+ element `x[`j`]` for which `x[`i`] < x[`j`]` is `false` for all selected
184
+ indices i of `mask`.
185
+
186
+ ``` cpp
187
+ template<class T, class Abi> constexpr T reduce_max(const basic_vec<T, Abi>& x) noexcept;
188
+ ```
189
+
190
+ *Constraints:* `T` models `totally_ordered`.
191
+
192
+ *Returns:* The value of an element `x[`j`]` for which `x[`j`] < x[`i`]`
193
+ is `false` for all i in the range of \[`0`,
194
+ `basic_vec<T, Abi>::size()`).
195
+
196
+ ``` cpp
197
+ template<class T, class Abi>
198
+ constexpr T reduce_max(
199
+ const basic_vec<T, Abi>&, const typename basic_vec<T, Abi>::mask_type&) noexcept;
200
+ ```
201
+
202
+ *Constraints:* `T` models `totally_ordered`.
203
+
204
+ *Returns:* If `none_of(mask)` is `true`, returns
205
+ `numeric_limits<V::value_type>::lowest()`. Otherwise, returns the value
206
+ of a selected element `x[`j`]` for which `x[`j`] < x[`i`]` is `false`
207
+ for all selected indices i of `mask`.
208
+
209
+ #### Load and store functions <a id="simd.loadstore">[[simd.loadstore]]</a>
210
+
211
+ ``` cpp
212
+ template<class V = see below, ranges::contiguous_range R, class... Flags>
213
+ requires ranges::sized_range<R>
214
+ constexpr V unchecked_load(R&& r, flags<Flags...> f = {});
215
+ template<class V = see below, ranges::contiguous_range R, class... Flags>
216
+ requires ranges::sized_range<R>
217
+ constexpr V unchecked_load(R&& r, const typename V::mask_type& mask, flags<Flags...> f = {});
218
+ template<class V = see below, contiguous_iterator I, class... Flags>
219
+ constexpr V unchecked_load(I first, iter_difference_t<I> n, flags<Flags...> f = {});
220
+ template<class V = see below, contiguous_iterator I, class... Flags>
221
+ constexpr V unchecked_load(I first, iter_difference_t<I> n, const typename V::mask_type& mask,
222
+ flags<Flags...> f = {});
223
+ template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags>
224
+ constexpr V unchecked_load(I first, S last, flags<Flags...> f = {});
225
+ template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags>
226
+ constexpr V unchecked_load(I first, S last, const typename V::mask_type& mask,
227
+ flags<Flags...> f = {});
228
+ ```
229
+
230
+ Let
231
+
232
+ - `mask` be `V::mask_type(true)` for the overloads with no `mask`
233
+ parameter;
234
+ - `R` be `span<const iter_value_t<I>>` for the overloads with no
235
+ template parameter `R`;
236
+ - `r` be `R(first, n)` for the overloads with an `n` parameter and
237
+ `R(first, last)` for the overloads with a `last` parameter.
238
+
239
+ *Mandates:* If `ranges::size(r)` is a constant expression then
240
+ `ranges::size(r)` ≥ `V::size()`.
241
+
242
+ *Preconditions:*
243
+
244
+ - \[`first`, `first + n`) is a valid range for the overloads with an `n`
245
+ parameter.
246
+ - \[`first`, `last`) is a valid range for the overloads with a `last`
247
+ parameter.
248
+ - `ranges::size(r)` ≥ `V::size()`
249
+
250
+ *Effects:* Equivalent to: `return partial_load<V>(r, mask, f);`
251
+
252
+ *Remarks:* The default argument for template parameter `V` is
253
+ `basic_vec<ranges::range_value_t<R>>`.
254
+
255
+ ``` cpp
256
+ template<class V = see below, ranges::contiguous_range R, class... Flags>
257
+ requires ranges::sized_range<R>
258
+ constexpr V partial_load(R&& r, flags<Flags...> f = {});
259
+ template<class V = see below, ranges::contiguous_range R, class... Flags>
260
+ requires ranges::sized_range<R>
261
+ constexpr V partial_load(R&& r, const typename V::mask_type& mask, flags<Flags...> f = {});
262
+ template<class V = see below, contiguous_iterator I, class... Flags>
263
+ constexpr V partial_load(I first, iter_difference_t<I> n, flags<Flags...> f = {});
264
+ template<class V = see below, contiguous_iterator I, class... Flags>
265
+ constexpr V partial_load(I first, iter_difference_t<I> n, const typename V::mask_type& mask,
266
+ flags<Flags...> f = {});
267
+ template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags>
268
+ constexpr V partial_load(I first, S last, flags<Flags...> f = {});
269
+ template<class V = see below, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags>
270
+ constexpr V partial_load(I first, S last, const typename V::mask_type& mask,
271
+ flags<Flags...> f = {});
272
+ ```
273
+
274
+ Let
275
+
276
+ - `mask` be `V::mask_type(true)` for the overloads with no `mask`
277
+ parameter;
278
+ - `R` be `span<const iter_value_t<I>>` for the overloads with no
279
+ template parameter `R`;
280
+ - `r` be `R(first, n)` for the overloads with an `n` parameter and
281
+ `R(first, last)` for the overloads with a `last` parameter.
282
+
283
+ *Mandates:*
284
+
285
+ - `ranges::range_value_t<R>` is a vectorizable type,
286
+ - `same_as<remove_cvref_t<V>, V>` is `true`,
287
+ - `V` is an enabled specialization of `basic_vec`, and
288
+ - if the template parameter pack `Flags` does not contain
289
+ *`convert-flag`*, then the conversion from `ranges::range_value_t<R>`
290
+ to `V::value_type` is value-preserving.
291
+
292
+ *Preconditions:*
293
+
294
+ - \[`first`, `first + n`) is a valid range for the overloads with an `n`
295
+ parameter.
296
+ - \[`first`, `last`) is a valid range for the overloads with a `last`
297
+ parameter.
298
+ - If the template parameter pack `Flags` contains *`aligned-flag`*,
299
+ `ranges::data(r)` points to storage aligned by
300
+ `alignment_v<V, ranges::range_value_t<R>>`.
301
+ - If the template parameter pack `Flags` contains
302
+ *`overaligned-flag`*`<N>`, `ranges::data(r)` points to storage aligned
303
+ by `N`.
304
+
305
+ *Effects:* Initializes the iᵗʰ element with
306
+ `mask[`i`] && `i` < ranges::size(r) ? static_cast<T>(ranges::data(r)[`i`]) : T()`
307
+ for all i in the range of \[`0`, `V::size()`).
308
+
309
+ *Remarks:* The default argument for template parameter `V` is
310
+ `basic_vec<ranges::range_value_t<R>>`.
311
+
312
+ ``` cpp
313
+ template<class T, class Abi, ranges::contiguous_range R, class... Flags>
314
+ requires ranges::sized_range<R> && indirectly_writable<ranges::iterator_t<R>, T>
315
+ constexpr void unchecked_store(const basic_vec<T, Abi>& v, R&& r, flags<Flags...> f = {});
316
+ template<class T, class Abi, ranges::contiguous_range R, class... Flags>
317
+ requires ranges::sized_range<R> && indirectly_writable<ranges::iterator_t<R>, T>
318
+ constexpr void unchecked_store(const basic_vec<T, Abi>& v, R&& r,
319
+ const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
320
+ template<class T, class Abi, contiguous_iterator I, class... Flags>
321
+ requires indirectly_writable<I, T>
322
+ constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
323
+ flags<Flags...> f = {});
324
+ template<class T, class Abi, contiguous_iterator I, class... Flags>
325
+ requires indirectly_writable<I, T>
326
+ constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
327
+ const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
328
+ template<class T, class Abi, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags>
329
+ requires indirectly_writable<I, T>
330
+ constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, S last,
331
+ flags<Flags...> f = {});
332
+ template<class T, class Abi, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags>
333
+ requires indirectly_writable<I, T>
334
+ constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, S last,
335
+ const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
336
+ ```
337
+
338
+ Let
339
+
340
+ - `mask` be `basic_vec<T, Abi>::mask_type(true)` for the overloads with
341
+ no `mask` parameter;
342
+ - `R` be `span<iter_value_t<I>>` for the overloads with no template
343
+ parameter `R`;
344
+ - `r` be `R(first, n)` for the overloads with an `n` parameter and
345
+ `R(first, last)` for the overloads with a `last` parameter.
346
+
347
+ *Mandates:* If `ranges::size(r)` is a constant expression then
348
+ `ranges::size(r)` ≥ *`simd-size-v`*`<T, Abi>`.
349
+
350
+ *Preconditions:*
351
+
352
+ - \[`first`, `first + n`) is a valid range for the overloads with an `n`
353
+ parameter.
354
+ - \[`first`, `last`) is a valid range for the overloads with a `last`
355
+ parameter.
356
+ - `ranges::size(r)` ≥ *`simd-size-v`*`<T, Abi>`
357
+
358
+ *Effects:* Equivalent to: `partial_store(v, r, mask, f)`.
359
+
360
+ ``` cpp
361
+ template<class T, class Abi, ranges::contiguous_range R, class... Flags>
362
+ requires ranges::sized_range<R> && indirectly_writable<ranges::iterator_t<R>, T>
363
+ constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r, flags<Flags...> f = {});
364
+ template<class T, class Abi, ranges::contiguous_range R, class... Flags>
365
+ requires ranges::sized_range<R> && indirectly_writable<ranges::iterator_t<R>, T>
366
+ constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r,
367
+ const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
368
+ template<class T, class Abi, contiguous_iterator I, class... Flags>
369
+ requires indirectly_writable<I, T>
370
+ constexpr void partial_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
371
+ flags<Flags...> f = {});
372
+ template<class T, class Abi, contiguous_iterator I, class... Flags>
373
+ requires indirectly_writable<I, T>
374
+ constexpr void partial_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
375
+ const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
376
+ template<class T, class Abi, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags>
377
+ requires indirectly_writable<I, T>
378
+ constexpr void partial_store(const basic_vec<T, Abi>& v, I first, S last,
379
+ flags<Flags...> f = {});
380
+ template<class T, class Abi, contiguous_iterator I, sized_sentinel_for<I> S, class... Flags>
381
+ requires indirectly_writable<I, T>
382
+ constexpr void partial_store(const basic_vec<T, Abi>& v, I first, S last,
383
+ const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
384
+ ```
385
+
386
+ Let
387
+
388
+ - `mask` be `basic_vec<T, Abi>::mask_type(true)` for the overloads with
389
+ no `mask` parameter;
390
+ - `R` be `span<iter_value_t<I>>` for the overloads with no template
391
+ parameter `R`;
392
+ - `r` be `R(first, n)` for the overloads with an `n` parameter and
393
+ `R(first, last)` for the overloads with a `last` parameter.
394
+
395
+ *Mandates:*
396
+
397
+ - `ranges::range_value_t<R>` is a vectorizable type, and
398
+ - if the template parameter pack `Flags` does not contain
399
+ *`convert-flag`*, then the conversion from `T` to
400
+ `ranges::range_value_t<R>` is value-preserving.
401
+
402
+ *Preconditions:*
403
+
404
+ - \[`first`, `first + n`) is a valid range for the overloads with an `n`
405
+ parameter.
406
+ - \[`first`, `last`) is a valid range for the overloads with a `last`
407
+ parameter.
408
+ - If the template parameter pack `Flags` contains *`aligned-flag`*,
409
+ `ranges::data(r)` points to storage aligned by
410
+ `alignment_v<basic_vec<T, Abi>, ranges::range_value_t<R>>`.
411
+ - If the template parameter pack `Flags` contains
412
+ *`overaligned-flag`*`<N>`, `ranges::data(r)` points to storage aligned
413
+ by `N`.
414
+
415
+ *Effects:* For all i in the range of \[`0`,
416
+ `basic_vec<T, Abi>::size()`), if `mask[`i`] && `i` < ranges::size(r)` is
417
+ `true`, evaluates `ranges::data(r)[`i`] = v[`i`]`.
418
+
419
+ #### Static permute <a id="simd.permute.static">[[simd.permute.static]]</a>
420
+
421
+ ``` cpp
422
+ template<simd-size-type N = see below, simd-vec-type V, class IdxMap>
423
+ constexpr resize_t<N, V> permute(const V& v, IdxMap&& idxmap);
424
+ template<simd-size-type N = see below, simd-mask-type M, class IdxMap>
425
+ constexpr resize_t<N, M> permute(const M& v, IdxMap&& idxmap);
426
+ ```
427
+
428
+ Let:
429
+
430
+ - *`gen-fn`*`(i)` be `idxmap(i, V::size())` if that expression is
431
+ well-formed, and `idxmap(i)` otherwise.
432
+ - *perm-fn* be the following exposition-only function template:
433
+ ``` cpp
434
+ template<simd-size-type I>
435
+ typename V::value_type perm-fn() {
436
+ constexpr auto src_index = gen-fn(I);
437
+ if constexpr (src_index == zero_element) {
438
+ return typename V::value_type();
439
+ } else if constexpr (src_index == uninit_element) {
440
+ return unspecified-value;
441
+ } else {
442
+ return v[src_index];
443
+ }
444
+ }
445
+ ```
446
+
447
+ *Constraints:* At least one of
448
+ `invoke_result_t<IdxMap&, `*`simd-size-type`*`>` and
449
+ `invoke_result_t<IdxMap&, `*`simd-size-type`*`, `*`simd-size-type`*`>`
450
+ satisfies `integral`.
451
+
452
+ *Mandates:* *`gen-fn`*`(`i`)` is a constant expression whose value is
453
+ `zero_element`, `uninit_element`, or in the range \[`0`, `V::size()`),
454
+ for all i in the range \[`0`, `N`).
455
+
456
+ *Returns:* A data-parallel object where the iᵗʰ element is initialized
457
+ to the result of *`perm-fn`*`<`i`>()` for all i in the range \[`0`,
458
+ `N`).
459
+
460
+ *Remarks:* The default argument for template parameter `N` is
461
+ `V::size()`.
462
+
463
+ #### Dynamic permute <a id="simd.permute.dynamic">[[simd.permute.dynamic]]</a>
464
+
465
+ ``` cpp
466
+ template<simd-vec-type V, simd-integral I>
467
+ constexpr resize_t<I::size(), V> permute(const V& v, const I& indices);
468
+ template<simd-mask-type M, simd-integral I>
469
+ constexpr resize_t<I::size(), M> permute(const M& v, const I& indices);
470
+ ```
471
+
472
+ *Preconditions:* All values in `indices` are in the range \[`0`,
473
+ `V::size()`).
474
+
475
+ *Returns:* A data-parallel object where the iᵗʰ element is initialized
476
+ to the result of `v[indices[`i`]]` for all i in the range \[`0`,
477
+ `I::size()`).
478
+
479
+ #### Mask permute <a id="simd.permute.mask">[[simd.permute.mask]]</a>
480
+
481
+ ``` cpp
482
+ template<simd-vec-type V>
483
+ constexpr V compress(const V& v, const typename V::mask_type& selector);
484
+ template<simd-mask-type M>
485
+ constexpr M compress(const M& v, const type_identity_t<M>& selector);
486
+ ```
487
+
488
+ Let:
489
+
490
+ - *`bit-index`*`(`i`)` be a function which returns the index of the iᵗʰ
491
+ element of `selector` that is `true`.
492
+ - *`select-value`*`(`i`)` be a function which returns
493
+ `v[`*`bit-index`*`(`i`)]` for i in the range \[`0`,
494
+ `reduce_count(selector)`) and a valid but unspecified value otherwise.
495
+ \[*Note 1*: Different calls to *`select-value`* can return different
496
+ unspecified values. — *end note*]
497
+
498
+ *Returns:* A data-parallel object where the iᵗʰ element is initialized
499
+ to the result of *`select-value`*`(`i`)` for all i in the range \[`0`,
500
+ `V::size()`).
501
+
502
+ ``` cpp
503
+ template<simd-vec-type V>
504
+ constexpr V compress(const V& v, const typename V::mask_type& selector,
505
+ const typename V::value_type& fill_value);
506
+ template<simd-mask-type M>
507
+ constexpr M compress(const M& v, const type_identity_t<M>& selector,
508
+ const typename M::value_type& fill_value);
509
+ ```
510
+
511
+ Let:
512
+
513
+ - *`bit-index`*`(`i`)` be a function which returns the index of the iᵗʰ
514
+ element of `selector` that is `true`.
515
+ - *`select-value`*`(`i`)` be a function which returns
516
+ `v[`*`bit-index`*`(`i`)]` for i in the range \[`0`,
517
+ `reduce_count(selector)`) and `fill_value` otherwise.
518
+
519
+ *Returns:* A data-parallel object where the iᵗʰ element is initialized
520
+ to the result of *`select-value`*`(`i`)` for all i in the range \[`0`,
521
+ `V::size()`).
522
+
523
+ ``` cpp
524
+ template<simd-vec-type V>
525
+ constexpr V expand(const V& v, const typename V::mask_type& selector, const V& original = {});
526
+ template<simd-mask-type M>
527
+ constexpr M expand(const M& v, const type_identity_t<M>& selector, const M& original = {});
528
+ ```
529
+
530
+ Let:
531
+
532
+ - *set-indices* be a list of the index positions of `true` elements in
533
+ `selector`, in ascending order.
534
+ - *`bit-lookup`*`(`b`)` be a function which returns the index where b
535
+ appears in *`set-indices`*.
536
+ - *`select-value`*`(`i`)` be a function which returns
537
+ `v[`*`bit-lookup`*`(`i`)]` if `selector[`i`]` is `true`, otherwise
538
+ returns `original[`i`]`.
539
+
540
+ *Returns:* A data-parallel object where the iᵗʰ element is initialized
541
+ to the result of *`select-value`*`(`i`)` for all i in the range \[`0`,
542
+ `V::size()`).
543
+
544
+ #### Memory permute <a id="simd.permute.memory">[[simd.permute.memory]]</a>
545
+
546
+ ``` cpp
547
+ template<class V = see below, ranges::contiguous_range R, simd-integral I, class... Flags>
548
+ requires ranges::sized_range<R>
549
+ constexpr V unchecked_gather_from(R&& in, const I& indices, flags<Flags...> f = {});
550
+ template<class V = see below, ranges::contiguous_range R, simd-integral I, class... Flags>
551
+ requires ranges::sized_range<R>
552
+ constexpr V unchecked_gather_from(R&& in, const typename I::mask_type& mask,
553
+ const I& indices, flags<Flags...> f = {});
554
+ ```
555
+
556
+ Let `mask` be `typename I::mask_type(true)` for the overload with no
557
+ `mask` parameter.
558
+
559
+ *Preconditions:* All values in
560
+ `select(mask, indices, typename I::value_type())` are in the range
561
+ \[`0`, `ranges::size(in)`).
562
+
563
+ *Effects:* Equivalent to:
564
+ `return partial_gather_from<V>(in, mask, indices, f);`
565
+
566
+ *Remarks:* The default argument for template parameter `V` is
567
+ `vec<ranges::range_value_t<R>, I::size()>`.
568
+
569
+ ``` cpp
570
+ template<class V = see below, ranges::contiguous_range R, simd-integral I, class... Flags>
571
+ requires ranges::sized_range<R>
572
+ constexpr V partial_gather_from(R&& in, const I& indices, flags<Flags...> f = {});
573
+ template<class V = see below, ranges::contiguous_range R, simd-integral I, class... Flags>
574
+ requires ranges::sized_range<R>
575
+ constexpr V partial_gather_from(R&& in, const typename I::mask_type& mask,
576
+ const I& indices, flags<Flags...> f = {});
577
+ ```
578
+
579
+ Let:
580
+
581
+ - `mask` be `typename I::mask_type(true)` for the overload with no
582
+ `mask` parameter;
583
+ - `T` be `typename V::value_type`.
584
+
585
+ *Mandates:*
586
+
587
+ - `ranges::range_value_t<R>` is a vectorizable type,
588
+ - `same_as<remove_cvref_t<V>, V>` is `true`,
589
+ - `V` is an enabled specialization of `basic_vec`,
590
+ - `V::size() == I::size()` is `true`, and
591
+ - if the template parameter pack `Flags` does not contain
592
+ *convert-flag*, then the conversion from `ranges::range_value_t<R>` to
593
+ `T` is value-preserving.
594
+
595
+ *Preconditions:*
596
+
597
+ - If the template parameter pack `Flags` contains *aligned-flag*,
598
+ `ranges::data(in)` points to storage aligned by
599
+ `alignment_v<V, ranges::range_value_t<R>>`.
600
+ - If the template parameter pack `Flags` contains
601
+ *`overaligned-flag`*`<N>`, `ranges::data(in)` points to storage
602
+ aligned by `N`.
603
+
604
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
605
+ the result of
606
+
607
+ ``` cpp
608
+ mask[i] && indices[i] < ranges::size(in) ? static_cast<T>(ranges::data(in)[indices[i]]) : T()
609
+ ```
610
+
611
+ for all i in the range \[`0`, `I::size()`).
612
+
613
+ *Remarks:* The default argument for template parameter `V` is
614
+ `vec<ranges::range_value_t<R>, I::size()>`.
615
+
616
+ ``` cpp
617
+ template<simd-vec-type V, ranges::contiguous_range R, simd-integral I, class... Flags>
618
+ requires ranges::sized_range<R>
619
+ constexpr void unchecked_scatter_to(const V& v, R&& out, const I& indices,
620
+ flags<Flags...> f = {});
621
+ template<simd-vec-type V, ranges::contiguous_range R, simd-integral I, class... Flags>
622
+ requires ranges::sized_range<R>
623
+ constexpr void unchecked_scatter_to(const V& v, R&& out, const typename I::mask_type& mask,
624
+ const I& indices, flags<Flags...> f = {});
625
+ ```
626
+
627
+ Let `mask` be `typename I::mask_type(true)` for the overload with no
628
+ `mask` parameter.
629
+
630
+ *Preconditions:* All values in
631
+ `select(mask, indices, typename I::value_type())` are in the range
632
+ \[`0`, `ranges::size(out)`).
633
+
634
+ *Effects:* Equivalent to:
635
+ `partial_scatter_to(v, out, mask, indices, f);`
636
+
637
+ ``` cpp
638
+ template<simd-vec-type V, ranges::contiguous_range R, simd-integral I, class... Flags>
639
+ requires ranges::sized_range<R>
640
+ constexpr void
641
+ partial_scatter_to(const V& v, R&& out, const I& indices, flags<Flags...> f = {});
642
+ template<simd-vec-type V, ranges::contiguous_range R, simd-integral I, class... Flags>
643
+ requires ranges::sized_range<R>
644
+ constexpr void partial_scatter_to(const V& v, R&& out, const typename I::mask_type& mask,
645
+ const I& indices, flags<Flags...> f = {});
646
+ ```
647
+
648
+ Let `mask` be `typename I::mask_type(true)` for the overload with no
649
+ `mask` parameter.
650
+
651
+ *Constraints:* `V::size() == I::size()` is `true`.
652
+
653
+ *Mandates:*
654
+
655
+ - `ranges::range_value_t<R>` is a vectorizable type, and
656
+ - if the template parameter pack `Flags` does not contain
657
+ *convert-flag*, then the conversion from `typename V::value_type` to
658
+ `ranges::range_value_t<R>` is value-preserving.
659
+
660
+ *Preconditions:*
661
+
662
+ - For all selected indices i the values `indices[`i`]` are unique.
663
+ - If the template parameter pack `Flags` contains *aligned-flag*,
664
+ `ranges::data(out)` points to storage aligned by
665
+ `alignment_v<V, ranges::range_value_t<R>>`.
666
+ - If the template parameter pack `Flags` contains
667
+ *`overaligned-flag`*`<N>`, `ranges::data(out)` points to storage
668
+ aligned by `N`.
669
+
670
+ *Effects:* For all i in the range \[`0`, `I::size()`), if
671
+ `mask[`i`] && (indices[`i`] < ranges::size(out))` is `true`, evaluates
672
+ `ranges::data(out)[indices[`i`]] = v[`i`]`.
673
+
674
+ #### Creation <a id="simd.creation">[[simd.creation]]</a>
675
+
676
+ ``` cpp
677
+ template<class T, class Abi>
678
+ constexpr auto chunk(const basic_vec<typename T::value_type, Abi>& x) noexcept;
679
+ template<class T, class Abi>
680
+ constexpr auto chunk(const basic_mask<mask-element-size<T>, Abi>& x) noexcept;
681
+ ```
682
+
683
+ *Constraints:*
684
+
685
+ - For the first overload, `T` is an enabled specialization of
686
+ `basic_vec`. If
687
+ `basic_vec<typename T::value_type, Abi>::size() % T::size()` is not
688
+ `0`, then
689
+ `resize_t<basic_vec<typename T::value_type, Abi>::size() % T::size(), T>`
690
+ is valid and denotes a type.
691
+ - For the second overload, `T` is an enabled specialization of
692
+ `basic_mask`. If
693
+ `basic_mask<`*`mask-element-size`*`<T>, Abi>::size() % T::size()` is
694
+ not `0`, then
695
+ `resize_t<basic_mask<`*`mask-element-size`*`<T>, Abi>::size() % T::size(), T>`
696
+ is valid and denotes a type.
697
+
698
+ Let N be `x.size() / T::size()`.
699
+
700
+ *Returns:*
701
+
702
+ - If `x.size() % T::size() == 0` is `true`, an `array<T, `N`>` with the
703
+ iᵗʰ `basic_vec` or `basic_mask` element of the jᵗʰ `array` element
704
+ initialized to the value of the element in `x` with index
705
+ i` + `j` * T::size()`.
706
+ - Otherwise, a `tuple` of N objects of type `T` and one object of type
707
+ `resize_t<x.size() % T::size(), T>`. The iᵗʰ `basic_vec` or
708
+ `basic_mask` element of the jᵗʰ `tuple` element of type `T` is
709
+ initialized to the value of the element in `x` with index
710
+ i` + `j` * T::size()`. The iᵗʰ `basic_vec` or `basic_mask` element of
711
+ the Nᵗʰ `tuple` element is initialized to the value of the element in
712
+ `x` with index i` + `N` * T::size()`.
713
+
714
+ ``` cpp
715
+ template<simd-size-type N, class T, class Abi>
716
+ constexpr auto chunk(const basic_vec<T, Abi>& x) noexcept;
717
+ ```
718
+
719
+ *Effects:* Equivalent to:
720
+ `return chunk<resize_t<N, basic_vec<T, Abi>>>(x);`
721
+
722
+ ``` cpp
723
+ template<simd-size-type N, size_t Bytes, class Abi>
724
+ constexpr auto chunk(const basic_mask<Bytes, Abi>& x) noexcept;
725
+ ```
726
+
727
+ *Effects:* Equivalent to:
728
+ `return chunk<resize_t<N, basic_mask<Bytes, Abi>>>(x);`
729
+
730
+ ``` cpp
731
+ template<class T, class... Abis>
732
+ constexpr vec<T, (basic_vec<T, Abis>::size() + ...)>
733
+ cat(const basic_vec<T, Abis>&... xs) noexcept;
734
+ template<size_t Bytes, class... Abis>
735
+ constexpr basic_mask<Bytes, deduce-abi-t<integer-from<Bytes>,
736
+ (basic_mask<Bytes, Abis>::size() + ...)>>
737
+ cat(const basic_mask<Bytes, Abis>&... xs) noexcept;
738
+ ```
739
+
740
+ *Constraints:*
741
+
742
+ - For the first overload `vec<T, (basic_vec<T, Abis>::size() + ...)>` is
743
+ enabled.
744
+ - For the second overload
745
+ `basic_mask<Bytes, `*`deduce-abi-t`*`<`*`integer-from`*`<Bytes>, (basic_mask<Bytes, Abis>::size() + ...)>>`
746
+ is enabled.
747
+
748
+ *Returns:* A data-parallel object initialized with the concatenated
749
+ values in the `xs` pack of data-parallel objects: The iᵗʰ
750
+ `basic_vec`/`basic_mask` element of the jᵗʰ parameter in the `xs` pack
751
+ is copied to the return value’s element with index i + the sum of the
752
+ width of the first j parameters in the `xs` pack.
753
+
754
+ #### Algorithms <a id="simd.alg">[[simd.alg]]</a>
755
+
756
+ ``` cpp
757
+ template<class T, class Abi>
758
+ constexpr basic_vec<T, Abi> min(const basic_vec<T, Abi>& a,
759
+ const basic_vec<T, Abi>& b) noexcept;
760
+ ```
761
+
762
+ *Constraints:* `T` models `totally_ordered`.
763
+
764
+ *Returns:* The result of the element-wise application of
765
+ `min(a[`i`], b[`i`])` for all i in the range of \[`0`,
766
+ `basic_vec<T, Abi>::size()`).
767
+
768
+ ``` cpp
769
+ template<class T, class Abi>
770
+ constexpr basic_vec<T, Abi> max(const basic_vec<T, Abi>& a,
771
+ const basic_vec<T, Abi>& b) noexcept;
772
+ ```
773
+
774
+ *Constraints:* `T` models `totally_ordered`.
775
+
776
+ *Returns:* The result of the element-wise application of
777
+ `max(a[`i`], b[`i`])` for all i in the range of \[`0`,
778
+ `basic_vec<T, Abi>::size()`).
779
+
780
+ ``` cpp
781
+ template<class T, class Abi>
782
+ constexpr pair<basic_vec<T, Abi>, basic_vec<T, Abi>>
783
+ minmax(const basic_vec<T, Abi>& a, const basic_vec<T, Abi>& b) noexcept;
784
+ ```
785
+
786
+ *Effects:* Equivalent to: `return pair{min(a, b), max(a, b)};`
787
+
788
+ ``` cpp
789
+ template<class T, class Abi>
790
+ constexpr basic_vec<T, Abi> clamp(
791
+ const basic_vec<T, Abi>& v, const basic_vec<T, Abi>& lo, const basic_vec<T, Abi>& hi);
792
+ ```
793
+
794
+ *Constraints:* `T` models `totally_ordered`.
795
+
796
+ *Preconditions:* No element in `lo` is greater than the corresponding
797
+ element in `hi`.
798
+
799
+ *Returns:* The result of element-wise application of
800
+ `clamp(v[`i`], lo[`i`], hi[`i`])` for all i in the range of \[`0`,
801
+ `basic_vec<T, Abi>::size()`).
802
+
803
+ ``` cpp
804
+ template<class T, class U>
805
+ constexpr auto select(bool c, const T& a, const U& b)
806
+ -> remove_cvref_t<decltype(c ? a : b)>;
807
+ ```
808
+
809
+ *Effects:* Equivalent to: `return c ? a : b;`
810
+
811
+ ``` cpp
812
+ template<size_t Bytes, class Abi, class T, class U>
813
+ constexpr auto select(const basic_mask<Bytes, Abi>& c, const T& a, const U& b)
814
+ noexcept -> decltype(simd-select-impl(c, a, b));
815
+ ```
816
+
817
+ *Effects:* Equivalent to:
818
+
819
+ ``` cpp
820
+ return simd-select-impl(c, a, b);
821
+ ```
822
+
823
+ where *`simd-select-impl`* is found by argument-dependent
824
+ lookup [[basic.lookup.argdep]] contrary to [[contents]].
825
+
826
+ #### Mathematical functions <a id="simd.math">[[simd.math]]</a>
827
+
828
+ ``` cpp
829
+ template<math-floating-point V>
830
+ constexpr rebind_t<int, deduced-vec-t<V>> ilogb(const V& x);
831
+ template<math-floating-point V>
832
+ constexpr deduced-vec-t<V> ldexp(const V& x, const rebind_t<int, deduced-vec-t<V>>& exp);
833
+ template<math-floating-point V>
834
+ constexpr deduced-vec-t<V> scalbn(const V& x, const rebind_t<int, deduced-vec-t<V>>& n);
835
+ template<math-floating-point V>
836
+ constexpr deduced-vec-t<V>
837
+ scalbln(const V& x, const rebind_t<long int, deduced-vec-t<V>>& n);
838
+ template<signed_integral T, class Abi>
839
+ constexpr basic_vec<T, Abi> abs(const basic_vec<T, Abi>& j);
840
+ template<math-floating-point V>
841
+ constexpr deduced-vec-t<V> abs(const V& j);
842
+ template<math-floating-point V>
843
+ constexpr deduced-vec-t<V> fabs(const V& x);
844
+ template<math-floating-point V>
845
+ constexpr deduced-vec-t<V> ceil(const V& x);
846
+ template<math-floating-point V>
847
+ constexpr deduced-vec-t<V> floor(const V& x);
848
+ template<math-floating-point V>
849
+ deduced-vec-t<V> nearbyint(const V& x);
850
+ template<math-floating-point V>
851
+ deduced-vec-t<V> rint(const V& x);
852
+ template<math-floating-point V>
853
+ rebind_t<long int, deduced-vec-t<V>> lrint(const V& x);
854
+ template<math-floating-point V>
855
+ rebind_t<long long int, deduced-vec-t<V>> llrint(const V& x);
856
+ template<math-floating-point V>
857
+ constexpr deduced-vec-t<V> round(const V& x);
858
+ template<math-floating-point V>
859
+ constexpr rebind_t<long int, deduced-vec-t<V>> lround(const V& x);
860
+ template<math-floating-point V>
861
+ constexpr rebind_t<long long int, deduced-vec-t<V>> llround(const V& x);
862
+ template<class V0, class V1>
863
+ constexpr math-common-simd-t<V0, V1> fmod(const V0& x, const V1& y);
864
+ template<math-floating-point V>
865
+ constexpr deduced-vec-t<V> trunc(const V& x);
866
+ template<class V0, class V1>
867
+ constexpr math-common-simd-t<V0, V1> remainder(const V0& x, const V1& y);
868
+ template<class V0, class V1>
869
+ constexpr math-common-simd-t<V0, V1> copysign(const V0& x, const V1& y);
870
+ template<class V0, class V1>
871
+ constexpr math-common-simd-t<V0, V1> nextafter(const V0& x, const V1& y);
872
+ template<class V0, class V1>
873
+ constexpr math-common-simd-t<V0, V1> fdim(const V0& x, const V1& y);
874
+ template<class V0, class V1>
875
+ constexpr math-common-simd-t<V0, V1> fmax(const V0& x, const V1& y);
876
+ template<class V0, class V1>
877
+ constexpr math-common-simd-t<V0, V1> fmin(const V0& x, const V1& y);
878
+ template<class V0, class V1, class V2>
879
+ constexpr math-common-simd-t<V0, V1, V2> fma(const V0& x, const V1& y, const V2& z);
880
+ template<math-floating-point V>
881
+ constexpr rebind_t<int, deduced-vec-t<V>> fpclassify(const V& x);
882
+ template<math-floating-point V>
883
+ constexpr typename deduced-vec-t<V>::mask_type isfinite(const V& x);
884
+ template<math-floating-point V>
885
+ constexpr typename deduced-vec-t<V>::mask_type isinf(const V& x);
886
+ template<math-floating-point V>
887
+ constexpr typename deduced-vec-t<V>::mask_type isnan(const V& x);
888
+ template<math-floating-point V>
889
+ constexpr typename deduced-vec-t<V>::mask_type isnormal(const V& x);
890
+ template<math-floating-point V>
891
+ constexpr typename deduced-vec-t<V>::mask_type signbit(const V& x);
892
+ template<class V0, class V1>
893
+ constexpr typename math-common-simd-t<V0, V1>::mask_type isgreater(const V0& x, const V1& y);
894
+ template<class V0, class V1>
895
+ constexpr typename math-common-simd-t<V0, V1>::mask_type
896
+ isgreaterequal(const V0& x, const V1& y);
897
+ template<class V0, class V1>
898
+ constexpr typename math-common-simd-t<V0, V1>::mask_type isless(const V0& x, const V1& y);
899
+ template<class V0, class V1>
900
+ constexpr typename math-common-simd-t<V0, V1>::mask_type islessequal(const V0& x, const V1& y);
901
+ template<class V0, class V1>
902
+ constexpr typename math-common-simd-t<V0, V1>::mask_type islessgreater(const V0& x, const V1& y);
903
+ template<class V0, class V1>
904
+ constexpr typename math-common-simd-t<V0, V1>::mask_type isunordered(const V0& x, const V1& y);
905
+ ```
906
+
907
+ Let `Ret` denote the return type of the specialization of a function
908
+ template with the name *`math-func`*. Let *`math-func-vec`* denote:
909
+
910
+ ``` cpp
911
+ template<class... Args>
912
+ Ret math-func-vec(Args... args) {
913
+ return Ret([&](simd-size-type i) {
914
+ return math-func(make-compatible-simd-t<Ret, Args>(args)[i]...);
915
+ });
916
+ }
917
+ ```
918
+
919
+ *Returns:* A value `ret` of type `Ret`, that is element-wise equal to
920
+ the result of calling *`math-func-vec`* with the arguments of the above
921
+ functions. If in an invocation of a scalar overload of *`math-func`* for
922
+ index `i` in *`math-func-vec`* a domain, pole, or range error would
923
+ occur, the value of `ret[i]` is unspecified.
924
+
925
+ *Remarks:* It is unspecified whether `errno` [[errno]] is accessed.
926
+
927
+ ``` cpp
928
+ template<math-floating-point V> constexpr deduced-vec-t<V> acos(const V& x);
929
+ template<math-floating-point V> constexpr deduced-vec-t<V> asin(const V& x);
930
+ template<math-floating-point V> constexpr deduced-vec-t<V> atan(const V& x);
931
+ template<class V0, class V1>
932
+ constexpr math-common-simd-t<V0, V1> atan2(const V0& y, const V1& x);
933
+ template<math-floating-point V> constexpr deduced-vec-t<V> cos(const V& x);
934
+ template<math-floating-point V> constexpr deduced-vec-t<V> sin(const V& x);
935
+ template<math-floating-point V> constexpr deduced-vec-t<V> tan(const V& x);
936
+ template<math-floating-point V> constexpr deduced-vec-t<V> acosh(const V& x);
937
+ template<math-floating-point V> constexpr deduced-vec-t<V> asinh(const V& x);
938
+ template<math-floating-point V> constexpr deduced-vec-t<V> atanh(const V& x);
939
+ template<math-floating-point V> constexpr deduced-vec-t<V> cosh(const V& x);
940
+ template<math-floating-point V> constexpr deduced-vec-t<V> sinh(const V& x);
941
+ template<math-floating-point V> constexpr deduced-vec-t<V> tanh(const V& x);
942
+ template<math-floating-point V> constexpr deduced-vec-t<V> exp(const V& x);
943
+ template<math-floating-point V> constexpr deduced-vec-t<V> exp2(const V& x);
944
+ template<math-floating-point V> constexpr deduced-vec-t<V> expm1(const V& x);
945
+ template<math-floating-point V> constexpr deduced-vec-t<V> log(const V& x);
946
+ template<math-floating-point V> constexpr deduced-vec-t<V> log10(const V& x);
947
+ template<math-floating-point V> constexpr deduced-vec-t<V> log1p(const V& x);
948
+ template<math-floating-point V> constexpr deduced-vec-t<V> log2(const V& x);
949
+ template<math-floating-point V> constexpr deduced-vec-t<V> logb(const V& x);
950
+ template<math-floating-point V> constexpr deduced-vec-t<V> cbrt(const V& x);
951
+ template<class V0, class V1>
952
+ constexpr math-common-simd-t<V0, V1> hypot(const V0& x, const V1& y);
953
+ template<class V0, class V1, class V2>
954
+ constexpr math-common-simd-t<V0, V1, V2> hypot(const V0& x, const V1& y, const V2& z);
955
+ template<class V0, class V1>
956
+ constexpr math-common-simd-t<V0, V1> pow(const V0& x, const V1& y);
957
+ template<math-floating-point V> constexpr deduced-vec-t<V> sqrt(const V& x);
958
+ template<math-floating-point V> constexpr deduced-vec-t<V> erf(const V& x);
959
+ template<math-floating-point V> constexpr deduced-vec-t<V> erfc(const V& x);
960
+ template<math-floating-point V> constexpr deduced-vec-t<V> lgamma(const V& x);
961
+ template<math-floating-point V> constexpr deduced-vec-t<V> tgamma(const V& x);
962
+ template<class V0, class V1, class V2>
963
+ constexpr math-common-simd-t<V0, V1, V2> lerp(const V0& a, const V1& b, const V2& t) noexcept;
964
+ template<math-floating-point V>
965
+ deduced-vec-t<V> assoc_laguerre(const rebind_t<unsigned, deduced-vec-t<V>>& n, const
966
+ rebind_t<unsigned, deduced-vec-t<V>>& m, const V& x);
967
+ template<math-floating-point V>
968
+ deduced-vec-t<V> assoc_legendre(const rebind_t<unsigned, deduced-vec-t<V>>& l, const
969
+ rebind_t<unsigned, deduced-vec-t<V>>& m, const V& x);
970
+ template<class V0, class V1>
971
+ math-common-simd-t<V0, V1> beta(const V0& x, const V1& y);
972
+ template<math-floating-point V> deduced-vec-t<V> comp_ellint_1(const V& k);
973
+ template<math-floating-point V> deduced-vec-t<V> comp_ellint_2(const V& k);
974
+ template<class V0, class V1>
975
+ math-common-simd-t<V0, V1> comp_ellint_3(const V0& k, const V1& nu);
976
+ template<class V0, class V1>
977
+ math-common-simd-t<V0, V1> cyl_bessel_i(const V0& nu, const V1& x);
978
+ template<class V0, class V1>
979
+ math-common-simd-t<V0, V1> cyl_bessel_j(const V0& nu, const V1& x);
980
+ template<class V0, class V1>
981
+ math-common-simd-t<V0, V1> cyl_bessel_k(const V0& nu, const V1& x);
982
+ template<class V0, class V1>
983
+ math-common-simd-t<V0, V1> cyl_neumann(const V0& nu, const V1& x);
984
+ template<class V0, class V1>
985
+ math-common-simd-t<V0, V1> ellint_1(const V0& k, const V1& phi);
986
+ template<class V0, class V1>
987
+ math-common-simd-t<V0, V1> ellint_2(const V0& k, const V1& phi);
988
+ template<class V0, class V1, class V2>
989
+ math-common-simd-t<V0, V1, V2> ellint_3(const V0& k, const V1& nu, const V2& phi);
990
+ template<math-floating-point V> deduced-vec-t<V> expint(const V& x);
991
+ template<math-floating-point V> deduced-vec-t<V> hermite(const rebind_t<unsigned,
992
+ deduced-vec-t<V>>& n, const V& x);
993
+ template<math-floating-point V> deduced-vec-t<V> laguerre(const rebind_t<unsigned,
994
+ deduced-vec-t<V>>& n, const V& x);
995
+ template<math-floating-point V> deduced-vec-t<V> legendre(const rebind_t<unsigned,
996
+ deduced-vec-t<V>>& l, const V& x);
997
+ template<math-floating-point V> deduced-vec-t<V> riemann_zeta(const V& x);
998
+ template<math-floating-point V> deduced-vec-t<V> sph_bessel(const rebind_t<unsigned,
999
+ deduced-vec-t<V>>& n, const V& x);
1000
+ template<math-floating-point V>
1001
+ deduced-vec-t<V> sph_legendre(const rebind_t<unsigned, deduced-vec-t<V>>& l,
1002
+ const rebind_t<unsigned, deduced-vec-t<V>>& m,
1003
+ const V& theta);
1004
+ template<math-floating-point V> deduced-vec-t<V> sph_neumann(const rebind_t<unsigned,
1005
+ deduced-vec-t<V>>& n, const V& x);
1006
+ ```
1007
+
1008
+ Let `Ret` denote the return type of the specialization of a function
1009
+ template with the name *`math-func`*. Let *`math-func-vec`* denote:
1010
+
1011
+ ``` cpp
1012
+ template<class... Args>
1013
+ Ret math-func-vec(Args... args) {
1014
+ return Ret([&](simd-size-type i) {
1015
+ return math-func(make-compatible-simd-t<Ret, Args>(args)[i]...);
1016
+ });
1017
+ }
1018
+ ```
1019
+
1020
+ *Returns:* A value `ret` of type `Ret`, that is element-wise
1021
+ approximately equal to the result of calling *`math-func-vec`* with the
1022
+ arguments of the above functions. If in an invocation of a scalar
1023
+ overload of *`math-func`* for index `i` in *`math-func-vec`* a domain,
1024
+ pole, or range error would occur, the value of `ret[i]` is unspecified.
1025
+
1026
+ *Remarks:* It is unspecified whether `errno` [[errno]] is accessed.
1027
+
1028
+ ``` cpp
1029
+ template<math-floating-point V>
1030
+ constexpr deduced-vec-t<V> frexp(const V& value, rebind_t<int, deduced-vec-t<V>>* exp);
1031
+ ```
1032
+
1033
+ Let `Ret` be *`deduced-vec-t`*`<V>`. Let *`frexp-vec`* denote:
1034
+
1035
+ ``` cpp
1036
+ template<class V>
1037
+ pair<Ret, rebind_t<int, Ret>> frexp-vec(const V& x) {
1038
+ int r1[Ret::size()];
1039
+ Ret r0([&](simd-size-type i) {
1040
+ return frexp(make-compatible-simd-t<Ret, V>(x)[i], &r1[i]);
1041
+ });
1042
+ return {r0, rebind_t<int, Ret>(r1)};
1043
+ }
1044
+ ```
1045
+
1046
+ Let `ret` be a value of type `pair<Ret, rebind_t<int, Ret>>` that is the
1047
+ same value as the result of calling *`frexp-vec`*`(x)`.
1048
+
1049
+ *Effects:* Sets `*exp` to `ret.second`.
1050
+
1051
+ *Returns:* `ret.first`.
1052
+
1053
+ ``` cpp
1054
+ template<class V0, class V1>
1055
+ constexpr math-common-simd-t<V0, V1> remquo(const V0& x, const V1& y,
1056
+ rebind_t<int, math-common-simd-t<V0, V1>>* quo);
1057
+ ```
1058
+
1059
+ Let `Ret` be *`math-common-simd-t`*`<V0, V1>`. Let *`remquo-vec`*
1060
+ denote:
1061
+
1062
+ ``` cpp
1063
+ template<class V0, class V1>
1064
+ pair<Ret, rebind_t<int, Ret>> remquo-vec(const V0& x, const V1& y) {
1065
+ int r1[Ret::size()];
1066
+ Ret r0([&](simd-size-type i) {
1067
+ return remquo(make-compatible-simd-t<Ret, V0>(x)[i],
1068
+ make-compatible-simd-t<Ret, V1>(y)[i], &r1[i]);
1069
+ });
1070
+ return {r0, rebind_t<int, Ret>(r1)};
1071
+ }
1072
+ ```
1073
+
1074
+ Let `ret` be a value of type `pair<Ret, rebind_t<int, Ret>>` that is the
1075
+ same value as the result of calling *`remquo-vec`*`(x, y)`. If in an
1076
+ invocation of a scalar overload of `remquo` for index `i` in
1077
+ *`remquo-vec`* a domain, pole, or range error would occur, the value of
1078
+ `ret[i]` is unspecified.
1079
+
1080
+ *Effects:* Sets `*quo` to `ret.second`.
1081
+
1082
+ *Returns:* `ret.first`.
1083
+
1084
+ *Remarks:* It is unspecified whether `errno` [[errno]] is accessed.
1085
+
1086
+ ``` cpp
1087
+ template<class T, class Abi>
1088
+ constexpr basic_vec<T, Abi> modf(const type_identity_t<basic_vec<T, Abi>>& value,
1089
+ basic_vec<T, Abi>* iptr);
1090
+ ```
1091
+
1092
+ Let `V` be `basic_vec<T, Abi>`. Let *`modf-vec`* denote:
1093
+
1094
+ ``` cpp
1095
+ pair<V, V> modf-vec(const V& x) {
1096
+ T r1[Ret::size()];
1097
+ V r0([&](simd-size-type i) {
1098
+ return modf(V(x)[i], &r1[i]);
1099
+ });
1100
+ return {r0, V(r1)};
1101
+ }
1102
+ ```
1103
+
1104
+ Let `ret` be a value of type `pair<V, V>` that is the same value as the
1105
+ result of calling *`modf-vec`*`(value)`.
1106
+
1107
+ *Effects:* Sets `*iptr` to `ret.second`.
1108
+
1109
+ *Returns:* `ret.first`.
1110
+
1111
+ #### Bit manipulation <a id="simd.bit">[[simd.bit]]</a>
1112
+
1113
+ ``` cpp
1114
+ template<simd-vec-type V> constexpr V byteswap(const V& v) noexcept;
1115
+ ```
1116
+
1117
+ *Constraints:* The type `V::value_type` models `integral`.
1118
+
1119
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
1120
+ the result of `std::byteswap(v[`i`])` for all i in the range \[`0`,
1121
+ `V::size()`).
1122
+
1123
+ ``` cpp
1124
+ template<simd-vec-type V> constexpr V bit_ceil(const V& v) noexcept;
1125
+ ```
1126
+
1127
+ *Constraints:* The type `V::value_type` is an unsigned integer
1128
+ type [[basic.fundamental]].
1129
+
1130
+ *Preconditions:* For every i in the range \[`0`, `V::size()`), the
1131
+ smallest power of 2 greater than or equal to `v[`i`]` is representable
1132
+ as a value of type `V::value_type`.
1133
+
1134
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
1135
+ the result of `std::bit_ceil(v[`i`])` for all i in the range \[`0`,
1136
+ `V::size()`).
1137
+
1138
+ *Remarks:* A function call expression that violates the precondition in
1139
+ the *Preconditions:* element is not a core constant
1140
+ expression [[expr.const]].
1141
+
1142
+ ``` cpp
1143
+ template<simd-vec-type V> constexpr V bit_floor(const V& v) noexcept;
1144
+ ```
1145
+
1146
+ *Constraints:* The type `V::value_type` is an unsigned integer
1147
+ type [[basic.fundamental]].
1148
+
1149
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
1150
+ the result of `std::bit_floor(v[`i`])` for all i in the range \[`0`,
1151
+ `V::size()`).
1152
+
1153
+ ``` cpp
1154
+ template<simd-vec-type V>
1155
+ constexpr typename V::mask_type has_single_bit(const V& v) noexcept;
1156
+ ```
1157
+
1158
+ *Constraints:* The type `V::value_type` is an unsigned integer
1159
+ type [[basic.fundamental]].
1160
+
1161
+ *Returns:* A `basic_mask` object where the iᵗʰ element is initialized to
1162
+ the result of `std::has_single_bit(v[`i`])` for all i in the range
1163
+ \[`0`, `V::size()`).
1164
+
1165
+ ``` cpp
1166
+ template<simd-vec-type V0, simd-vec-type V1>
1167
+ constexpr V0 rotl(const V0& v0, const V1& v1) noexcept;
1168
+ template<simd-vec-type V0, simd-vec-type V1>
1169
+ constexpr V0 rotr(const V0& v0, const V1& v1) noexcept;
1170
+ ```
1171
+
1172
+ *Constraints:*
1173
+
1174
+ - The type `V0::value_type` is an unsigned integer
1175
+ type [[basic.fundamental]],
1176
+ - the type `V1::value_type` models `integral`,
1177
+ - `V0::size() == V1::size()` is `true`, and
1178
+ - `sizeof(typename V0::value_type) == sizeof(typename V1::value_type)`
1179
+ is `true`.
1180
+
1181
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
1182
+ the result of *`bit-func`*`(v0[`i`], static_cast<int>(v1[`i`]))` for all
1183
+ i in the range \[`0`, `V0::size()`), where *`bit-func`* is the
1184
+ corresponding scalar function from `<bit>`.
1185
+
1186
+ ``` cpp
1187
+ template<simd-vec-type V> constexpr V rotl(const V& v, int s) noexcept;
1188
+ template<simd-vec-type V> constexpr V rotr(const V& v, int s) noexcept;
1189
+ ```
1190
+
1191
+ *Constraints:* The type `V::value_type` is an unsigned integer
1192
+ type [[basic.fundamental]].
1193
+
1194
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
1195
+ the result of *`bit-func`*`(v[`i`], s)` for all i in the range \[`0`,
1196
+ `V::size()`), where *`bit-func`* is the corresponding scalar function
1197
+ from `<bit>`.
1198
+
1199
+ ``` cpp
1200
+ template<simd-vec-type V>
1201
+ constexpr rebind_t<make_signed_t<typename V::value_type>, V> bit_width(const V& v) noexcept;
1202
+ template<simd-vec-type V>
1203
+ constexpr rebind_t<make_signed_t<typename V::value_type>, V> countl_zero(const V& v) noexcept;
1204
+ template<simd-vec-type V>
1205
+ constexpr rebind_t<make_signed_t<typename V::value_type>, V> countl_one(const V& v) noexcept;
1206
+ template<simd-vec-type V>
1207
+ constexpr rebind_t<make_signed_t<typename V::value_type>, V> countr_zero(const V& v) noexcept;
1208
+ template<simd-vec-type V>
1209
+ constexpr rebind_t<make_signed_t<typename V::value_type>, V> countr_one(const V& v) noexcept;
1210
+ template<simd-vec-type V>
1211
+ constexpr rebind_t<make_signed_t<typename V::value_type>, V> popcount(const V& v) noexcept;
1212
+ ```
1213
+
1214
+ *Constraints:* The type `V::value_type` is an unsigned integer
1215
+ type [[basic.fundamental]].
1216
+
1217
+ *Returns:* A `basic_vec` object where the iᵗʰ element is initialized to
1218
+ the result of *`bit-func`*`(v[`i`])` for all i in the range \[`0`,
1219
+ `V::size()`), where *`bit-func`* is the corresponding scalar function
1220
+ from `<bit>`.
1221
+
1222
+ #### Complex math <a id="simd.complex.math">[[simd.complex.math]]</a>
1223
+
1224
+ ``` cpp
1225
+ template<simd-complex V>
1226
+ constexpr rebind_t<simd-complex-value-type<V>, V> real(const V&) noexcept;
1227
+ template<simd-complex V>
1228
+ constexpr rebind_t<simd-complex-value-type<V>, V> imag(const V&) noexcept;
1229
+
1230
+ template<simd-complex V>
1231
+ constexpr rebind_t<simd-complex-value-type<V>, V> abs(const V&);
1232
+ template<simd-complex V>
1233
+ constexpr rebind_t<simd-complex-value-type<V>, V> arg(const V&);
1234
+ template<simd-complex V>
1235
+ constexpr rebind_t<simd-complex-value-type<V>, V> norm(const V&);
1236
+ template<simd-complex V> constexpr V conj(const V&);
1237
+ template<simd-complex V> constexpr V proj(const V&);
1238
+
1239
+ template<simd-complex V> constexpr V exp(const V& v);
1240
+ template<simd-complex V> constexpr V log(const V& v);
1241
+ template<simd-complex V> constexpr V log10(const V& v);
1242
+
1243
+ template<simd-complex V> constexpr V sqrt(const V& v);
1244
+ template<simd-complex V> constexpr V sin(const V& v);
1245
+ template<simd-complex V> constexpr V asin(const V& v);
1246
+ template<simd-complex V> constexpr V cos(const V& v);
1247
+ template<simd-complex V> constexpr V acos(const V& v);
1248
+ template<simd-complex V> constexpr V tan(const V& v);
1249
+ template<simd-complex V> constexpr V atan(const V& v);
1250
+ template<simd-complex V> constexpr V sinh(const V& v);
1251
+ template<simd-complex V> constexpr V asinh(const V& v);
1252
+ template<simd-complex V> constexpr V cosh(const V& v);
1253
+ template<simd-complex V> constexpr V acosh(const V& v);
1254
+ template<simd-complex V> constexpr V tanh(const V& v);
1255
+ template<simd-complex V> constexpr V atanh(const V& v);
1256
+ ```
1257
+
1258
+ *Returns:* A `basic_vec` object `ret` where the iᵗʰ element is
1259
+ initialized to the result of *`cmplx-func`*`(v[`i`])` for all i in the
1260
+ range \[`0`, `V::size()`), where *`cmplx-func`* is the corresponding
1261
+ function from `<complex>`. If in an invocation of *`cmplx-func`* for
1262
+ index i a domain, pole, or range error would occur, the value of
1263
+ `ret[`i`]` is unspecified.
1264
+
1265
+ *Remarks:* It is unspecified whether `errno` [[errno]] is accessed.
1266
+
1267
+ ``` cpp
1268
+ template<simd-floating-point V>
1269
+ rebind_t<complex<typename V::value_type>, V> polar(const V& x, const V& y = {});
1270
+
1271
+ template<simd-complex V> constexpr V pow(const V& x, const V& y);
1272
+ ```
1273
+
1274
+ *Returns:* A `basic_vec` object `ret` where the iᵗʰ element is
1275
+ initialized to the result of *`cmplx-func`*`(x[`i`], y[`i`])` for all i
1276
+ in the range \[`0`, `V::size()`), where *`cmplx-func`* is the
1277
+ corresponding function from `<complex>`. If in an invocation of
1278
+ *`cmplx-func`* for index i a domain, pole, or range error would occur,
1279
+ the value of `ret[`i`]` is unspecified.
1280
+
1281
+ *Remarks:* It is unspecified whether `errno` [[errno]] is accessed.
1282
+