1#![allow(missing_docs)]
2#![allow(non_camel_case_types)] use crate::scalar::{Field, SubsetOf, SupersetOf};
7use crate::simd::{
8 PrimitiveSimdValue, SimdBool, SimdComplexField, SimdPartialOrd, SimdRealField, SimdSigned,
9 SimdValue,
10};
11use approx::AbsDiffEq;
12#[cfg(feature = "decimal")]
13use decimal::d128;
14use num::{FromPrimitive, Num, One, Zero};
15use std::{
16 fmt,
17 ops::{
18 Add, AddAssign, BitAnd, BitOr, BitXor, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem,
19 RemAssign, Sub, SubAssign,
20 },
21};
22
23macro_rules! ident_to_value (
27 () => {
28 const _0: usize = 0; const _1: usize = 1; const _2: usize = 2; const _3: usize = 3; const _4: usize = 4; const _5: usize = 5; const _6: usize = 6; const _7: usize = 7;
29 const _8: usize = 8; const _9: usize = 9; const _10: usize = 10; const _11: usize = 11; const _12: usize = 12; const _13: usize = 13; const _14: usize = 14; const _15: usize = 15;
30 const _16: usize = 16; const _17: usize = 17; const _18: usize = 18; const _19: usize = 19; const _20: usize = 20; const _21: usize = 21; const _22: usize = 22; const _23: usize = 23;
31 const _24: usize = 24; const _25: usize = 25; const _26: usize = 26; const _27: usize = 27; const _28: usize = 28; const _29: usize = 29; const _30: usize = 30; const _31: usize = 31;
32 const _32: usize = 32; const _33: usize = 33; const _34: usize = 34; const _35: usize = 35; const _36: usize = 36; const _37: usize = 37; const _38: usize = 38; const _39: usize = 39;
33 const _40: usize = 40; const _41: usize = 41; const _42: usize = 42; const _43: usize = 43; const _44: usize = 44; const _45: usize = 45; const _46: usize = 46; const _47: usize = 47;
34 const _48: usize = 48; const _49: usize = 49; const _50: usize = 50; const _51: usize = 51; const _52: usize = 52; const _53: usize = 53; const _54: usize = 54; const _55: usize = 55;
35 const _56: usize = 56; const _57: usize = 57; const _58: usize = 58; const _59: usize = 59; const _60: usize = 60; const _61: usize = 61; const _62: usize = 62; const _63: usize = 63;
36 }
37);
38
39#[repr(align(16))]
43#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
44#[cfg_attr(
45 feature = "rkyv",
46 derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize),
47 archive(as = "Self", bound(archive = "N: rkyv::Archive<Archived = N>"))
48)]
49pub struct AutoSimd<N>(pub N);
50
51#[repr(align(16))]
55#[derive(Copy, Clone, PartialEq, Eq, Debug)]
56#[cfg_attr(
57 feature = "rkyv",
58 derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize),
59 archive(as = "Self", bound(archive = "N: rkyv::Archive<Archived = N>"))
60)]
61pub struct AutoBoolSimd<N>(pub N);
62
63macro_rules! impl_bool_simd (
64 ($($t: ty, $lanes: expr, $($i: ident),*;)*) => {$(
65 impl_simd_value!($t, bool, $lanes, AutoSimd<$t> $(, $i)*;);
66
67 impl AutoSimd<$t> {
68 pub const ZERO: Self = AutoSimd([false; $lanes]);
69 pub const ONE: Self = AutoSimd([true; $lanes]);
70
71 pub fn new($($i: bool),*) -> Self {
72 AutoSimd([$($i),*])
73 }
74 }
75
76 impl From<[bool; $lanes]> for AutoSimd<$t> {
77 #[inline(always)]
78 fn from(vals: [bool; $lanes]) -> Self {
79 Self(vals)
80 }
81 }
82
83 impl Not for AutoSimd<$t> {
84 type Output = Self;
85
86 #[inline]
87 fn not(self) -> Self {
88 self.map(|x| !x)
89 }
90 }
91
92 impl BitAnd<AutoSimd<$t>> for AutoSimd<$t> {
93 type Output = Self;
94 fn bitand(self, rhs: Self) -> Self {
95 self.zip_map(rhs, |x, y| x & y)
96 }
97 }
98
99 impl BitOr<AutoSimd<$t>> for AutoSimd<$t> {
100 type Output = Self;
101 fn bitor(self, rhs: Self) -> Self {
102 self.zip_map(rhs, |x, y| x | y)
103 }
104 }
105
106 impl BitXor<AutoSimd<$t>> for AutoSimd<$t> {
107 type Output = Self;
108 fn bitxor(self, rhs: Self) -> Self {
109 self.zip_map(rhs, |x, y| x ^ y)
110 }
111 }
112
113 impl SimdBool for AutoSimd<$t> {
114 #[inline(always)]
115 fn bitmask(self) -> u64 {
116 ident_to_value!();
117 0u64 $(
118 | ((self.0[$i] as u64) << $i)
119 )*
120 }
121
122 #[inline(always)]
123 fn and(self) -> bool {
124 ident_to_value!();
125 true $(
126 && self.0[$i]
127 )*
128 }
129
130 #[inline(always)]
131 fn or(self) -> bool {
132 ident_to_value!();
133 false $(
134 || self.0[$i]
135 )*
136 }
137
138 #[inline(always)]
139 fn xor(self) -> bool {
140 ident_to_value!();
141 false $(
142 ^ self.0[$i]
143 )*
144 }
145
146 #[inline(always)]
147 fn all(self) -> bool {
148 self.and()
149 }
150
151 #[inline(always)]
152 fn any(self) -> bool {
153 self.or()
154 }
155
156 #[inline(always)]
157 fn none(self) -> bool {
158 !self.any()
159 }
160
161 #[inline(always)]
162 fn if_else<Res: SimdValue<SimdBool = Self>>(
163 self,
164 if_value: impl FnOnce() -> Res,
165 else_value: impl FnOnce() -> Res,
166 ) -> Res {
167 let a = if_value();
168 let b = else_value();
169 a.select(self, b)
170 }
171
172 #[inline(always)]
173 fn if_else2<Res: SimdValue<SimdBool = Self>>(
174 self,
175 if_value: impl FnOnce() -> Res,
176 else_if: (impl FnOnce() -> Self, impl FnOnce() -> Res),
177 else_value: impl FnOnce() -> Res,
178 ) -> Res {
179 let a = if_value();
180 let b = else_if.1();
181 let c = else_value();
182
183 let cond_a = self;
184 let cond_b = else_if.0();
185
186 a.select(cond_a, b.select(cond_b, c))
187 }
188
189 #[inline(always)]
190 fn if_else3<Res: SimdValue<SimdBool = Self>>(
191 self,
192 if_value: impl FnOnce() -> Res,
193 else_if: (impl FnOnce() -> Self, impl FnOnce() -> Res),
194 else_else_if: (impl FnOnce() -> Self, impl FnOnce() -> Res),
195 else_value: impl FnOnce() -> Res,
196 ) -> Res {
197 let a = if_value();
198 let b = else_if.1();
199 let c = else_else_if.1();
200 let d = else_value();
201
202 let cond_a = self;
203 let cond_b = else_if.0();
204 let cond_c = else_else_if.0();
205
206 a.select(cond_a, b.select(cond_b, c.select(cond_c, d)))
207 }
208 }
209 )*}
210);
211
212macro_rules! impl_scalar_subset_of_simd (
213 ($($t: ty),*) => {$(
214 impl<N2> SubsetOf<AutoSimd<N2>> for $t
215 where AutoSimd<N2>: SimdValue + Copy,
216 <AutoSimd<N2> as SimdValue>::Element: SupersetOf<$t> + PartialEq, {
217 #[inline(always)]
218 fn to_superset(&self) -> AutoSimd<N2> {
219 AutoSimd::<N2>::splat(<AutoSimd<N2> as SimdValue>::Element::from_subset(self))
220 }
221
222 #[inline(always)]
223 fn from_superset_unchecked(element: &AutoSimd<N2>) -> $t {
224 element.extract(0).to_subset_unchecked()
225 }
226
227 #[inline(always)]
228 fn is_in_subset(c: &AutoSimd<N2>) -> bool {
229 let elt0 = c.extract(0);
230 elt0.is_in_subset() &&
231 (1..AutoSimd::<N2>::LANES).all(|i| c.extract(i) == elt0)
232 }
233 }
234 )*}
235);
236
237impl_scalar_subset_of_simd!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);
238#[cfg(feature = "decimal")]
239impl_scalar_subset_of_simd!(d128);
240
241macro_rules! impl_simd_value (
242 ($($t: ty, $elt: ty, $lanes: expr, $bool: ty, $($i: ident),*;)*) => ($(
243 impl ArrTransform for AutoSimd<$t> {
244 #[inline(always)]
245 fn map(self, f: impl Fn(Self::Element) -> Self::Element) -> Self {
246 ident_to_value!();
247 Self([$(f(self.0[$i])),*])
248 }
249
250 #[inline(always)]
251 fn zip_map(self, other: Self, f: impl Fn(Self::Element, Self::Element) -> Self::Element) -> Self {
252 ident_to_value!();
253 Self([$(f(self.0[$i], other.0[$i])),*])
254 }
255
256 #[inline(always)]
257 fn zip_zip_map(self, b: Self, c: Self, f: impl Fn(Self::Element, Self::Element, Self::Element) -> Self::Element) -> Self {
258 ident_to_value!();
259 Self([$(f(self.0[$i], b.0[$i], c.0[$i])),*])
260 }
261
262 #[inline(always)]
263 fn map_bool(self, f: impl Fn(Self::Element) -> bool) -> Self::SimdBool {
264 ident_to_value!();
265 AutoSimd([$(f(self.0[$i])),*])
266 }
267
268 #[inline(always)]
269 fn zip_map_bool(self, other: Self, f: impl Fn(Self::Element, Self::Element) -> bool) -> Self::SimdBool {
270 ident_to_value!();
271 AutoSimd([$(f(self.0[$i], other.0[$i])),*])
272 }
273 }
274
275 impl fmt::Display for AutoSimd<$t> {
276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277 if Self::LANES == 1 {
278 return self.extract(0).fmt(f);
279 }
280
281 write!(f, "({}", self.extract(0))?;
282
283 #[allow(clippy::reversed_empty_ranges)] for i in 1..Self::LANES {
285 write!(f, ", {}", self.extract(i))?;
286 }
287
288 write!(f, ")")
289 }
290 }
291
292 impl PrimitiveSimdValue for AutoSimd<$t> {}
293
294 impl SimdValue for AutoSimd<$t> {
295 const LANES: usize = $lanes;
296 type Element = $elt;
297 type SimdBool = $bool;
298
299
300 #[inline(always)]
301 fn splat(val: Self::Element) -> Self {
302 AutoSimd([val; $lanes])
303 }
304
305 #[inline(always)]
306 fn extract(&self, i: usize) -> Self::Element {
307 self.0[i]
308 }
309
310 #[inline(always)]
311 unsafe fn extract_unchecked(&self, i: usize) -> Self::Element {
312 *self.0.get_unchecked(i)
313 }
314
315 #[inline(always)]
316 fn replace(&mut self, i: usize, val: Self::Element) {
317 self.0[i] = val
318 }
319
320 #[inline(always)]
321 unsafe fn replace_unchecked(&mut self, i: usize, val: Self::Element) {
322 *self.0.get_unchecked_mut(i) = val
323 }
324
325 #[inline(always)]
326 fn select(self, cond: Self::SimdBool, other: Self) -> Self {
327 ident_to_value!();
328 Self([
329 $(if cond.0[$i] { self.0[$i] } else { other.0[$i] }),*
330 ])
331 }
332 }
333 )*)
334);
335
336macro_rules! impl_uint_simd (
337 ($($t: ty, $elt: ty, $lanes: expr, $bool: ty, $($i: ident),*;)*) => ($(
338 impl_simd_value!($t, $elt, $lanes, $bool $(, $i)*;);
339
340 impl AutoSimd<$t> {
341 pub const ZERO: Self = AutoSimd([0 as $elt; $lanes]);
342 pub const ONE: Self = AutoSimd([1 as $elt; $lanes]);
343
344 pub fn new($($i: $elt),*) -> Self {
345 AutoSimd([$($i),*])
346 }
347 }
348
349 impl From<[$elt; $lanes]> for AutoSimd<$t> {
350 #[inline(always)]
351 fn from(vals: [$elt; $lanes]) -> Self {
352 AutoSimd(vals)
353 }
354 }
355
356 impl From<AutoSimd<$t>> for [$elt; $lanes] {
357 #[inline(always)]
358 fn from(val: AutoSimd<$t>) -> [$elt; $lanes] {
359 val.0
360 }
361 }
362
363 impl SubsetOf<AutoSimd<$t>> for AutoSimd<$t> {
364 #[inline(always)]
365 fn to_superset(&self) -> Self {
366 *self
367 }
368
369 #[inline(always)]
370 fn from_superset(element: &Self) -> Option<Self> {
371 Some(*element)
372 }
373
374 #[inline(always)]
375 fn from_superset_unchecked(element: &Self) -> Self {
376 *element
377 }
378
379 #[inline(always)]
380 fn is_in_subset(_: &Self) -> bool {
381 true
382 }
383 }
384
385 impl Num for AutoSimd<$t> {
386 type FromStrRadixErr = <$elt as Num>::FromStrRadixErr;
387
388 #[inline(always)]
389 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
390 <$elt>::from_str_radix(str, radix).map(Self::splat)
391 }
392 }
393
394 impl FromPrimitive for AutoSimd<$t> {
395 #[inline(always)]
396 fn from_i64(n: i64) -> Option<Self> {
397 <$elt>::from_i64(n).map(Self::splat)
398 }
399
400 #[inline(always)]
401 fn from_u64(n: u64) -> Option<Self> {
402 <$elt>::from_u64(n).map(Self::splat)
403 }
404
405 #[inline(always)]
406 fn from_isize(n: isize) -> Option<Self> {
407 <$elt>::from_isize(n).map(Self::splat)
408 }
409
410 #[inline(always)]
411 fn from_i8(n: i8) -> Option<Self> {
412 <$elt>::from_i8(n).map(Self::splat)
413 }
414
415 #[inline(always)]
416 fn from_i16(n: i16) -> Option<Self> {
417 <$elt>::from_i16(n).map(Self::splat)
418 }
419
420 #[inline(always)]
421 fn from_i32(n: i32) -> Option<Self> {
422 <$elt>::from_i32(n).map(Self::splat)
423 }
424
425 #[inline(always)]
426 fn from_usize(n: usize) -> Option<Self> {
427 <$elt>::from_usize(n).map(Self::splat)
428 }
429
430 #[inline(always)]
431 fn from_u8(n: u8) -> Option<Self> {
432 <$elt>::from_u8(n).map(Self::splat)
433 }
434
435 #[inline(always)]
436 fn from_u16(n: u16) -> Option<Self> {
437 <$elt>::from_u16(n).map(Self::splat)
438 }
439
440 #[inline(always)]
441 fn from_u32(n: u32) -> Option<Self> {
442 <$elt>::from_u32(n).map(Self::splat)
443 }
444
445 #[inline(always)]
446 fn from_f32(n: f32) -> Option<Self> {
447 <$elt>::from_f32(n).map(Self::splat)
448 }
449
450 #[inline(always)]
451 fn from_f64(n: f64) -> Option<Self> {
452 <$elt>::from_f64(n).map(Self::splat)
453 }
454 }
455
456
457 impl Zero for AutoSimd<$t> {
458 #[inline(always)]
459 fn zero() -> Self {
460 AutoSimd([<$elt>::zero(); $lanes])
461 }
462
463 #[inline(always)]
464 fn is_zero(&self) -> bool {
465 *self == Self::zero()
466 }
467 }
468
469 impl One for AutoSimd<$t> {
470 #[inline(always)]
471 fn one() -> Self {
472 AutoSimd([<$elt>::one(); $lanes])
473 }
474 }
475
476 impl Add<AutoSimd<$t>> for AutoSimd<$t> {
477 type Output = Self;
478
479 #[inline(always)]
480 fn add(self, rhs: Self) -> Self {
481 self.zip_map(rhs, |x, y| x + y)
482 }
483 }
484
485 impl Sub<AutoSimd<$t>> for AutoSimd<$t> {
486 type Output = Self;
487
488 #[inline(always)]
489 fn sub(self, rhs: Self) -> Self {
490 self.zip_map(rhs, |x, y| x - y)
491 }
492 }
493
494 impl Mul<AutoSimd<$t>> for AutoSimd<$t> {
495 type Output = Self;
496
497 #[inline(always)]
498 fn mul(self, rhs: Self) -> Self {
499 self.zip_map(rhs, |x, y| x * y)
500 }
501 }
502
503 impl Div<AutoSimd<$t>> for AutoSimd<$t> {
504 type Output = Self;
505
506 #[inline(always)]
507 fn div(self, rhs: Self) -> Self {
508 self.zip_map(rhs, |x, y| x / y)
509 }
510 }
511
512 impl Rem<AutoSimd<$t>> for AutoSimd<$t> {
513 type Output = Self;
514
515 #[inline(always)]
516 fn rem(self, rhs: Self) -> Self {
517 self.zip_map(rhs, |x, y| x % y)
518 }
519 }
520
521 impl AddAssign<AutoSimd<$t>> for AutoSimd<$t> {
522 #[inline(always)]
523 fn add_assign(&mut self, rhs: Self) {
524 *self = *self + rhs;
525 }
526 }
527
528 impl SubAssign<AutoSimd<$t>> for AutoSimd<$t> {
529 #[inline(always)]
530 fn sub_assign(&mut self, rhs: Self) {
531 *self = *self - rhs;
532 }
533 }
534
535 impl DivAssign<AutoSimd<$t>> for AutoSimd<$t> {
536 #[inline(always)]
537 fn div_assign(&mut self, rhs: Self) {
538 *self = *self / rhs;
539 }
540 }
541
542 impl MulAssign<AutoSimd<$t>> for AutoSimd<$t> {
543 #[inline(always)]
544 fn mul_assign(&mut self, rhs: Self) {
545 *self = *self * rhs;
546 }
547 }
548
549 impl RemAssign<AutoSimd<$t>> for AutoSimd<$t> {
550 #[inline(always)]
551 fn rem_assign(&mut self, rhs: Self) {
552 *self = *self % rhs;
553 }
554 }
555
556 impl SimdPartialOrd for AutoSimd<$t> {
557 #[inline(always)]
558 fn simd_gt(self, other: Self) -> Self::SimdBool {
559 self.zip_map_bool(other, |x, y| x.simd_gt(y))
560 }
561
562 #[inline(always)]
563 fn simd_lt(self, other: Self) -> Self::SimdBool {
564 self.zip_map_bool(other, |x, y| x.simd_lt(y))
565 }
566
567 #[inline(always)]
568 fn simd_ge(self, other: Self) -> Self::SimdBool {
569 self.zip_map_bool(other, |x, y| x.simd_ge(y))
570 }
571
572 #[inline(always)]
573 fn simd_le(self, other: Self) -> Self::SimdBool {
574 self.zip_map_bool(other, |x, y| x.simd_le(y))
575 }
576
577 #[inline(always)]
578 fn simd_eq(self, other: Self) -> Self::SimdBool {
579 self.zip_map_bool(other, |x, y| x.simd_eq(y))
580 }
581
582 #[inline(always)]
583 fn simd_ne(self, other: Self) -> Self::SimdBool {
584 self.zip_map_bool(other, |x, y| x.simd_ne(y))
585 }
586
587 #[inline(always)]
588 fn simd_max(self, other: Self) -> Self {
589 self.zip_map(other, |x, y| x.simd_max(y))
590 }
591 #[inline(always)]
592 fn simd_min(self, other: Self) -> Self {
593 self.zip_map(other, |x, y| x.simd_min(y))
594 }
595
596 #[inline(always)]
597 fn simd_clamp(self, min: Self, max: Self) -> Self {
598 self.simd_max(min).simd_min(max)
599 }
600
601 #[inline(always)]
602 fn simd_horizontal_min(self) -> Self::Element {
603 ident_to_value!();
604 self.0[0] $(.simd_min(self.0[$i]))*
605 }
606
607 #[inline(always)]
608 fn simd_horizontal_max(self) -> Self::Element {
609 ident_to_value!();
610 self.0[0] $(.simd_max(self.0[$i]))*
611 }
612 }
613
614)*)
628);
629
630macro_rules! impl_int_simd (
631 ($($t: ty, $elt: ty, $lanes: expr, $bool: ty, $($i: ident),*;)*) => ($(
632 impl_uint_simd!($t, $elt, $lanes, $bool $(, $i)*;);
633
634 impl Neg for AutoSimd<$t> {
635 type Output = Self;
636
637 #[inline(always)]
638 fn neg(self) -> Self {
639 self.map(|x| -x)
640 }
641 }
642 )*)
643);
644
645macro_rules! impl_float_simd (
646 ($($t: ty, $elt: ty, $lanes: expr, $int: ty, $bool: ty, $($i: ident),*;)*) => ($(
647 impl_int_simd!($t, $elt, $lanes, $bool $(, $i)*;);
648
649 impl SimdSigned for AutoSimd<$t> {
651 #[inline(always)]
652 fn simd_abs(&self) -> Self {
653 self.map(|x| x.simd_abs())
654 }
655
656 #[inline(always)]
657 fn simd_abs_sub(&self, other: &Self) -> Self {
658 self.zip_map(*other, |x, y| x.simd_abs_sub(&y))
659 }
660
661 #[inline(always)]
662 fn simd_signum(&self) -> Self {
663 self.map(|x| x.simd_signum())
664 }
665
666 #[inline(always)]
667 fn is_simd_positive(&self) -> Self::SimdBool {
668 self.map_bool(|x| x.is_simd_positive())
669 }
670
671 #[inline(always)]
672 fn is_simd_negative(&self) -> Self::SimdBool {
673 self.map_bool(|x| x.is_simd_negative())
674 }
675 }
676
677 impl Field for AutoSimd<$t> {}
678
679 #[cfg(any(feature = "std", feature = "libm", feature = "libm_force"))]
680 impl SimdRealField for AutoSimd<$t> {
681 #[inline(always)]
682 fn simd_atan2(self, other: Self) -> Self {
683 self.zip_map(other, |x, y| x.simd_atan2(y))
684 }
685
686 #[inline(always)]
687 fn simd_copysign(self, sign: Self) -> Self {
688 self.zip_map(sign, |me, sgn| me.simd_copysign(sgn))
689 }
690
691 #[inline(always)]
692 fn simd_default_epsilon() -> Self {
693 Self::splat(<$elt>::default_epsilon())
694 }
695
696 #[inline(always)]
697 fn simd_pi() -> Self {
698 Self::splat(<$elt>::simd_pi())
699 }
700
701 #[inline(always)]
702 fn simd_two_pi() -> Self {
703 Self::splat(<$elt>::simd_two_pi())
704 }
705
706 #[inline(always)]
707 fn simd_frac_pi_2() -> Self {
708 Self::splat(<$elt>::simd_frac_pi_2())
709 }
710
711 #[inline(always)]
712 fn simd_frac_pi_3() -> Self {
713 Self::splat(<$elt>::simd_frac_pi_3())
714 }
715
716 #[inline(always)]
717 fn simd_frac_pi_4() -> Self {
718 Self::splat(<$elt>::simd_frac_pi_4())
719 }
720
721 #[inline(always)]
722 fn simd_frac_pi_6() -> Self {
723 Self::splat(<$elt>::simd_frac_pi_6())
724 }
725
726 #[inline(always)]
727 fn simd_frac_pi_8() -> Self {
728 Self::splat(<$elt>::simd_frac_pi_8())
729 }
730
731 #[inline(always)]
732 fn simd_frac_1_pi() -> Self {
733 Self::splat(<$elt>::simd_frac_1_pi())
734 }
735
736 #[inline(always)]
737 fn simd_frac_2_pi() -> Self {
738 Self::splat(<$elt>::simd_frac_2_pi())
739 }
740
741 #[inline(always)]
742 fn simd_frac_2_sqrt_pi() -> Self {
743 Self::splat(<$elt>::simd_frac_2_sqrt_pi())
744 }
745
746
747 #[inline(always)]
748 fn simd_e() -> Self {
749 Self::splat(<$elt>::simd_e())
750 }
751
752 #[inline(always)]
753 fn simd_log2_e() -> Self {
754 Self::splat(<$elt>::simd_log2_e())
755 }
756
757 #[inline(always)]
758 fn simd_log10_e() -> Self {
759 Self::splat(<$elt>::simd_log10_e() )
760 }
761
762 #[inline(always)]
763 fn simd_ln_2() -> Self {
764 Self::splat(<$elt>::simd_ln_2())
765 }
766
767 #[inline(always)]
768 fn simd_ln_10() -> Self {
769 Self::splat(<$elt>::simd_ln_10())
770 }
771 }
772
773 #[cfg(any(feature = "std", feature = "libm", feature = "libm_force"))]
774 impl SimdComplexField for AutoSimd<$t> {
775 type SimdRealField = Self;
776
777 #[inline(always)]
778 fn simd_horizontal_sum(self) -> Self::Element {
779 self.0.iter().sum()
780 }
781
782 #[inline(always)]
783 fn simd_horizontal_product(self) -> Self::Element {
784 self.0.iter().product()
785 }
786
787 #[inline(always)]
788 fn from_simd_real(re: Self::SimdRealField) -> Self {
789 re
790 }
791
792 #[inline(always)]
793 fn simd_real(self) -> Self::SimdRealField {
794 self
795 }
796
797 #[inline(always)]
798 fn simd_imaginary(self) -> Self::SimdRealField {
799 Self::zero()
800 }
801
802 #[inline(always)]
803 fn simd_norm1(self) -> Self::SimdRealField {
804 self.map(|x| x.simd_norm1())
805 }
806
807 #[inline(always)]
808 fn simd_modulus(self) -> Self::SimdRealField {
809 self.map(|x| x.simd_modulus())
810 }
811
812 #[inline(always)]
813 fn simd_modulus_squared(self) -> Self::SimdRealField {
814 self.map(|x| x.simd_modulus_squared())
815 }
816
817 #[inline(always)]
818 fn simd_argument(self) -> Self::SimdRealField {
819 self.map(|x| x.simd_argument())
820 }
821
822 #[inline(always)]
823 fn simd_to_exp(self) -> (Self::SimdRealField, Self) {
824 let ge = self.simd_ge(Self::one());
825 let exp = Self::one().select(ge, -Self::one());
826 (self * exp, exp)
827 }
828
829 #[inline(always)]
830 fn simd_recip(self) -> Self {
831 self.map(|x| x.simd_recip())
832 }
833
834 #[inline(always)]
835 fn simd_conjugate(self) -> Self {
836 self.map(|x| x.simd_conjugate())
837 }
838
839 #[inline(always)]
840 fn simd_scale(self, factor: Self::SimdRealField) -> Self {
841 self.zip_map(factor, |x, y| x.simd_scale(y))
842 }
843
844 #[inline(always)]
845 fn simd_unscale(self, factor: Self::SimdRealField) -> Self {
846 self.zip_map(factor, |x, y| x.simd_unscale(y))
847 }
848
849 #[inline(always)]
850 fn simd_floor(self) -> Self {
851 self.map(|e| e.simd_floor())
852 }
853
854 #[inline(always)]
855 fn simd_ceil(self) -> Self {
856 self.map(|e| e.simd_ceil())
857 }
858
859 #[inline(always)]
860 fn simd_round(self) -> Self {
861 self.map(|e| e.simd_round())
862 }
863
864 #[inline(always)]
865 fn simd_trunc(self) -> Self {
866 self.map(|e| e.simd_trunc())
867 }
868
869 #[inline(always)]
870 fn simd_fract(self) -> Self {
871 self.map(|e| e.simd_fract())
872 }
873
874 #[inline(always)]
875 fn simd_abs(self) -> Self {
876 self.map(|e| e.simd_abs())
877 }
878
879 #[inline(always)]
880 fn simd_signum(self) -> Self {
881 self.map(|e| e.simd_signum())
882 }
883
884 #[inline(always)]
885 fn simd_mul_add(self, a: Self, b: Self) -> Self {
886 self.zip_zip_map(a, b, |x, y, z| x.simd_mul_add(y, z))
887 }
888
889 #[inline(always)]
890 fn simd_powi(self, n: i32) -> Self {
891 self.map(|e| e.simd_powi(n))
892 }
893
894 #[inline(always)]
895 fn simd_powf(self, n: Self) -> Self {
896 self.zip_map(n, |x, y| x.simd_powf(y))
897 }
898
899 #[inline(always)]
900 fn simd_powc(self, n: Self) -> Self {
901 self.zip_map(n, |x, y| x.simd_powc(y))
902 }
903
904 #[inline(always)]
905 fn simd_sqrt(self) -> Self {
906 self.map(|x| x.simd_sqrt())
907 }
908
909 #[inline(always)]
910 fn simd_exp(self) -> Self {
911 self.map(|x| x.simd_exp())
912 }
913
914 #[inline(always)]
915 fn simd_exp2(self) -> Self {
916 self.map(|x| x.simd_exp2())
917 }
918
919
920 #[inline(always)]
921 fn simd_exp_m1(self) -> Self {
922 self.map(|x| x.simd_exp_m1())
923 }
924
925 #[inline(always)]
926 fn simd_ln_1p(self) -> Self {
927 self.map(|x| x.simd_ln_1p())
928 }
929
930 #[inline(always)]
931 fn simd_ln(self) -> Self {
932 self.map(|x| x.simd_ln())
933 }
934
935 #[inline(always)]
936 fn simd_log(self, base: Self) -> Self {
937 self.zip_map(base, |x, y| x.simd_log(y))
938 }
939
940 #[inline(always)]
941 fn simd_log2(self) -> Self {
942 self.map(|x| x.simd_log2())
943 }
944
945 #[inline(always)]
946 fn simd_log10(self) -> Self {
947 self.map(|x| x.simd_log10())
948 }
949
950 #[inline(always)]
951 fn simd_cbrt(self) -> Self {
952 self.map(|x| x.simd_cbrt())
953 }
954
955 #[inline(always)]
956 fn simd_hypot(self, other: Self) -> Self::SimdRealField {
957 self.zip_map(other, |x, y| x.simd_hypot(y))
958 }
959
960 #[inline(always)]
961 fn simd_sin(self) -> Self {
962 self.map(|x| x.simd_sin())
963 }
964
965 #[inline(always)]
966 fn simd_cos(self) -> Self {
967 self.map(|x| x.simd_cos())
968 }
969
970 #[inline(always)]
971 fn simd_tan(self) -> Self {
972 self.map(|x| x.simd_tan())
973 }
974
975 #[inline(always)]
976 fn simd_asin(self) -> Self {
977 self.map(|x| x.simd_asin())
978 }
979
980 #[inline(always)]
981 fn simd_acos(self) -> Self {
982 self.map(|x| x.simd_acos())
983 }
984
985 #[inline(always)]
986 fn simd_atan(self) -> Self {
987 self.map(|x| x.simd_atan())
988 }
989
990 #[inline(always)]
991 fn simd_sin_cos(self) -> (Self, Self) {
992 (self.simd_sin(), self.simd_cos())
993 }
994
995#[inline(always)]
1006 fn simd_sinh(self) -> Self {
1007 self.map(|x| x.simd_sinh())
1008 }
1009
1010 #[inline(always)]
1011 fn simd_cosh(self) -> Self {
1012 self.map(|x| x.simd_cosh())
1013 }
1014
1015 #[inline(always)]
1016 fn simd_tanh(self) -> Self {
1017 self.map(|x| x.simd_tanh())
1018 }
1019
1020 #[inline(always)]
1021 fn simd_asinh(self) -> Self {
1022 self.map(|x| x.simd_asinh())
1023 }
1024
1025 #[inline(always)]
1026 fn simd_acosh(self) -> Self {
1027 self.map(|x| x.simd_acosh())
1028 }
1029
1030 #[inline(always)]
1031 fn simd_atanh(self) -> Self {
1032 self.map(|x| x.simd_atanh())
1033 }
1034 }
1035
1036 #[cfg(any(feature = "std", feature = "libm", feature = "libm_force"))]
1040 impl SimdComplexField for num_complex::Complex<AutoSimd<$t>> {
1041 type SimdRealField = AutoSimd<$t>;
1042
1043 #[inline(always)]
1044 fn simd_horizontal_sum(self) -> Self::Element {
1045 num_complex::Complex::new(self.re.simd_horizontal_sum(), self.im.simd_horizontal_sum())
1046 }
1047
1048 #[inline(always)]
1049 fn simd_horizontal_product(self) -> Self::Element {
1050 let mut prod = self.extract(0);
1051 for ii in 1..$lanes {
1052 prod *= self.extract(ii)
1053 }
1054 prod
1055 }
1056
1057 #[inline]
1058 fn from_simd_real(re: Self::SimdRealField) -> Self {
1059 Self::new(re, Self::SimdRealField::zero())
1060 }
1061
1062 #[inline]
1063 fn simd_real(self) -> Self::SimdRealField {
1064 self.re
1065 }
1066
1067 #[inline]
1068 fn simd_imaginary(self) -> Self::SimdRealField {
1069 self.im
1070 }
1071
1072 #[inline]
1073 fn simd_argument(self) -> Self::SimdRealField {
1074 self.im.simd_atan2(self.re)
1075 }
1076
1077 #[inline]
1078 fn simd_modulus(self) -> Self::SimdRealField {
1079 self.re.simd_hypot(self.im)
1080 }
1081
1082 #[inline]
1083 fn simd_modulus_squared(self) -> Self::SimdRealField {
1084 self.re * self.re + self.im * self.im
1085 }
1086
1087 #[inline]
1088 fn simd_norm1(self) -> Self::SimdRealField {
1089 self.re.simd_abs() + self.im.simd_abs()
1090 }
1091
1092 #[inline]
1093 fn simd_recip(self) -> Self {
1094 Self::one() / self
1095 }
1096
1097 #[inline]
1098 fn simd_conjugate(self) -> Self {
1099 self.conj()
1100 }
1101
1102 #[inline]
1103 fn simd_scale(self, factor: Self::SimdRealField) -> Self {
1104 self * factor
1105 }
1106
1107 #[inline]
1108 fn simd_unscale(self, factor: Self::SimdRealField) -> Self {
1109 self / factor
1110 }
1111
1112 #[inline]
1113 fn simd_floor(self) -> Self {
1114 Self::new(self.re.simd_floor(), self.im.simd_floor())
1115 }
1116
1117 #[inline]
1118 fn simd_ceil(self) -> Self {
1119 Self::new(self.re.simd_ceil(), self.im.simd_ceil())
1120 }
1121
1122 #[inline]
1123 fn simd_round(self) -> Self {
1124 Self::new(self.re.simd_round(), self.im.simd_round())
1125 }
1126
1127 #[inline]
1128 fn simd_trunc(self) -> Self {
1129 Self::new(self.re.simd_trunc(), self.im.simd_trunc())
1130 }
1131
1132 #[inline]
1133 fn simd_fract(self) -> Self {
1134 Self::new(self.re.simd_fract(), self.im.simd_fract())
1135 }
1136
1137 #[inline]
1138 fn simd_mul_add(self, a: Self, b: Self) -> Self {
1139 self * a + b
1140 }
1141
1142 #[inline]
1143 fn simd_abs(self) -> Self::SimdRealField {
1144 self.simd_modulus()
1145 }
1146
1147 #[inline]
1148 fn simd_exp2(self) -> Self {
1149 let _2 = AutoSimd::<$t>::one() + AutoSimd::<$t>::one();
1150 num_complex::Complex::new(_2, AutoSimd::<$t>::zero()).simd_powc(self)
1151 }
1152
1153 #[inline]
1154 fn simd_exp_m1(self) -> Self {
1155 self.simd_exp() - Self::one()
1156 }
1157
1158 #[inline]
1159 fn simd_ln_1p(self) -> Self {
1160 (Self::one() + self).simd_ln()
1161 }
1162
1163 #[inline]
1164 fn simd_log2(self) -> Self {
1165 let _2 = AutoSimd::<$t>::one() + AutoSimd::<$t>::one();
1166 self.simd_log(_2)
1167 }
1168
1169 #[inline]
1170 fn simd_log10(self) -> Self {
1171 let _10 = AutoSimd::<$t>::from_subset(&10.0f64);
1172 self.simd_log(_10)
1173 }
1174
1175 #[inline]
1176 fn simd_cbrt(self) -> Self {
1177 let one_third = AutoSimd::<$t>::from_subset(&(1.0 / 3.0));
1178 self.simd_powf(one_third)
1179 }
1180
1181 #[inline]
1182 fn simd_powi(self, n: i32) -> Self {
1183 let n = AutoSimd::<$t>::from_subset(&(n as f64));
1185 self.simd_powf(n)
1186 }
1187
1188 #[inline]
1199 fn simd_exp(self) -> Self {
1200 simd_complex_from_polar(self.re.simd_exp(), self.im)
1203 }
1204
1205 #[inline]
1213 fn simd_ln(self) -> Self {
1214 let (r, theta) = self.simd_to_polar();
1216 Self::new(r.simd_ln(), theta)
1217 }
1218
1219 #[inline]
1227 fn simd_sqrt(self) -> Self {
1228 let two = AutoSimd::<$t>::one() + AutoSimd::<$t>::one();
1230 let (r, theta) = self.simd_to_polar();
1231 simd_complex_from_polar(r.simd_sqrt(), theta / two)
1232 }
1233
1234 #[inline]
1235 fn simd_hypot(self, b: Self) -> Self::SimdRealField {
1236 (self.simd_modulus_squared() + b.simd_modulus_squared()).simd_sqrt()
1237 }
1238
1239 #[inline]
1241 fn simd_powf(self, exp: Self::SimdRealField) -> Self {
1242 let (r, theta) = self.simd_to_polar();
1245 simd_complex_from_polar(r.simd_powf(exp), theta * exp)
1246 }
1247
1248 #[inline]
1250 fn simd_log(self, base: AutoSimd<$t>) -> Self {
1251 let (r, theta) = self.simd_to_polar();
1255 Self::new(r.simd_log(base), theta / base.simd_ln())
1256 }
1257
1258 #[inline]
1260 fn simd_powc(self, exp: Self) -> Self {
1261 let (r, theta) = self.simd_to_polar();
1273 simd_complex_from_polar(
1274 r.simd_powf(exp.re) * (-exp.im * theta).simd_exp(),
1275 exp.re * theta + exp.im * r.simd_ln(),
1276 )
1277 }
1278
1279 #[inline]
1291 fn simd_sin(self) -> Self {
1292 Self::new(
1294 self.re.simd_sin() * self.im.simd_cosh(),
1295 self.re.simd_cos() * self.im.simd_sinh(),
1296 )
1297 }
1298
1299 #[inline]
1301 fn simd_cos(self) -> Self {
1302 Self::new(
1304 self.re.simd_cos() * self.im.simd_cosh(),
1305 -self.re.simd_sin() * self.im.simd_sinh(),
1306 )
1307 }
1308
1309 #[inline]
1310 fn simd_sin_cos(self) -> (Self, Self) {
1311 let (rsin, rcos) = self.re.simd_sin_cos();
1312 let (isinh, icosh) = self.im.simd_sinh_cosh();
1313 let sin = Self::new(rsin * icosh, rcos * isinh);
1314 let cos = Self::new(rcos * icosh, -rsin * isinh);
1315
1316 (sin, cos)
1317 }
1318
1319 #[inline]
1321 fn simd_tan(self) -> Self {
1322 let (two_re, two_im) = (self.re + self.re, self.im + self.im);
1324 Self::new(two_re.simd_sin(), two_im.simd_sinh()).unscale(two_re.simd_cos() + two_im.simd_cosh())
1325 }
1326
1327 #[inline]
1336 fn simd_asin(self) -> Self {
1337 let i = Self::i();
1339 -i * ((Self::one() - self * self).simd_sqrt() + i * self).simd_ln()
1340 }
1341
1342 #[inline]
1351 fn simd_acos(self) -> Self {
1352 let i = Self::i();
1354 -i * (i * (Self::one() - self * self).simd_sqrt() + self).simd_ln()
1355 }
1356
1357 #[inline]
1366 fn simd_atan(self) -> Self {
1367 let i = Self::i();
1369 let one = Self::one();
1370 let two = one + one;
1371
1372 if self == i {
1373 return Self::new(AutoSimd::<$t>::zero(), AutoSimd::<$t>::one() / AutoSimd::<$t>::zero());
1374 } else if self == -i {
1375 return Self::new(AutoSimd::<$t>::zero(), -AutoSimd::<$t>::one() / AutoSimd::<$t>::zero());
1376 }
1377
1378 ((one + i * self).simd_ln() - (one - i * self).simd_ln()) / (two * i)
1379 }
1380
1381 #[inline]
1383 fn simd_sinh(self) -> Self {
1384 Self::new(
1386 self.re.simd_sinh() * self.im.simd_cos(),
1387 self.re.simd_cosh() * self.im.simd_sin(),
1388 )
1389 }
1390
1391 #[inline]
1393 fn simd_cosh(self) -> Self {
1394 Self::new(
1396 self.re.simd_cosh() * self.im.simd_cos(),
1397 self.re.simd_sinh() * self.im.simd_sin(),
1398 )
1399 }
1400
1401 #[inline]
1402 fn simd_sinh_cosh(self) -> (Self, Self) {
1403 let (rsinh, rcosh) = self.re.simd_sinh_cosh();
1404 let (isin, icos) = self.im.simd_sin_cos();
1405 let sin = Self::new(rsinh * icos, rcosh * isin);
1406 let cos = Self::new(rcosh * icos, rsinh * isin);
1407
1408 (sin, cos)
1409 }
1410
1411 #[inline]
1413 fn simd_tanh(self) -> Self {
1414 let (two_re, two_im) = (self.re + self.re, self.im + self.im);
1416 Self::new(two_re.simd_sinh(), two_im.simd_sin()).unscale(two_re.simd_cosh() + two_im.simd_cos())
1417 }
1418
1419 #[inline]
1428 fn simd_asinh(self) -> Self {
1429 let one = Self::one();
1431 (self + (one + self * self).simd_sqrt()).simd_ln()
1432 }
1433
1434 #[inline]
1442 fn simd_acosh(self) -> Self {
1443 let one = Self::one();
1445 let two = one + one;
1446 two * (((self + one) / two).simd_sqrt() + ((self - one) / two).simd_sqrt()).simd_ln()
1447 }
1448
1449 #[inline]
1458 fn simd_atanh(self) -> Self {
1459 let one = Self::one();
1461 let two = one + one;
1462 if self == one {
1463 return Self::new(AutoSimd::<$t>::one() / AutoSimd::<$t>::zero(), AutoSimd::<$t>::zero());
1464 } else if self == -one {
1465 return Self::new(-AutoSimd::<$t>::one() / AutoSimd::<$t>::zero(), AutoSimd::<$t>::zero());
1466 }
1467 ((one + self).simd_ln() - (one - self).simd_ln()) / two
1468 }
1469 }
1470 )*)
1471);
1472
1473#[inline]
1474fn simd_complex_from_polar<N: SimdRealField>(r: N, theta: N) -> num_complex::Complex<N> {
1475 num_complex::Complex::new(r.clone() * theta.clone().simd_cos(), r * theta.simd_sin())
1476}
1477
1478impl_float_simd!(
1479 [f32; 2], f32, 2, [i32; 2], AutoBoolx2, _0, _1;
1480 [f32; 4], f32, 4, [i32; 4], AutoBoolx4, _0, _1, _2, _3;
1481 [f32; 8], f32, 8, [i32; 8], AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1482 [f32; 16], f32, 16, [i32; 16], AutoBoolx16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1483 [f64; 2], f64, 2, [i64; 2], AutoBoolx2, _0, _1;
1484 [f64; 4], f64, 4, [i64; 4], AutoBoolx4, _0, _1, _2, _3;
1485 [f64; 8], f64, 8, [i64; 8], AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1486);
1487
1488impl_int_simd!(
1489 [i128; 1], i128, 1, AutoBoolx1, _0;
1490 [i128; 2], i128, 2, AutoBoolx2, _0, _1;
1491 [i128; 4], i128, 4, AutoBoolx4, _0, _1, _2, _3;
1492 [i16; 2], i16, 2, AutoBoolx2, _0, _1;
1493 [i16; 4], i16, 4, AutoBoolx4, _0, _1, _2, _3;
1494 [i16; 8], i16, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1495 [i16; 16], i16, 16, AutoBoolx16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1496 [i16; 32], i16, 32, AutoBoolx32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1497 [i32; 2], i32, 2, AutoBoolx2, _0, _1;
1498 [i32; 4], i32, 4, AutoBoolx4, _0, _1, _2, _3;
1499 [i32; 8], i32, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1500 [i32; 16], i32, 16, AutoBoolx16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1501 [i64; 2], i64, 2, AutoBoolx2, _0, _1;
1502 [i64; 4], i64, 4, AutoBoolx4, _0, _1, _2, _3;
1503 [i64; 8], i64, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1504 [i8; 2], i8, 2, AutoBoolx2, _0, _1;
1505 [i8; 4], i8, 4, AutoBoolx4, _0, _1, _2, _3;
1506 [i8; 8], i8, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1507 [i8; 16], i8, 16, AutoBoolx16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1508 [i8; 32], i8, 32, AutoBoolx32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1509 [isize; 2], isize, 2, AutoBoolx2, _0, _1;
1511 [isize; 4], isize, 4, AutoBoolx4, _0, _1, _2, _3;
1512 [isize; 8], isize, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1513);
1514
1515impl_uint_simd!(
1516 [u128; 1], u128, 1, AutoBoolx1, _0;
1517 [u128; 2], u128, 2, AutoBoolx2, _0, _1;
1518 [u128; 4], u128, 4, AutoBoolx4, _0, _1, _2, _3;
1519 [u16; 2], u16, 2, AutoBoolx2, _0, _1;
1520 [u16; 4], u16, 4, AutoBoolx4, _0, _1, _2, _3;
1521 [u16; 8], u16, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1522 [u16; 16], u16, 16, AutoBoolx16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1523 [u16; 32], u16, 32, AutoBoolx32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1524 [u32; 2], u32, 2, AutoBoolx2, _0, _1;
1525 [u32; 4], u32, 4, AutoBoolx4, _0, _1, _2, _3;
1526 [u32; 8], u32, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1527 [u32; 16], u32, 16, AutoBoolx16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1528 [u64; 2], u64, 2, AutoBoolx2, _0, _1;
1529 [u64; 4], u64, 4, AutoBoolx4, _0, _1, _2, _3;
1530 [u64; 8], u64, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1531 [u8; 2], u8, 2, AutoBoolx2, _0, _1;
1532 [u8; 4], u8, 4, AutoBoolx4, _0, _1, _2, _3;
1533 [u8; 8], u8, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1534 [u8; 16], u8, 16, AutoBoolx16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1535 [u8; 32], u8, 32, AutoBoolx32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1536 [usize; 2], usize, 2, AutoBoolx2, _0, _1;
1538 [usize; 4], usize, 4, AutoBoolx4, _0, _1, _2, _3;
1539 [usize; 8], usize, 8, AutoBoolx8, _0, _1, _2, _3, _4, _5, _6, _7;
1540);
1541
1542impl_bool_simd!(
1543 [bool; 1], 1, _0;
1544 [bool; 2], 2, _0, _1;
1545 [bool; 4], 4, _0, _1, _2, _3;
1546 [bool; 8], 8, _0, _1, _2, _3, _4, _5, _6, _7;
1547 [bool; 16], 16, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
1548 [bool; 32], 32, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31;
1549 );
1551
1552pub type AutoF32x2 = AutoSimd<[f32; 2]>;
1581pub type AutoF32x4 = AutoSimd<[f32; 4]>;
1582pub type AutoF32x8 = AutoSimd<[f32; 8]>;
1583pub type AutoF32x16 = AutoSimd<[f32; 16]>;
1584pub type AutoF64x2 = AutoSimd<[f64; 2]>;
1585pub type AutoF64x4 = AutoSimd<[f64; 4]>;
1586pub type AutoF64x8 = AutoSimd<[f64; 8]>;
1587pub type AutoI128x1 = AutoSimd<[i128; 1]>;
1588pub type AutoI128x2 = AutoSimd<[i128; 2]>;
1589pub type AutoI128x4 = AutoSimd<[i128; 4]>;
1590pub type AutoI16x2 = AutoSimd<[i16; 2]>;
1591pub type AutoI16x4 = AutoSimd<[i16; 4]>;
1592pub type AutoI16x8 = AutoSimd<[i16; 8]>;
1593pub type AutoI16x16 = AutoSimd<[i16; 16]>;
1594pub type AutoI16x32 = AutoSimd<[i16; 32]>;
1595pub type AutoI32x2 = AutoSimd<[i32; 2]>;
1596pub type AutoI32x4 = AutoSimd<[i32; 4]>;
1597pub type AutoI32x8 = AutoSimd<[i32; 8]>;
1598pub type AutoI32x16 = AutoSimd<[i32; 16]>;
1599pub type AutoI64x2 = AutoSimd<[i64; 2]>;
1600pub type AutoI64x4 = AutoSimd<[i64; 4]>;
1601pub type AutoI64x8 = AutoSimd<[i64; 8]>;
1602pub type AutoI8x2 = AutoSimd<[i8; 2]>;
1603pub type AutoI8x4 = AutoSimd<[i8; 4]>;
1604pub type AutoI8x8 = AutoSimd<[i8; 8]>;
1605pub type AutoI8x16 = AutoSimd<[i8; 16]>;
1606pub type AutoI8x32 = AutoSimd<[i8; 32]>;
1607pub type AutoIsizex2 = AutoSimd<[isize; 2]>;
1609pub type AutoIsizex4 = AutoSimd<[isize; 4]>;
1610pub type AutoIsizex8 = AutoSimd<[isize; 8]>;
1611pub type AutoU128x1 = AutoSimd<[u128; 1]>;
1612pub type AutoU128x2 = AutoSimd<[u128; 2]>;
1613pub type AutoU128x4 = AutoSimd<[u128; 4]>;
1614pub type AutoU16x2 = AutoSimd<[u16; 2]>;
1615pub type AutoU16x4 = AutoSimd<[u16; 4]>;
1616pub type AutoU16x8 = AutoSimd<[u16; 8]>;
1617pub type AutoU16x16 = AutoSimd<[u16; 16]>;
1618pub type AutoU16x32 = AutoSimd<[u16; 32]>;
1619pub type AutoU32x2 = AutoSimd<[u32; 2]>;
1620pub type AutoU32x4 = AutoSimd<[u32; 4]>;
1621pub type AutoU32x8 = AutoSimd<[u32; 8]>;
1622pub type AutoU32x16 = AutoSimd<[u32; 16]>;
1623pub type AutoU64x2 = AutoSimd<[u64; 2]>;
1624pub type AutoU64x4 = AutoSimd<[u64; 4]>;
1625pub type AutoU64x8 = AutoSimd<[u64; 8]>;
1626pub type AutoU8x2 = AutoSimd<[u8; 2]>;
1627pub type AutoU8x4 = AutoSimd<[u8; 4]>;
1628pub type AutoU8x8 = AutoSimd<[u8; 8]>;
1629pub type AutoU8x16 = AutoSimd<[u8; 16]>;
1630pub type AutoU8x32 = AutoSimd<[u8; 32]>;
1631pub type AutoUsizex2 = AutoSimd<[usize; 2]>;
1633pub type AutoUsizex4 = AutoSimd<[usize; 4]>;
1634pub type AutoUsizex8 = AutoSimd<[usize; 8]>;
1635
1636pub type AutoBoolx1 = AutoSimd<[bool; 1]>;
1637pub type AutoBoolx16 = AutoSimd<[bool; 16]>;
1638pub type AutoBoolx2 = AutoSimd<[bool; 2]>;
1639pub type AutoBoolx32 = AutoSimd<[bool; 32]>;
1640pub type AutoBoolx4 = AutoSimd<[bool; 4]>;
1641pub type AutoBoolx8 = AutoSimd<[bool; 8]>;
1643
1644trait ArrTransform: SimdValue {
1648 fn map(self, f: impl Fn(Self::Element) -> Self::Element) -> Self;
1649 fn zip_map(
1650 self,
1651 other: Self,
1652 f: impl Fn(Self::Element, Self::Element) -> Self::Element,
1653 ) -> Self;
1654 fn zip_zip_map(
1655 self,
1656 b: Self,
1657 c: Self,
1658 f: impl Fn(Self::Element, Self::Element, Self::Element) -> Self::Element,
1659 ) -> Self;
1660 fn map_bool(self, f: impl Fn(Self::Element) -> bool) -> Self::SimdBool;
1661 fn zip_map_bool(
1662 self,
1663 other: Self,
1664 f: impl Fn(Self::Element, Self::Element) -> bool,
1665 ) -> Self::SimdBool;
1666}