add count_leading_zeros, count_trailing_zeros, and count_ones implementations
[vector-math.git] / src / prim.rs
index 08ede9e643616a73a8fe15fb189cfdf4a32e741b..7ba23e5b394ba9fe9c9ea1f18a43ee9fbacd9a3b 100644 (file)
@@ -1,3 +1,5 @@
+#[cfg(not(feature = "std"))]
+use crate::scalar::{Scalar, Value};
 use crate::{
     f16::F16,
     traits::{ConvertFrom, ConvertTo},
@@ -85,6 +87,11 @@ pub trait PrimInt:
     + ops::ShlAssign
     + ops::ShrAssign
 {
+    const ZERO: Self;
+    const ONE: Self;
+    const MIN: Self;
+    const MAX: Self;
+    const BITS: Self;
 }
 
 pub trait PrimUInt: PrimInt + ConvertFrom<Self::SignedType> {
@@ -99,8 +106,20 @@ macro_rules! impl_int {
     ($uint:ident, $sint:ident) => {
         impl PrimBase for $uint {}
         impl PrimBase for $sint {}
-        impl PrimInt for $uint {}
-        impl PrimInt for $sint {}
+        impl PrimInt for $uint {
+            const ZERO: Self = 0;
+            const ONE: Self = 1;
+            const MIN: Self = 0;
+            const MAX: Self = !0;
+            const BITS: Self = (0 as $uint).count_zeros() as $uint;
+        }
+        impl PrimInt for $sint {
+            const ZERO: Self = 0;
+            const ONE: Self = 1;
+            const MIN: Self = $sint::MIN;
+            const MAX: Self = $sint::MAX;
+            const BITS: Self = (0 as $sint).count_zeros() as $sint;
+        }
         impl PrimUInt for $uint {
             type SignedType = $sint;
         }
@@ -139,6 +158,17 @@ pub trait PrimFloat:
     fn is_nan(self) -> bool;
     fn from_bits(bits: Self::BitsType) -> Self;
     fn to_bits(self) -> Self::BitsType;
+    fn abs(self) -> Self;
+    fn max_contiguous_integer() -> Self {
+        (Self::BitsType::cvt_from(1) << (Self::MANTISSA_FIELD_WIDTH + 1.to())).to()
+    }
+    fn is_finite(self) -> bool;
+    fn trunc(self) -> Self;
+    /// round to nearest, ties to unspecified
+    fn round(self) -> Self;
+    fn floor(self) -> Self;
+    fn ceil(self) -> Self;
+    fn copy_sign(self, sign: Self) -> Self;
 }
 
 macro_rules! impl_float {
@@ -185,6 +215,46 @@ macro_rules! impl_float {
             fn to_bits(self) -> Self::BitsType {
                 self.to_bits()
             }
+            fn abs(self) -> Self {
+                #[cfg(feature = "std")]
+                return $float::abs(self);
+                #[cfg(not(feature = "std"))]
+                return crate::algorithms::base::abs(Scalar, Value(self)).0;
+            }
+            fn is_finite(self) -> bool {
+                $float::is_finite(self)
+            }
+            fn trunc(self) -> Self {
+                #[cfg(feature = "std")]
+                return $float::trunc(self);
+                #[cfg(not(feature = "std"))]
+                return crate::algorithms::base::trunc(Scalar, Value(self)).0;
+            }
+            fn round(self) -> Self {
+                #[cfg(feature = "std")]
+                return $float::round(self);
+                #[cfg(not(feature = "std"))]
+                return crate::algorithms::base::round_to_nearest_ties_to_even(Scalar, Value(self))
+                    .0;
+            }
+            fn floor(self) -> Self {
+                #[cfg(feature = "std")]
+                return $float::floor(self);
+                #[cfg(not(feature = "std"))]
+                return crate::algorithms::base::floor(Scalar, Value(self)).0;
+            }
+            fn ceil(self) -> Self {
+                #[cfg(feature = "std")]
+                return $float::ceil(self);
+                #[cfg(not(feature = "std"))]
+                return crate::algorithms::base::ceil(Scalar, Value(self)).0;
+            }
+            fn copy_sign(self, sign: Self) -> Self {
+                #[cfg(feature = "std")]
+                return $float::copysign(self, sign);
+                #[cfg(not(feature = "std"))]
+                return crate::algorithms::base::copy_sign(Scalar, Value(self), Value(sign)).0;
+            }
         }
     };
 }