1use super::*;
20
21use core::mem::{self, ManuallyDrop};
22use core::num::FpCategory;
23use core::ops::*;
24
25use num_traits::{float::FloatCore, *};
26
27use generic_array::internals::{ArrayConsumer, IntrusiveArrayBuilder};
28
29macro_rules! impl_unary_ops {
30 ($($op_trait:ident::$op:ident),*) => {
31 $(
32 impl<T, N: ArrayLength> $op_trait for NumericArray<T, N>
33 where
34 T: $op_trait,
35 {
36 type Output = NumericArray<<T as $op_trait>::Output, N>;
37
38 #[inline(always)]
39 fn $op(self) -> Self::Output {
40 NumericArray(self.0.map($op_trait::$op))
41 }
42 }
43
44 impl<'a, T: Clone, N: ArrayLength> $op_trait for &'a NumericArray<T, N>
45 where
46 T: $op_trait,
47 {
48 type Output = NumericArray<<T as $op_trait>::Output, N>;
49
50 #[inline(always)]
51 fn $op(self) -> Self::Output {
52 NumericArray((&self.0).map(|x| $op_trait::$op(x.clone())))
53 }
54 }
55 )*
56 }
57}
58
59macro_rules! impl_binary_ops {
60 ($($op_trait:ident::$op:ident),*) => {
61 $(
62 impl<T, U, N: ArrayLength> $op_trait<NumericArray<U, N>> for NumericArray<T, N>
63 where
64 T: $op_trait<U>,
65 {
66 type Output = NumericArray<<T as $op_trait<U>>::Output, N>;
67
68 #[inline(always)]
69 fn $op(self, rhs: NumericArray<U, N>) -> Self::Output {
70 NumericArray(self.0.zip(rhs.0, $op_trait::$op))
71 }
72 }
73
74 impl<'a, T, U: Clone, N: ArrayLength> $op_trait<&'a NumericArray<U, N>> for NumericArray<T, N>
75 where
76 T: $op_trait<U>,
77 {
78 type Output = NumericArray<<T as $op_trait<U>>::Output, N>;
79
80 #[inline(always)]
81 fn $op(self, rhs: &'a NumericArray<U, N>) -> Self::Output {
82 NumericArray(self.0.zip(&rhs.0, |l, r| $op_trait::$op(l, r.clone())))
83 }
84 }
85
86 impl<'a, T: Clone, U, N: ArrayLength> $op_trait<NumericArray<U, N>> for &'a NumericArray<T, N>
87 where
88 T: $op_trait<U>,
89 {
90 type Output = NumericArray<<T as $op_trait<U>>::Output, N>;
91
92 #[inline(always)]
93 fn $op(self, rhs: NumericArray<U, N>) -> Self::Output {
94 NumericArray((&self.0).zip(rhs.0, |l, r| $op_trait::$op(l.clone(), r)))
95 }
96 }
97
98 impl<'a, 'b, T: Clone, U: Clone, N: ArrayLength> $op_trait<&'b NumericArray<U, N>> for &'a NumericArray<T, N>
99 where
100 T: $op_trait<U>,
101 {
102 type Output = NumericArray<<T as $op_trait<U>>::Output, N>;
103
104 #[inline(always)]
105 fn $op(self, rhs: &'b NumericArray<U, N>) -> Self::Output {
106 NumericArray((&self.0).zip(&rhs.0, |l, r| $op_trait::$op(l.clone(), r.clone())))
107 }
108 }
109
110 impl<T, U: Clone, N: ArrayLength> $op_trait<NumericConstant<U>> for NumericArray<T, N>
111 where
112 T: $op_trait<U>,
113 {
114 type Output = NumericArray<<T as $op_trait<U>>::Output, N>;
115
116 #[inline(always)]
117 fn $op(self, rhs: NumericConstant<U>) -> Self::Output {
118 NumericArray(self.0.map(|l| $op_trait::$op(l, rhs.0.clone())))
119 }
120 }
121
122 impl<'a, T: Clone, U: Clone, N: ArrayLength> $op_trait<NumericConstant<U>> for &'a NumericArray<T, N>
123 where
124 T: $op_trait<U>,
125 {
126 type Output = NumericArray<<T as $op_trait<U>>::Output, N>;
127
128 #[inline(always)]
129 fn $op(self, rhs: NumericConstant<U>) -> Self::Output {
130 NumericArray((&self.0).map(|l| $op_trait::$op(l.clone(), rhs.0.clone())))
131 }
132 }
133
134 impl<T, U: Clone, N: ArrayLength> $op_trait<NumericArray<T, N>> for NumericConstant<U>
135 where
136 U: $op_trait<T>,
137 {
138 type Output = NumericArray<<U as $op_trait<T>>::Output, N>;
139
140 #[inline(always)]
141 fn $op(self, rhs: NumericArray<T, N>) -> Self::Output {
142 NumericArray(rhs.0.map(|r| $op_trait::$op(self.0.clone(), r)))
143 }
144 }
145
146 impl<'a, T: Clone, U: Clone, N: ArrayLength> $op_trait<&'a NumericArray<T, N>> for NumericConstant<U>
147 where
148 U: $op_trait<T>,
149 {
150 type Output = NumericArray<<U as $op_trait<T>>::Output, N>;
151
152 #[inline(always)]
153 fn $op(self, rhs: &'a NumericArray<T, N>) -> Self::Output {
154 NumericArray((&rhs.0).map(|r| $op_trait::$op(self.0.clone(), r.clone())))
155 }
156 }
157 )*
158 }
159}
160
161macro_rules! impl_assign_ops {
162 ($($op_trait:ident::$op:ident),*) => {
163 $(
164 impl<T, U, N: ArrayLength> $op_trait<NumericArray<U, N>> for NumericArray<T, N>
165 where
166 T: $op_trait<U>,
167 {
168 fn $op(&mut self, rhs: NumericArray<U, N>) {
169 if mem::needs_drop::<U>() {
170 unsafe {
171 let mut right = ArrayConsumer::new(rhs.0);
172
173 let (right_iter, right_position) = right.iter_position();
174
175 self.iter_mut().zip(right_iter).for_each(|(lhs, rhs)| {
176 $op_trait::$op(lhs, ptr::read(rhs));
177
178 *right_position += 1;
179 });
180 }
181 } else {
182 let right = ManuallyDrop::new(rhs);
183
184 self.iter_mut().zip(right.iter()).for_each(|(lhs, rhs)| unsafe {
185 $op_trait::$op(lhs, ptr::read(rhs));
186 });
187 }
188 }
189 }
190
191 impl<'a, T, U: Clone, N: ArrayLength> $op_trait<&'a NumericArray<U, N>> for NumericArray<T, N>
192 where
193 T: $op_trait<U>,
194 {
195 fn $op(&mut self, rhs: &'a NumericArray<U, N>) {
196 self.iter_mut().zip(rhs.iter()).for_each(|(lhs, rhs)| {
197 $op_trait::$op(lhs, rhs.clone());
198 });
199 }
200 }
201
202 impl<T, U: Clone, N: ArrayLength> $op_trait<NumericConstant<U>> for NumericArray<T, N>
203 where
204 T: $op_trait<U>,
205 {
206 fn $op(&mut self, rhs: NumericConstant<U>) {
207 self.iter_mut().for_each(|lhs| {
208 $op_trait::$op(lhs, rhs.0.clone());
209 });
210 }
211 }
212 )*
213 }
214}
215
216macro_rules! impl_wrapping_ops {
217 ($($op_trait:ident::$op:ident),*) => {
218 $(
219 impl<T, N: ArrayLength> num_traits::$op_trait for NumericArray<T, N>
220 where
221 T: num_traits::$op_trait,
222 {
223 fn $op(&self, rhs: &Self) -> Self {
224 NumericArray((&self.0).zip(&rhs.0, num_traits::$op_trait::$op))
225 }
226 }
227 )*
228 }
229}
230
231macro_rules! impl_checked_ops {
232 ($($op_trait:ident::$op:ident),*) => {
233 $(
234 impl<T, N: ArrayLength> $op_trait for NumericArray<T, N>
235 where
236 T: $op_trait,
237 {
238 fn $op(&self, rhs: &Self) -> Option<Self> {
239 unsafe {
240 let mut array = GenericArray::uninit();
241 let mut builder = IntrusiveArrayBuilder::new(&mut array);
242
243 {
244 let (array_iter, position) = builder.iter_position();
245
246 for (dst, (lhs, rhs)) in array_iter.zip(self.iter().zip(rhs.iter())) {
247 if let Some(value) = $op_trait::$op(lhs, rhs) {
248 dst.write(value);
249 *position += 1;
250 } else {
251 return None;
252 }
253 }
254 }
255
256 Some(NumericArray({
257 builder.finish();
258 IntrusiveArrayBuilder::array_assume_init(array)
259 }))
260 }
261 }
262 }
263 )*
264 }
265}
266
267macro_rules! impl_float_const {
268 ($($f:ident),*) => {
269 impl<T, N: ArrayLength> FloatConst for NumericArray<T, N>
270 where
271 T: FloatConst,
272 {
273 $(
274 fn $f() -> Self {
275 NumericArray(GenericArray::generate(|_| <T as FloatConst>::$f()))
276 }
277 )*
278 }
279 }
280}
281
282impl_unary_ops! {
283 Inv::inv, Neg::neg,
285 Not::not
286}
287
288impl_binary_ops! {
289 Pow::pow, Add::add,
291 Sub::sub,
292 Mul::mul,
293 Div::div,
294 Rem::rem,
295 BitAnd::bitand,
296 BitOr::bitor,
297 BitXor::bitxor,
298 Shr::shr,
299 Shl::shl
300}
301
302impl_assign_ops! {
303 AddAssign::add_assign,
304 SubAssign::sub_assign,
305 MulAssign::mul_assign,
306 DivAssign::div_assign,
307 RemAssign::rem_assign,
308 BitAndAssign::bitand_assign,
309 BitOrAssign::bitor_assign,
310 BitXorAssign::bitxor_assign,
311 ShrAssign::shr_assign,
312 ShlAssign::shl_assign
313}
314
315impl_wrapping_ops! {
316 WrappingAdd::wrapping_add,
317 WrappingSub::wrapping_sub,
318 WrappingMul::wrapping_mul
319}
320
321impl_checked_ops! {
322 CheckedAdd::checked_add,
323 CheckedSub::checked_sub,
324 CheckedMul::checked_mul,
325 CheckedDiv::checked_div
326}
327
328impl<T, N: ArrayLength> CheckedShl for NumericArray<T, N>
329where
330 T: CheckedShl,
331 Self: Shl<u32, Output = Self>,
332{
333 fn checked_shl(&self, rhs: u32) -> Option<Self> {
334 unsafe {
335 let mut array = GenericArray::uninit();
336 let mut builder = IntrusiveArrayBuilder::new(&mut array);
337
338 {
339 let (builder_iter, builder_position) = builder.iter_position();
340
341 for (dst, lhs) in builder_iter.zip(self.iter()) {
342 if let Some(value) = CheckedShl::checked_shl(lhs, rhs) {
343 dst.write(value);
344 *builder_position += 1;
345 } else {
346 return None;
347 }
348 }
349 }
350
351 Some(NumericArray({
352 builder.finish();
353 IntrusiveArrayBuilder::array_assume_init(array)
354 }))
355 }
356 }
357}
358
359impl<T, N: ArrayLength> CheckedShr for NumericArray<T, N>
360where
361 T: CheckedShr,
362 Self: Shr<u32, Output = Self>,
363{
364 fn checked_shr(&self, rhs: u32) -> Option<Self> {
365 unsafe {
366 let mut array = GenericArray::uninit();
367 let mut builder = IntrusiveArrayBuilder::new(&mut array);
368
369 {
370 let (builder_iter, builder_position) = builder.iter_position();
371
372 for (dst, lhs) in builder_iter.zip(self.iter()) {
373 if let Some(value) = CheckedShr::checked_shr(lhs, rhs) {
374 dst.write(value);
375 *builder_position += 1;
376 } else {
377 return None;
378 }
379 }
380 }
381
382 Some(NumericArray({
383 builder.finish();
384 IntrusiveArrayBuilder::array_assume_init(array)
385 }))
386 }
387 }
388}
389
390impl_float_const!(
391 E,
392 FRAC_1_PI,
393 FRAC_1_SQRT_2,
394 FRAC_2_PI,
395 FRAC_2_SQRT_PI,
396 FRAC_PI_2,
397 FRAC_PI_3,
398 FRAC_PI_4,
399 FRAC_PI_6,
400 FRAC_PI_8,
401 LN_10,
402 LN_2,
403 LOG10_E,
404 LOG2_E,
405 PI,
406 SQRT_2
407);
408
409impl<T, N: ArrayLength> Zero for NumericArray<T, N>
410where
411 T: Zero,
412{
413 fn zero() -> Self {
414 NumericArray(GenericArray::generate(|_| <T as Zero>::zero()))
415 }
416
417 fn is_zero(&self) -> bool {
418 self.iter().all(|x| x.is_zero())
419 }
420}
421
422impl<T, N: ArrayLength> One for NumericArray<T, N>
423where
424 T: One,
425{
426 fn one() -> Self {
427 NumericArray(GenericArray::generate(|_| <T as One>::one()))
428 }
429}
430
431impl<T, N: ArrayLength> Saturating for NumericArray<T, N>
432where
433 T: Saturating,
434{
435 fn saturating_add(self, rhs: Self) -> Self {
436 NumericArray(self.0.zip(rhs.0, Saturating::saturating_add))
437 }
438
439 fn saturating_sub(self, rhs: Self) -> Self {
440 NumericArray(self.0.zip(rhs.0, Saturating::saturating_sub))
441 }
442}
443
444impl<T: Clone, N: ArrayLength> Num for NumericArray<T, N>
445where
446 T: Num,
447{
448 type FromStrRadixErr = <T as Num>::FromStrRadixErr;
449
450 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
451 <T as Num>::from_str_radix(str, radix).map(Self::splat)
452 }
453}
454
455impl<T: Clone, N: ArrayLength> Signed for NumericArray<T, N>
456where
457 T: Signed,
458{
459 fn abs(&self) -> Self {
460 NumericArray((&self.0).map(Signed::abs))
461 }
462
463 fn abs_sub(&self, rhs: &Self) -> Self {
464 NumericArray((&self.0).zip(&rhs.0, Signed::abs_sub))
465 }
466
467 fn signum(&self) -> Self {
468 NumericArray((&self.0).map(Signed::signum))
469 }
470
471 fn is_positive(&self) -> bool {
472 self.iter().all(Signed::is_positive)
473 }
474
475 fn is_negative(&self) -> bool {
476 self.iter().any(Signed::is_negative)
477 }
478}
479
480impl<T: Clone, N: ArrayLength> Unsigned for NumericArray<T, N> where T: Unsigned {}
481
482impl<T, N: ArrayLength> Bounded for NumericArray<T, N>
483where
484 T: Bounded,
485{
486 fn min_value() -> Self {
487 NumericArray(GenericArray::generate(|_| <T as Bounded>::min_value()))
488 }
489
490 fn max_value() -> Self {
491 NumericArray(GenericArray::generate(|_| <T as Bounded>::max_value()))
492 }
493}
494
495macro_rules! impl_to_primitive {
496 ($($to:ident => $prim:ty),*) => {
497 impl<T, N: ArrayLength> ToPrimitive for NumericArray<T, N>
498 where
499 T: ToPrimitive,
500 {
501 $(
502 #[inline]
503 fn $to(&self) -> Option<$prim> {
504 if N::to_usize() == 0 { None } else {
505 self.first().and_then(ToPrimitive::$to)
506 }
507 }
508 )*
509 }
510 }
511}
512
513impl_to_primitive! {
514 to_i8 => i8,
515 to_i16 => i16,
516 to_i32 => i32,
517 to_i64 => i64,
518 to_i128 => i128,
519 to_isize => isize,
520
521 to_u8 => u8,
522 to_u16 => u16,
523 to_u32 => u32,
524 to_u64 => u64,
525 to_u128 => u128,
526 to_usize => usize,
527
528 to_f32 => f32,
529 to_f64 => f64
530}
531
532impl<T, N: ArrayLength> NumCast for NumericArray<T, N>
533where
534 T: NumCast + Clone,
535{
536 fn from<P: ToPrimitive>(n: P) -> Option<Self> {
537 T::from(n).map(Self::splat)
538 }
539}
540
541macro_rules! impl_float {
542 ($float:ident { $($extra:tt)* }) => {
543 impl<T, N: ArrayLength> $float for NumericArray<T, N>
544 where
545 T: $float,
546 Self: Copy,
547 {
548 $($extra)*
549
550 #[inline]
551 fn nan() -> Self {
552 Self::splat($float::nan())
553 }
554
555 #[inline]
556 fn infinity() -> Self {
557 Self::splat($float::infinity())
558 }
559
560 #[inline]
561 fn neg_infinity() -> Self {
562 Self::splat($float::neg_infinity())
563 }
564
565 #[inline]
566 fn neg_zero() -> Self {
567 Self::splat($float::neg_zero())
568 }
569
570 #[inline]
571 fn min_value() -> Self {
572 Self::splat($float::min_value())
573 }
574
575 #[inline]
576 fn min_positive_value() -> Self {
577 Self::splat($float::min_positive_value())
578 }
579
580 #[inline]
581 fn max_value() -> Self {
582 Self::splat($float::max_value())
583 }
584
585 #[inline]
586 fn is_nan(self) -> bool {
587 self.iter().any(|x| $float::is_nan(*x))
588 }
589
590 #[inline]
591 fn is_infinite(self) -> bool {
592 self.iter().any(|x| $float::is_infinite(*x))
593 }
594
595 #[inline]
596 fn is_finite(self) -> bool {
597 self.iter().all(|x| $float::is_finite(*x))
598 }
599
600 #[inline]
601 fn is_normal(self) -> bool {
602 self.iter().all(|x| $float::is_normal(*x))
603 }
604
605 #[inline]
606 fn epsilon() -> Self {
607 Self::splat($float::epsilon())
608 }
609
610 #[inline]
611 fn to_degrees(self) -> Self {
612 self.0.map($float::to_degrees).into()
613 }
614
615 #[inline]
616 fn to_radians(self) -> Self {
617 self.0.map($float::to_radians).into()
618 }
619
620 #[inline]
621 fn integer_decode(self) -> (u64, i16, i8) {
622 if N::to_usize() == 0 {
623 (0, 0, 0)
624 } else {
625 self.first().unwrap().integer_decode()
626 }
627 }
628
629 fn classify(self) -> FpCategory {
630 let mut ret = FpCategory::Zero;
631
632 for x in self.iter() {
633 match $float::classify(*x) {
634 FpCategory::Nan => return FpCategory::Nan,
636 FpCategory::Infinite => ret = FpCategory::Infinite,
638 FpCategory::Subnormal if ret != FpCategory::Infinite => {
640 ret = FpCategory::Subnormal;
641 }
642 FpCategory::Normal if ret == FpCategory::Zero => {
644 ret = FpCategory::Normal;
645 }
646 _ => {}
647 }
648 }
649
650 ret
651 }
652
653 #[inline]
654 fn floor(self) -> Self {
655 self.0.map($float::floor).into()
656 }
657
658 #[inline]
659 fn ceil(self) -> Self {
660 self.0.map($float::ceil).into()
661 }
662
663 #[inline]
664 fn round(self) -> Self {
665 self.0.map($float::round).into()
666 }
667
668 #[inline]
669 fn trunc(self) -> Self {
670 self.0.map($float::trunc).into()
671 }
672
673 #[inline]
674 fn fract(self) -> Self {
675 self.0.map($float::fract).into()
676 }
677
678 #[inline]
679 fn abs(self) -> Self {
680 self.0.map($float::abs).into()
681 }
682
683 #[inline]
684 fn signum(self) -> Self {
685 self.0.map($float::signum).into()
686 }
687
688 #[inline]
689 fn is_sign_positive(self) -> bool {
690 self.iter().all(|x| $float::is_sign_positive(*x))
691 }
692
693 #[inline]
694 fn is_sign_negative(self) -> bool {
695 self.iter().any(|x| $float::is_sign_negative(*x))
696 }
697
698 #[inline]
699 fn max(self, other: Self) -> Self {
700 self.0.zip(other.0, $float::max).into()
701 }
702
703 #[inline]
704 fn min(self, other: Self) -> Self {
705 self.0.zip(other.0, $float::min).into()
706 }
707
708 #[inline]
709 fn recip(self) -> Self {
710 self.0.map($float::recip).into()
711 }
712
713 #[inline]
714 fn powi(self, n: i32) -> Self {
715 self.0.map(|x| $float::powi(x, n)).into()
716
717 }
736 }
737 };
738}
739
740impl_float!(FloatCore {});
741
742#[cfg(feature = "std")]
743impl_float!(Float {
744 #[inline]
745 fn mul_add(self, a: Self, b: Self) -> Self {
746 if mem::needs_drop::<T>() {
747 unsafe {
748 let mut left = ArrayConsumer::new(self.0);
749 let mut a_arr = ArrayConsumer::new(a.0);
750 let mut b_arr = ArrayConsumer::new(b.0);
751
752 let (left_iter, left_position) = left.iter_position();
753 let (a_arr_iter, a_arr_position) = a_arr.iter_position();
754 let (b_arr_iter, b_arr_position) = b_arr.iter_position();
755
756 NumericArray::from_iter(left_iter.zip(a_arr_iter.zip(b_arr_iter)).map(|(l, (a, b))| {
757 let l = ptr::read(l);
758 let a = ptr::read(a);
759 let b = ptr::read(b);
760
761 *left_position += 1;
762 *a_arr_position = *left_position;
763 *b_arr_position = *left_position;
764
765 Float::mul_add(l, a, b)
766 }))
767 }
768 } else {
769 let left = ManuallyDrop::new(self);
770 let a = ManuallyDrop::new(a);
771 let b = ManuallyDrop::new(b);
772
773 NumericArray::from_iter(left.iter().zip(a.iter()).zip(b.iter()).map(|((l, a), b)| unsafe {
774 Float::mul_add(ptr::read(l), ptr::read(a), ptr::read(b)) }))
776 }
777 }
778
779 #[inline]
780 fn powf(self, n: Self) -> Self {
781 self.0.zip(n.0, Float::powf).into()
782 }
783
784 #[inline]
785 fn sqrt(self) -> Self {
786 self.0.map(Float::sqrt).into()
787 }
788
789 #[inline]
790 fn exp(self) -> Self {
791 self.0.map(Float::exp).into()
792 }
793
794 #[inline]
795 fn exp2(self) -> Self {
796 self.0.map(Float::exp2).into()
797 }
798
799 #[inline]
800 fn ln(self) -> Self {
801 self.0.map(Float::ln).into()
802 }
803
804 #[inline]
805 fn log(self, base: Self) -> Self {
806 self.0.zip(base.0, Float::log).into()
807 }
808
809 #[inline]
810 fn log2(self) -> Self {
811 self.0.map(Float::log2).into()
812 }
813
814 #[inline]
815 fn log10(self) -> Self {
816 self.0.map(Float::log10).into()
817 }
818
819 #[inline]
820 fn abs_sub(self, other: Self) -> Self {
821 self.0.zip(other.0, Float::abs_sub).into()
822 }
823
824 #[inline]
825 fn cbrt(self) -> Self {
826 self.0.map(Float::cbrt).into()
827 }
828
829 #[inline]
830 fn hypot(self, other: Self) -> Self {
831 self.0.zip(other.0, Float::hypot).into()
832 }
833
834 #[inline]
835 fn sin(self) -> Self {
836 self.0.map(Float::sin).into()
837 }
838
839 #[inline]
840 fn cos(self) -> Self {
841 self.0.map(Float::cos).into()
842 }
843
844 #[inline]
845 fn tan(self) -> Self {
846 self.0.map(Float::tan).into()
847 }
848
849 #[inline]
850 fn asin(self) -> Self {
851 self.0.map(Float::asin).into()
852 }
853
854 #[inline]
855 fn acos(self) -> Self {
856 self.0.map(Float::acos).into()
857 }
858
859 #[inline]
860 fn atan(self) -> Self {
861 self.0.map(Float::atan).into()
862 }
863
864 #[inline]
865 fn atan2(self, other: Self) -> Self {
866 self.0.zip(other.0, Float::atan2).into()
867 }
868
869 #[inline]
870 fn sin_cos(self) -> (Self, Self) {
871 let mut sin_array = GenericArray::uninit();
872 let mut cos_array = GenericArray::uninit();
873
874 let mut sin_destination = IntrusiveArrayBuilder::new(&mut sin_array);
875 let mut cos_destination = IntrusiveArrayBuilder::new(&mut cos_array);
876
877 if mem::needs_drop::<T>() {
878 unsafe {
879 let mut source = ArrayConsumer::new(self.0);
880
881 let (source_iter, source_position) = source.iter_position();
882
883 {
884 let (sin_destination_iter, sin_destination_position) = sin_destination.iter_position();
885 let (cos_destination_iter, cos_destination_position) = cos_destination.iter_position();
886
887 sin_destination_iter
888 .zip(cos_destination_iter)
889 .zip(source_iter)
890 .for_each(|((sin, cos), src)| {
891 let x = ptr::read(src);
892
893 *source_position += 1;
894
895 let (s, c) = Float::sin_cos(x);
896
897 sin.write(s);
898 cos.write(c);
899
900 *sin_destination_position = *source_position;
901 *cos_destination_position = *source_position;
902 });
903 }
904 }
905 } else {
906 unsafe {
907 let (sin_destination_iter, _) = sin_destination.iter_position();
908 let (cos_destination_iter, _) = cos_destination.iter_position();
909
910 sin_destination_iter
911 .zip(cos_destination_iter)
912 .zip(self.iter())
913 .for_each(|((sin, cos), src)| {
914 let (s, c) = Float::sin_cos(ptr::read(src));
915
916 sin.write(s);
917 cos.write(c);
918 });
919 }
920 }
921
922 (
923 NumericArray::new(unsafe { sin_destination.finish(); IntrusiveArrayBuilder::array_assume_init(sin_array) }),
924 NumericArray::new(unsafe { cos_destination.finish(); IntrusiveArrayBuilder::array_assume_init(cos_array) }),
925 )
926 }
927
928 #[inline]
929 fn exp_m1(self) -> Self {
930 self.0.map(Float::exp_m1).into()
931 }
932
933 #[inline]
934 fn ln_1p(self) -> Self {
935 self.0.map(Float::ln_1p).into()
936 }
937
938 #[inline]
939 fn sinh(self) -> Self {
940 self.0.map(Float::sinh).into()
941 }
942
943 #[inline]
944 fn cosh(self) -> Self {
945 self.0.map(Float::cosh).into()
946 }
947
948 #[inline]
949 fn tanh(self) -> Self {
950 self.0.map(Float::tanh).into()
951 }
952
953 #[inline]
954 fn asinh(self) -> Self {
955 self.0.map(Float::asinh).into()
956 }
957
958 #[inline]
959 fn acosh(self) -> Self {
960 self.0.map(Float::acosh).into()
961 }
962
963 #[inline]
964 fn atanh(self) -> Self {
965 self.0.map(Float::atanh).into()
966 }
967});