1use core::ops::*;
7#[cfg(any(feature = "use_libm_fma", target_arch = "aarch64", target_feature = "fma"))]
8use num_traits::MulAdd;
9use num_traits::{Float, Num, NumAssignOps};
10
11use crate::{Aligned4, Aligned8, Aligned16, Aligned32, Aligned64, Simd};
12
13impl<const N: usize> Simd<bool, N> {
14 #[inline(always)]
17 pub fn select<T: Copy>(self, if_true: Simd<T, N>, if_false: Simd<T, N>) -> Simd<T, N> {
18 let mut out = if_true.0;
19 for ((o, f), m) in out.iter_mut().zip(if_false.0).zip(self.0) {
20 if !m {
21 *o = f;
22 }
23 }
24 Simd(out)
25 }
26
27 #[inline(always)]
29 pub fn any_true(self) -> bool {
30 self.0.iter().any(|b| *b)
31 }
32
33 #[inline(always)]
35 pub fn all_true(self) -> bool {
36 self.0.iter().all(|b| *b)
37 }
38}
39
40#[duplicate::duplicate_item(
41 _mod_ _vec_;
42 [simd_impls] [Simd];
43 [impls_a4] [Aligned4];
44 [impls_a8] [Aligned8];
45 [impls_a16] [Aligned16];
46 [impls_a32] [Aligned32];
47 [impls_a64] [Aligned64];
48)]
49mod _mod_ {
50 use super::*;
51
52 #[duplicate::duplicate_item(
55 _trait_ _method_;
56 [Add] [add] ;
57 [Sub] [sub] ;
58 [Mul] [mul] ;
59 [Div] [div] ;
60 )]
61 impl<T, const N: usize> _trait_ for _vec_<T, N>
62 where
63 T: Num + Copy,
64 {
65 type Output = Self;
66
67 #[inline(always)]
68 fn _method_(self, rhs: Self) -> Self {
69 let mut out = self.0;
70 for (o, r) in out.iter_mut().zip(rhs.0) {
71 *o = _trait_::_method_(*o, r);
72 }
73 Self(out)
74 }
75 }
76
77 #[duplicate::duplicate_item(
78 _trait_ _method_;
79 [Add] [add] ;
80 [Sub] [sub] ;
81 [Mul] [mul] ;
82 [Div] [div] ;
83 )]
84 impl<T, const N: usize> _trait_<T> for _vec_<T, N>
85 where
86 T: Num + Copy,
87 {
88 type Output = Self;
89
90 #[inline(always)]
91 fn _method_(self, rhs: T) -> Self {
92 let mut out = self.0;
93 for o in out.iter_mut() {
94 *o = _trait_::_method_(*o, rhs);
95 }
96 Self(out)
97 }
98 }
99
100 #[duplicate::duplicate_item(
101 _trait_ _method_;
102 [AddAssign] [add_assign];
103 [SubAssign] [sub_assign];
104 [MulAssign] [mul_assign];
105 [DivAssign] [div_assign];
106 )]
107 impl<T, const N: usize> _trait_ for _vec_<T, N>
108 where
109 T: NumAssignOps + Copy,
110 {
111 #[inline(always)]
112 fn _method_(&mut self, rhs: Self) {
113 for (o, r) in self.0.iter_mut().zip(rhs.0) {
114 _trait_::_method_(o, r);
115 }
116 }
117 }
118
119 #[duplicate::duplicate_item(
120 _trait_ _method_;
121 [AddAssign] [add_assign];
122 [SubAssign] [sub_assign];
123 [MulAssign] [mul_assign];
124 [DivAssign] [div_assign];
125 )]
126 impl<T, const N: usize> _trait_<T> for _vec_<T, N>
127 where
128 T: NumAssignOps + Copy,
129 {
130 #[inline(always)]
131 fn _method_(&mut self, rhs: T) {
132 for o in self.0.iter_mut() {
133 _trait_::_method_(o, rhs);
134 }
135 }
136 }
137
138 impl<T, const N: usize> Neg for _vec_<T, N>
139 where
140 T: Neg<Output = T> + Copy,
141 {
142 type Output = Self;
143
144 #[inline(always)]
145 fn neg(self) -> Self {
146 let mut out = self.0;
147 for (o, x) in out.iter_mut().zip(self.0) {
148 *o = Neg::neg(x);
149 }
150 Self(out)
151 }
152 }
153
154 #[duplicate::duplicate_item(
159 _trait_ _method_;
160 [BitAnd] [bitand];
161 [BitOr] [bitor];
162 [BitXor] [bitxor];
163 )]
164 impl<T, const N: usize> _trait_ for _vec_<T, N>
165 where
166 T: _trait_<Output = T> + Copy,
167 {
168 type Output = Self;
169
170 #[inline(always)]
171 fn _method_(self, rhs: Self) -> Self {
172 let mut out = self.0;
173 for (o, r) in out.iter_mut().zip(rhs.0) {
174 *o = _trait_::_method_(*o, r);
175 }
176 Self(out)
177 }
178 }
179
180 #[duplicate::duplicate_item(
181 _trait_ _method_;
182 [BitAndAssign] [bitand_assign];
183 [BitOrAssign] [bitor_assign];
184 [BitXorAssign] [bitxor_assign];
185 )]
186 impl<T, const N: usize> _trait_ for _vec_<T, N>
187 where
188 T: _trait_ + Copy,
189 {
190 #[inline(always)]
191 fn _method_(&mut self, rhs: Self) {
192 for (o, r) in self.0.iter_mut().zip(rhs.0) {
193 _trait_::_method_(o, r);
194 }
195 }
196 }
197
198 impl<T, const N: usize> Not for _vec_<T, N>
199 where
200 T: Not<Output = T> + Copy,
201 {
202 type Output = Self;
203
204 #[inline(always)]
205 fn not(self) -> Self {
206 let mut out = self.0;
207 for (o, x) in out.iter_mut().zip(self.0) {
208 *o = Not::not(x);
209 }
210 Self(out)
211 }
212 }
213
214 #[duplicate::duplicate_item(
215 _trait_ _method_;
216 [Shl] [shl];
217 [Shr] [shr];
218 )]
219 impl<T, const N: usize> _trait_<usize> for _vec_<T, N>
220 where
221 T: _trait_<usize, Output = T> + Copy,
222 {
223 type Output = Self;
224
225 #[inline(always)]
226 fn _method_(self, rhs: usize) -> Self {
227 let mut out = self.0;
228 for o in out.iter_mut() {
229 *o = _trait_::_method_(*o, rhs);
230 }
231 Self(out)
232 }
233 }
234
235 #[cfg(any(feature = "use_libm_fma", target_arch = "aarch64", target_feature = "fma"))]
247 impl<T, const N: usize> _vec_<T, N>
248 where
249 T: MulAdd<Output = T> + Copy,
250 {
251 #[inline(always)]
263 pub fn mul_add(self, b: Self, c: Self) -> Self {
264 let mut out = self.0;
265 for ((o, b), c) in out.iter_mut().zip(b.0).zip(c.0) {
266 *o = MulAdd::mul_add(*o, b, c);
267 }
268 Self(out)
269 }
270
271 #[inline(always)]
276 pub fn fma_from(&mut self, b: Self, c: Self) {
277 for ((b, c), o) in b.0.iter().zip(c.0.iter()).zip(self.0.iter_mut()) {
278 *o = MulAdd::mul_add(*b, *c, *o);
279 }
280 }
281 }
282
283 #[cfg(not(any(feature = "use_libm_fma", target_arch = "aarch64", target_feature = "fma")))]
284 impl<T, const N: usize> _vec_<T, N>
285 where
286 T: Mul<Output = T> + Add<Output = T> + Copy,
287 {
288 #[inline(always)]
298 pub fn mul_add(self, b: Self, c: Self) -> Self {
299 let mut out = self.0;
300 for ((o, b), c) in out.iter_mut().zip(b.0).zip(c.0) {
301 *o = *o * b + c;
302 }
303 Self(out)
304 }
305
306 #[inline(always)]
312 pub fn fma_from(&mut self, b: Self, c: Self) {
313 for ((b, c), o) in b.0.iter().zip(c.0.iter()).zip(self.0.iter_mut()) {
314 *o = *b * *c + *o;
315 }
316 }
317 }
318
319 impl<T, const N: usize> _vec_<T, N>
324 where
325 T: Float + Copy,
326 {
327 #[duplicate::duplicate_item(
328 _name_;
329 [abs];
330 [sqrt];
331 [recip];
332 [floor];
333 [ceil];
334 [round];
335 [trunc];
336 [fract];
337 )]
338 #[doc = concat!("Lane-wise [`Float::", stringify!(_name_), "`].")]
339 #[inline(always)]
340 pub fn _name_(self) -> Self {
341 Self(self.0.map(|x| x._name_()))
342 }
343
344 #[inline(always)]
347 pub fn min(self, other: Self) -> Self {
348 let mut out = self.0;
349 for (o, r) in out.iter_mut().zip(other.0) {
350 *o = o.min(r);
351 }
352 Self(out)
353 }
354
355 #[inline(always)]
358 pub fn max(self, other: Self) -> Self {
359 let mut out = self.0;
360 for (o, r) in out.iter_mut().zip(other.0) {
361 *o = o.max(r);
362 }
363 Self(out)
364 }
365
366 #[inline(always)]
368 pub fn copysign(self, sign: Self) -> Self {
369 let mut out = self.0;
370 for (o, r) in out.iter_mut().zip(sign.0) {
371 *o = o.copysign(r);
372 }
373 Self(out)
374 }
375 }
376
377 impl<const N: usize> _vec_<f32, N> {
378 #[inline(always)]
383 pub fn round_ties_even(self) -> Self {
384 Self(self.0.map(f32::round_ties_even))
385 }
386 }
387
388 impl<const N: usize> _vec_<f64, N> {
389 #[inline(always)]
394 pub fn round_ties_even(self) -> Self {
395 Self(self.0.map(f64::round_ties_even))
396 }
397 }
398
399 impl<T, const N: usize> _vec_<T, N>
404 where
405 T: PartialOrd + Copy,
406 {
407 #[inline(always)]
409 pub fn simd_lt(self, rhs: Self) -> Simd<bool, N> {
410 Simd(core::array::from_fn(|i| self.0[i] < rhs.0[i]))
411 }
412
413 #[inline(always)]
415 pub fn simd_le(self, rhs: Self) -> Simd<bool, N> {
416 Simd(core::array::from_fn(|i| self.0[i] <= rhs.0[i]))
417 }
418
419 #[inline(always)]
421 pub fn simd_gt(self, rhs: Self) -> Simd<bool, N> {
422 Simd(core::array::from_fn(|i| self.0[i] > rhs.0[i]))
423 }
424
425 #[inline(always)]
427 pub fn simd_ge(self, rhs: Self) -> Simd<bool, N> {
428 Simd(core::array::from_fn(|i| self.0[i] >= rhs.0[i]))
429 }
430 }
431
432 impl<T, const N: usize> _vec_<T, N>
433 where
434 T: PartialEq + Copy,
435 {
436 #[inline(always)]
438 pub fn simd_eq(self, rhs: Self) -> Simd<bool, N> {
439 Simd(core::array::from_fn(|i| self.0[i] == rhs.0[i]))
440 }
441
442 #[inline(always)]
444 pub fn simd_ne(self, rhs: Self) -> Simd<bool, N> {
445 Simd(core::array::from_fn(|i| self.0[i] != rhs.0[i]))
446 }
447 }
448
449 }