1use core::ops::{Add, Div, Mul, Neg, Sub};
16
17use crate::bool_mask::HasBoolMask;
18
19#[cfg(all(not(feature = "std"), feature = "libm"))]
20mod libm;
21#[cfg(feature = "wide")]
22mod wide;
23
24pub trait Real {
27 #[must_use]
29 fn from_f64(n: f64) -> Self;
30}
31
32pub trait FromScalar {
34 type Scalar;
37
38 #[must_use]
41 fn from_scalar(scalar: Self::Scalar) -> Self;
42}
43
44pub trait FromScalarArray<const N: usize>: FromScalar {
46 #[must_use]
48 fn from_array(scalars: [Self::Scalar; N]) -> Self;
49}
50
51pub trait IntoScalarArray<const N: usize>: FromScalar {
53 #[must_use]
55 fn into_array(self) -> [Self::Scalar; N];
56}
57
58pub trait Zero {
60 #[must_use]
62 fn zero() -> Self;
63}
64
65pub trait One {
67 #[must_use]
69 fn one() -> Self;
70}
71
72pub trait Arithmetics
74where
75 Self: Add<Output = Self>
76 + Sub<Output = Self>
77 + Mul<Output = Self>
78 + Div<Output = Self>
79 + Neg<Output = Self>
80 + Sized,
81 for<'a> Self: Add<&'a Self, Output = Self>
82 + Sub<&'a Self, Output = Self>
83 + Mul<&'a Self, Output = Self>
84 + Div<&'a Self, Output = Self>,
85{
86}
87
88impl<T> Arithmetics for T
89where
90 T: Add<Output = Self>
91 + Sub<Output = Self>
92 + Mul<Output = Self>
93 + Div<Output = Self>
94 + Neg<Output = Self>
95 + Sized,
96 for<'a> Self: Add<&'a Self, Output = Self>
97 + Sub<&'a Self, Output = Self>
98 + Mul<&'a Self, Output = Self>
99 + Div<&'a Self, Output = Self>,
100{
101}
102
103pub trait MinMax: Sized {
105 #[must_use]
107 fn min(self, other: Self) -> Self;
108
109 #[must_use]
111 fn max(self, other: Self) -> Self;
112
113 #[must_use]
116 fn min_max(self, other: Self) -> (Self, Self);
117}
118
119pub trait Trigonometry: Sized {
121 #[must_use]
123 fn sin(self) -> Self;
124
125 #[must_use]
127 fn cos(self) -> Self;
128
129 #[must_use]
132 fn sin_cos(self) -> (Self, Self);
133
134 #[must_use]
136 fn tan(self) -> Self;
137
138 #[must_use]
140 fn asin(self) -> Self;
141
142 #[must_use]
144 fn acos(self) -> Self;
145
146 #[must_use]
148 fn atan(self) -> Self;
149
150 #[must_use]
152 fn atan2(self, other: Self) -> Self;
153}
154
155pub trait Abs {
157 #[must_use]
159 fn abs(self) -> Self;
160}
161
162pub trait Sqrt {
164 #[must_use]
166 fn sqrt(self) -> Self;
167}
168
169pub trait Cbrt {
171 #[must_use]
173 fn cbrt(self) -> Self;
174}
175
176pub trait Powf {
181 #[must_use]
183 fn powf(self, exp: Self) -> Self;
184}
185
186pub trait Powi {
188 #[must_use]
190 fn powi(self, exp: i32) -> Self;
191}
192
193pub trait Powu {
195 #[must_use]
197 fn powu(self, exp: u32) -> Self;
198}
199
200pub trait Recip {
202 #[must_use]
204 fn recip(self) -> Self;
205}
206
207pub trait Exp {
209 #[must_use]
211 fn exp(self) -> Self;
212}
213
214pub trait IsValidDivisor: HasBoolMask {
216 #[must_use]
222 fn is_valid_divisor(&self) -> Self::Mask;
223}
224
225pub trait Hypot {
227 #[must_use]
230 fn hypot(self, other: Self) -> Self;
231}
232
233pub trait Round {
235 #[must_use]
237 fn round(self) -> Self;
238
239 #[must_use]
241 fn floor(self) -> Self;
242
243 #[must_use]
245 fn ceil(self) -> Self;
246}
247
248pub trait Clamp {
250 #[must_use]
252 fn clamp(self, min: Self, max: Self) -> Self;
253
254 #[must_use]
256 fn clamp_min(self, min: Self) -> Self;
257
258 #[must_use]
260 fn clamp_max(self, max: Self) -> Self;
261}
262
263pub trait ClampAssign {
265 fn clamp_assign(&mut self, min: Self, max: Self);
267
268 fn clamp_min_assign(&mut self, min: Self);
270
271 fn clamp_max_assign(&mut self, max: Self);
273}
274
275pub trait MulAdd {
277 #[must_use]
279 fn mul_add(self, m: Self, a: Self) -> Self;
280}
281
282pub trait MulSub {
284 #[must_use]
286 fn mul_sub(self, m: Self, s: Self) -> Self;
287}
288
289pub trait SaturatingAdd<Rhs = Self> {
291 type Output;
293
294 #[must_use]
296 fn saturating_add(self, other: Rhs) -> Self::Output;
297}
298
299pub trait SaturatingSub<Rhs = Self> {
301 type Output;
303
304 #[must_use]
306 fn saturating_sub(self, other: Rhs) -> Self::Output;
307}
308
309pub trait Signum {
311 fn signum(self) -> Self;
317}
318
319pub trait Ln {
321 fn ln(self) -> Self;
323}
324
325macro_rules! impl_uint {
326 ($($ty: ident),+) => {
327 $(
328 impl FromScalar for $ty {
329 type Scalar = Self;
330
331 #[inline]
332 fn from_scalar(scalar: Self) -> Self {
333 scalar
334 }
335 }
336
337 impl FromScalarArray<1> for $ty {
338 #[inline]
339 fn from_array(scalars: [Self; 1]) -> Self {
340 let [scalar] = scalars;
341 scalar
342 }
343 }
344
345 impl IntoScalarArray<1> for $ty {
346 #[inline]
347 fn into_array(self) -> [Self; 1] {
348 [self]
349 }
350 }
351
352 impl Zero for $ty {
353 #[inline]
354 fn zero() -> Self {
355 0
356 }
357 }
358
359 impl One for $ty {
360 #[inline]
361 fn one() -> Self {
362 1
363 }
364 }
365
366 impl MinMax for $ty {
367 #[inline]
368 fn min(self, other: Self) -> Self {
369 core::cmp::Ord::min(self, other)
370 }
371
372 #[inline]
373 fn max(self, other: Self) -> Self {
374 core::cmp::Ord::max(self, other)
375 }
376
377 #[inline]
378 fn min_max(self, other: Self) -> (Self, Self) {
379 if self > other {
380 (other, self)
381 } else {
382 (self, other)
383 }
384 }
385 }
386
387 impl Powu for $ty {
388 #[inline]
389 fn powu(self, exp: u32) -> Self {
390 pow(self, exp)
391 }
392 }
393
394 impl IsValidDivisor for $ty {
395 #[inline]
396 fn is_valid_divisor(&self) -> bool {
397 *self != 0
398 }
399 }
400
401 impl Clamp for $ty {
402 #[inline]
403 fn clamp(self, min: Self, max: Self) -> Self {
404 core::cmp::Ord::clamp(self, min, max)
405 }
406
407 #[inline]
408 fn clamp_min(self, min: Self) -> Self {
409 core::cmp::Ord::max(self, min)
410 }
411
412 #[inline]
413 fn clamp_max(self, max: Self) -> Self {
414 core::cmp::Ord::min(self, max)
415 }
416 }
417
418 impl ClampAssign for $ty {
419 #[inline]
420 fn clamp_assign(&mut self, min: Self, max: Self) {
421 *self = core::cmp::Ord::clamp(*self, min, max);
422 }
423
424 #[inline]
425 fn clamp_min_assign(&mut self, min: Self) {
426 *self = core::cmp::Ord::max(*self, min);
427 }
428
429 #[inline]
430 fn clamp_max_assign(&mut self, max: Self) {
431 *self = core::cmp::Ord::min(*self, max);
432 }
433 }
434
435 impl MulAdd for $ty {
436 #[inline]
437 fn mul_add(self, m: Self, a: Self) -> Self {
438 (self * m) + a
439 }
440 }
441
442 impl MulSub for $ty {
443 #[inline]
444 fn mul_sub(self, m: Self, s: Self) -> Self {
445 (self * m) - s
446 }
447 }
448
449 impl SaturatingAdd for $ty {
450 type Output = $ty;
451 #[inline]
452 fn saturating_add(self, other: Self) -> Self{
453 <$ty>::saturating_add(self, other)
454 }
455 }
456
457 impl SaturatingSub for $ty {
458 type Output = $ty;
459 #[inline]
460 fn saturating_sub(self, other: Self) -> Self{
461 <$ty>::saturating_sub(self, other)
462 }
463 }
464 )+
465 };
466}
467
468macro_rules! impl_float {
469 ($($ty: ident),+) => {
470 $(
471 impl Real for $ty {
472 #[inline]
473 fn from_f64(n: f64) -> $ty {
474 n as $ty
475 }
476 }
477
478 impl FromScalar for $ty {
479 type Scalar = Self;
480
481 #[inline]
482 fn from_scalar(scalar: Self) -> Self {
483 scalar
484 }
485 }
486
487 impl FromScalarArray<1> for $ty {
488 #[inline]
489 fn from_array(scalars: [Self; 1]) -> Self {
490 let [scalar] = scalars;
491 scalar
492 }
493 }
494
495 impl IntoScalarArray<1> for $ty {
496 #[inline]
497 fn into_array(self) -> [Self; 1] {
498 [self]
499 }
500 }
501
502 impl Zero for $ty {
503 #[inline]
504 fn zero() -> Self {
505 0.0
506 }
507 }
508
509 impl One for $ty {
510 #[inline]
511 fn one() -> Self {
512 1.0
513 }
514 }
515
516 impl MinMax for $ty {
517 #[inline]
518 fn max(self, other: Self) -> Self {
519 $ty::max(self, other)
520 }
521
522 #[inline]
523 fn min(self, other: Self) -> Self {
524 $ty::min(self, other)
525 }
526
527 #[inline]
528 fn min_max(self, other: Self) -> (Self, Self) {
529 if self > other {
530 (other, self)
531 } else {
532 (self, other)
533 }
534 }
535 }
536
537 impl Powu for $ty {
538 #[inline]
539 fn powu(self, exp: u32) -> Self {
540 pow(self, exp)
541 }
542 }
543
544 impl IsValidDivisor for $ty {
545 #[inline]
546 fn is_valid_divisor(&self) -> bool {
547 $ty::is_normal(*self)
548 }
549 }
550
551 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
552 impl Trigonometry for $ty {
553 #[inline]
554 fn sin(self) -> Self {
555 $ty::sin(self)
556 }
557
558 #[inline]
559 fn cos(self) -> Self {
560 $ty::cos(self)
561 }
562
563 #[inline]
564 fn sin_cos(self) -> (Self, Self) {
565 $ty::sin_cos(self)
566 }
567
568 #[inline]
569 fn tan(self) -> Self {
570 $ty::tan(self)
571 }
572
573 #[inline]
574 fn asin(self) -> Self {
575 $ty::asin(self)
576 }
577
578 #[inline]
579 fn acos(self) -> Self {
580 $ty::acos(self)
581 }
582
583 #[inline]
584 fn atan(self) -> Self {
585 $ty::atan(self)
586 }
587
588 #[inline]
589 fn atan2(self, other: Self) -> Self {
590 $ty::atan2(self, other)
591 }
592 }
593
594 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
595 impl Abs for $ty {
596 #[inline]
597 fn abs(self) -> Self {
598 $ty::abs(self)
599 }
600 }
601
602 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
603 impl Sqrt for $ty {
604 #[inline]
605 fn sqrt(self) -> Self {
606 $ty::sqrt(self)
607 }
608 }
609
610 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
611 impl Cbrt for $ty {
612 #[inline]
613 fn cbrt(self) -> Self {
614 $ty::cbrt(self)
615 }
616 }
617
618 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
619 impl Powf for $ty {
620 #[inline]
621 fn powf(self, exp: Self) -> Self {
622 $ty::powf(self, exp)
623 }
624 }
625
626 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
627 impl Powi for $ty {
628 #[inline]
629 fn powi(self, exp: i32) -> Self {
630 $ty::powi(self, exp)
631 }
632 }
633
634 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
635 impl Recip for $ty {
636 #[inline]
637 fn recip(self) -> Self {
638 $ty::recip(self)
639 }
640 }
641
642 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
643 impl Exp for $ty {
644 #[inline]
645 fn exp(self) -> Self {
646 $ty::exp(self)
647 }
648 }
649
650 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
651 impl Hypot for $ty {
652 #[inline]
653 fn hypot(self, other: Self) -> Self {
654 $ty::hypot(self, other)
655 }
656 }
657
658 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
659 impl Round for $ty {
660 #[inline]
661 fn round(self) -> Self {
662 $ty::round(self)
663 }
664
665 #[inline]
666 fn floor(self) -> Self {
667 $ty::floor(self)
668 }
669
670 #[inline]
671 fn ceil(self) -> Self {
672 $ty::ceil(self)
673 }
674 }
675
676 impl Clamp for $ty {
677 #[inline]
678 fn clamp(self, min: Self, max: Self) -> Self {
679 $ty::clamp(self, min, max)
680 }
681
682 #[inline]
683 fn clamp_min(self, min: Self) -> Self {
684 $ty::max(self, min)
685 }
686
687 #[inline]
688 fn clamp_max(self, max: Self) -> Self {
689 $ty::min(self, max)
690 }
691 }
692
693 impl ClampAssign for $ty {
694 #[inline]
695 fn clamp_assign(&mut self, min: Self, max: Self) {
696 *self = $ty::clamp(*self, min, max);
697 }
698
699 #[inline]
700 fn clamp_min_assign(&mut self, min: Self) {
701 *self = $ty::max(*self, min);
702 }
703
704 #[inline]
705 fn clamp_max_assign(&mut self, max: Self) {
706 *self = $ty::min(*self, max);
707 }
708 }
709
710 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
711 impl MulAdd for $ty {
712 #[inline]
713 fn mul_add(self, m: Self, a: Self) -> Self {
714 $ty::mul_add(self, m, a)
715 }
716 }
717
718 impl MulSub for $ty {
719 #[inline]
720 fn mul_sub(self, m: Self, s: Self) -> Self {
721 (self * m) - s
722 }
723 }
724
725 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
726 impl Signum for $ty {
727 #[inline]
728 fn signum(self) -> Self {
729 $ty::signum(self)
730 }
731 }
732
733 #[cfg(any(feature = "std", all(test, not(feature = "libm"))))]
734 impl Ln for $ty {
735 #[inline]
736 fn ln(self) -> Self {
737 $ty::ln(self)
738 }
739 }
740 )+
741 };
742}
743
744impl_uint!(u8, u16, u32, u64, u128);
745impl_float!(f32, f64);
746
747#[inline]
763fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: u32) -> T {
764 if exp == 0 {
765 return T::one();
766 }
767
768 while exp & 1 == 0 {
769 base = base.clone() * base;
770 exp >>= 1;
771 }
772 if exp == 1 {
773 return base;
774 }
775
776 let mut acc = base.clone();
777 while exp > 1 {
778 exp >>= 1;
779 base = base.clone() * base;
780 if exp & 1 == 1 {
781 acc = acc * base.clone();
782 }
783 }
784 acc
785}
786
787pub trait PartialCmp: HasBoolMask {
792 #[must_use]
794 fn lt(&self, other: &Self) -> Self::Mask;
795
796 #[must_use]
798 fn lt_eq(&self, other: &Self) -> Self::Mask;
799
800 #[must_use]
802 fn eq(&self, other: &Self) -> Self::Mask;
803
804 #[must_use]
806 fn neq(&self, other: &Self) -> Self::Mask;
807
808 #[must_use]
810 fn gt_eq(&self, other: &Self) -> Self::Mask;
811
812 #[must_use]
814 fn gt(&self, other: &Self) -> Self::Mask;
815}
816
817macro_rules! impl_partial_cmp {
818 ($($ty:ident),+) => {
819 $(
820 impl PartialCmp for $ty {
821 #[inline]
822 fn lt(&self, other: &Self) -> Self::Mask {
823 self < other
824 }
825
826 #[inline]
827 fn lt_eq(&self, other: &Self) -> Self::Mask {
828 self <= other
829 }
830
831 #[inline]
832 fn eq(&self, other: &Self) -> Self::Mask {
833 self == other
834 }
835
836 #[inline]
837 fn neq(&self, other: &Self) -> Self::Mask {
838 self != other
839 }
840
841 #[inline]
842 fn gt_eq(&self, other: &Self) -> Self::Mask {
843 self >= other
844 }
845
846 #[inline]
847 fn gt(&self, other: &Self) -> Self::Mask {
848 self > other
849 }
850 }
851 )+
852 };
853}
854
855impl_partial_cmp!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);