1use ::wide::{f32x4, f32x8, f64x2, f64x4, CmpEq, CmpGe, CmpGt, CmpLe, CmpLt, CmpNe};
2
3use super::*;
4
5macro_rules! impl_wide_float {
6 ($($ty: ident { array: [$scalar: ident; $n: expr], powf: $pow_self: ident, }),+) => {
7 $(
8 impl Real for $ty {
9 #[inline]
10 fn from_f64(n: f64) -> $ty {
11 $ty::splat(n as $scalar)
12 }
13
14 }
15
16 impl FromScalar for $ty {
17 type Scalar = $scalar;
18
19 #[inline]
20 fn from_scalar(scalar: $scalar) -> Self {
21 $ty::splat(scalar)
22 }
23 }
24
25 impl FromScalarArray<$n> for $ty {
26 #[inline]
27 fn from_array(scalars: [$scalar; $n]) -> Self {
28 scalars.into()
29 }
30 }
31
32 impl IntoScalarArray<$n> for $ty {
33 #[inline]
34 fn into_array(self) -> [$scalar; $n] {
35 self.into()
36 }
37 }
38
39 impl Zero for $ty {
40 #[inline]
41 fn zero() -> Self {
42 $ty::ZERO
43 }
44 }
45
46 impl One for $ty {
47 #[inline]
48 fn one() -> Self {
49 $ty::ONE
50 }
51 }
52
53 impl MinMax for $ty {
54 #[inline]
55 fn max(self, other: Self) -> Self {
56 $ty::max(self, other)
57 }
58
59 #[inline]
60 fn min(self, other: Self) -> Self {
61 $ty::min(self, other)
62 }
63
64 #[inline]
65 fn min_max(self, other: Self) -> (Self, Self) {
66 ($ty::min(self, other), $ty::max(self, other))
67 }
68 }
69
70 impl Powu for $ty {
71 #[inline]
72 fn powu(self, exp: u32) -> Self {
73 pow(self, exp)
74 }
75 }
76
77 impl IsValidDivisor for $ty {
78 #[inline]
79 fn is_valid_divisor(&self) -> Self {
80 !self.cmp_eq($ty::ZERO)
81 }
82 }
83
84 impl Trigonometry for $ty {
85 #[inline]
86 fn sin(self) -> Self {
87 $ty::sin(self)
88 }
89
90 #[inline]
91 fn cos(self) -> Self {
92 $ty::cos(self)
93 }
94
95 #[inline]
96 fn sin_cos(self) -> (Self, Self) {
97 $ty::sin_cos(self)
98 }
99
100 #[inline]
101 fn tan(self) -> Self {
102 $ty::tan(self)
103 }
104
105 #[inline]
106 fn asin(self) -> Self {
107 $ty::asin(self)
108 }
109
110 #[inline]
111 fn acos(self) -> Self {
112 $ty::acos(self)
113 }
114
115 #[inline]
116 fn atan(self) -> Self {
117 $ty::atan(self)
118 }
119
120 #[inline]
121 fn atan2(self, other: Self) -> Self {
122 $ty::atan2(self, other)
123 }
124 }
125
126 impl Abs for $ty {
127 #[inline]
128 fn abs(self) -> Self {
129 $ty::abs(self)
130 }
131 }
132
133 impl Sqrt for $ty {
134 #[inline]
135 fn sqrt(self) -> Self {
136 $ty::sqrt(self)
137 }
138 }
139
140 impl Cbrt for $ty {
141 #[inline]
142 fn cbrt(self) -> Self {
143 let mut array = self.into_array();
144
145 for scalar in &mut array {
146 *scalar = scalar.cbrt();
147 }
148
149 array.into()
150 }
151 }
152
153 impl Powf for $ty {
154 #[inline]
155 fn powf(self, exp: Self) -> Self {
156 $ty::$pow_self(self, exp)
157 }
158 }
159
160 impl Powi for $ty {
161 #[inline]
162 fn powi(mut self, mut exp: i32) -> Self {
163 if exp < 0 {
164 exp = exp.wrapping_neg();
165 self = self.recip();
166 }
167
168 Powu::powu(self, exp as u32)
169 }
170 }
171
172 impl Exp for $ty {
180 #[inline]
181 fn exp(self) -> Self {
182 $ty::exp(self)
183 }
184 }
185
186 impl Hypot for $ty {
187 #[inline]
188 fn hypot(self, other: Self) -> Self {
189 (self * self + other * other).sqrt()
190 }
191 }
192
193 impl Round for $ty {
194 #[inline]
195 fn round(self) -> Self {
196 $ty::round(self)
197 }
198
199 #[inline]
200 fn floor(self) -> Self {
201 let mut array = self.into_array();
202
203 for scalar in &mut array {
204 *scalar = scalar.floor();
205 }
206
207 array.into()
208 }
209
210 #[inline]
211 fn ceil(self) -> Self {
212 let mut array = self.into_array();
213
214 for scalar in &mut array {
215 *scalar = scalar.ceil();
216 }
217
218 array.into()
219 }
220 }
221
222 impl Clamp for $ty {
223 #[inline]
224 fn clamp(self, min: Self, max: Self) -> Self {
225 self.min(max).max(min)
226 }
227
228 #[inline]
229 fn clamp_min(self, min: Self) -> Self {
230 $ty::max(self, min)
231 }
232
233 #[inline]
234 fn clamp_max(self, max: Self) -> Self {
235 $ty::min(self, max)
236 }
237 }
238
239 impl ClampAssign for $ty {
240 #[inline]
241 fn clamp_assign(&mut self, min: Self, max: Self) {
242 *self = $ty::clamp(*self, min, max);
243 }
244
245 #[inline]
246 fn clamp_min_assign(&mut self, min: Self) {
247 *self = $ty::max(*self, min);
248 }
249
250 #[inline]
251 fn clamp_max_assign(&mut self, max: Self) {
252 *self = $ty::min(*self, max);
253 }
254 }
255
256 impl PartialCmp for $ty {
257 #[inline]
258 fn lt(&self, other: &Self) -> Self::Mask {
259 self.cmp_lt(*other)
260 }
261
262 #[inline]
263 fn lt_eq(&self, other: &Self) -> Self::Mask {
264 self.cmp_le(*other)
265 }
266
267 #[inline]
268 fn eq(&self, other: &Self) -> Self::Mask {
269 self.cmp_eq(*other)
270 }
271
272 #[inline]
273 fn neq(&self, other: &Self) -> Self::Mask {
274 self.cmp_ne(*other)
275 }
276
277 #[inline]
278 fn gt_eq(&self, other: &Self) -> Self::Mask {
279 self.cmp_ge(*other)
280 }
281
282 #[inline]
283 fn gt(&self, other: &Self) -> Self::Mask {
284 self.cmp_gt(*other)
285 }
286 }
287
288 impl MulAdd for $ty {
289 #[inline]
290 fn mul_add(self, m: Self, a: Self) -> Self {
291 $ty::mul_add(self, m, a)
292 }
293 }
294
295 impl MulSub for $ty {
296 #[inline]
297 fn mul_sub(self, m: Self, s: Self) -> Self {
298 $ty::mul_sub(self, m, s)
299 }
300 }
301
302 impl Signum for $ty {
303 #[inline]
304 fn signum(self) -> Self {
305 self.is_nan().blend(Self::from($scalar::NAN), $ty::copysign(Self::from(1.0), self))
306 }
307 }
308
309 impl Ln for $ty {
310 #[inline]
311 fn ln(self) -> Self {
312 self.ln()
313 }
314 }
315 )+
316 };
317}
318
319impl_wide_float!(
320 f32x4 {
321 array: [f32; 4],
322 powf: pow_f32x4,
323 },
324 f32x8 {
325 array: [f32; 8],
326 powf: pow_f32x8,
327 },
328 f64x2 {
329 array: [f64; 2],
330 powf: pow_f64x2,
331 },
332 f64x4 {
333 array: [f64; 4],
334 powf: pow_f64x4,
335 }
336);
337
338impl Recip for f32x4 {
339 #[inline]
340 fn recip(self) -> Self {
341 f32x4::recip(self)
342 }
343}
344
345impl Recip for f32x8 {
346 #[inline]
347 fn recip(self) -> Self {
348 f32x8::recip(self)
349 }
350}
351
352impl Recip for f64x2 {
353 #[inline]
354 fn recip(self) -> Self {
355 f64x2::ONE / self
356 }
357}
358
359impl Recip for f64x4 {
360 #[inline]
361 fn recip(self) -> Self {
362 f64x4::ONE / self
363 }
364}