-use crate::{f16::F16, ieee754::FloatEncoding, scalar::Scalar};
+use crate::{f16::F16, ieee754::FloatEncoding};
use core::ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
fn make(ctx: Self::Context, v: Self::Prim) -> Self;
}
+pub trait ConvertFrom<T>: Sized {
+ fn cvt_from(v: T) -> Self;
+}
+
+impl<T> ConvertFrom<T> for T {
+ fn cvt_from(v: T) -> Self {
+ v
+ }
+}
+
pub trait ConvertTo<T> {
fn to(self) -> T;
}
-impl<T> ConvertTo<T> for T {
+impl<F, T: ConvertFrom<F>> ConvertTo<T> for F {
fn to(self) -> T {
- self
+ T::cvt_from(self)
}
}
-macro_rules! impl_convert_to_using_as {
+macro_rules! impl_convert_from_using_as {
($first:ident $(, $ty:ident)*) => {
$(
- impl ConvertTo<$first> for $ty {
- fn to(self) -> $first {
- self as $first
+ impl ConvertFrom<$first> for $ty {
+ fn cvt_from(v: $first) -> Self {
+ v as _
}
}
- impl ConvertTo<$ty> for $first {
- fn to(self) -> $ty {
- self as $ty
+ impl ConvertFrom<$ty> for $first {
+ fn cvt_from(v: $ty) -> Self {
+ v as _
}
}
)*
- impl_convert_to_using_as![$($ty),*];
+ impl_convert_from_using_as![$($ty),*];
};
() => {
};
}
-impl_convert_to_using_as![u8, i8, u16, i16, u32, i32, u64, i64, f32, f64];
+impl_convert_from_using_as![u8, i8, u16, i16, u32, i32, u64, i64, f32, f64];
pub trait Number:
Compare
pub trait SInt: Int + Neg<Output = Self> {}
-macro_rules! impl_int {
- ($ty:ident) => {
- impl Int for $ty {
- fn leading_zeros(self) -> Self {
- self.leading_zeros() as Self
- }
- fn leading_ones(self) -> Self {
- self.leading_ones() as Self
- }
- fn trailing_zeros(self) -> Self {
- self.trailing_zeros() as Self
- }
- fn trailing_ones(self) -> Self {
- self.trailing_ones() as Self
- }
- fn count_zeros(self) -> Self {
- self.count_zeros() as Self
- }
- fn count_ones(self) -> Self {
- self.count_ones() as Self
- }
- }
- };
-}
-
-macro_rules! impl_uint {
- ($($ty:ident),*) => {
- $(
- impl_int!($ty);
- impl UInt for $ty {}
- )*
- };
-}
-
-impl_uint![u8, u16, u32, u64];
-
-macro_rules! impl_sint {
- ($($ty:ident),*) => {
- $(
- impl_int!($ty);
- impl SInt for $ty {}
- )*
- };
-}
-
-impl_sint![i8, i16, i32, i64];
-
pub trait Float: Number + Neg<Output = Self> {
- type FloatEncoding: FloatEncoding + Make<Context = Scalar, Prim = <Self as Make>::Prim>;
+ type FloatEncoding: FloatEncoding + From<<Self as Make>::Prim> + Into<<Self as Make>::Prim>;
type BitsType: UInt
- + Make<Context = Self::Context, Prim = <Self::FloatEncoding as Float>::BitsType>
+ + Make<Context = Self::Context, Prim = <Self::FloatEncoding as FloatEncoding>::BitsType>
+ ConvertTo<Self::SignedBitsType>
+ Compare<Bool = Self::Bool>;
type SignedBitsType: SInt
- + Make<Context = Self::Context, Prim = <Self::FloatEncoding as Float>::SignedBitsType>
+ + Make<Context = Self::Context, Prim = <Self::FloatEncoding as FloatEncoding>::SignedBitsType>
+ ConvertTo<Self::BitsType>
+ Compare<Bool = Self::Bool>;
fn abs(self) -> Self;
}
}
-macro_rules! impl_float {
- ($ty:ty, $bits:ty, $signed_bits:ty) => {
- impl Float for $ty {
- type FloatEncoding = $ty;
- type BitsType = $bits;
- type SignedBitsType = $signed_bits;
- fn abs(self) -> Self {
- #[cfg(feature = "std")]
- return self.abs();
- #[cfg(not(feature = "std"))]
- todo!();
- }
- fn trunc(self) -> Self {
- #[cfg(feature = "std")]
- return self.trunc();
- #[cfg(not(feature = "std"))]
- todo!();
- }
- fn ceil(self) -> Self {
- #[cfg(feature = "std")]
- return self.ceil();
- #[cfg(not(feature = "std"))]
- todo!();
- }
- fn floor(self) -> Self {
- #[cfg(feature = "std")]
- return self.floor();
- #[cfg(not(feature = "std"))]
- todo!();
- }
- fn round(self) -> Self {
- #[cfg(feature = "std")]
- return self.round();
- #[cfg(not(feature = "std"))]
- todo!();
- }
- #[cfg(feature = "fma")]
- fn fma(self, a: Self, b: Self) -> Self {
- self.mul_add(a, b)
- }
- fn is_nan(self) -> Self::Bool {
- self.is_nan()
- }
- fn is_infinite(self) -> Self::Bool {
- self.is_infinite()
- }
- fn is_finite(self) -> Self::Bool {
- self.is_finite()
- }
- fn from_bits(v: Self::BitsType) -> Self {
- <$ty>::from_bits(v)
- }
- fn to_bits(self) -> Self::BitsType {
- self.to_bits()
- }
- }
- };
-}
-
-impl_float!(f32, u32, i32);
-impl_float!(f64, u64, i64);
-
pub trait Bool: Make + BitOps {}
-impl Bool for bool {}
-
pub trait Select<T>: Bool {
fn select(self, true_v: T, false_v: T) -> T;
}
-impl<T> Select<T> for bool {
- fn select(self, true_v: T, false_v: T) -> T {
- if self {
- true_v
- } else {
- false_v
- }
- }
-}
pub trait Compare: Make {
type Bool: Bool + Select<Self>;
fn eq(self, rhs: Self) -> Self::Bool;
fn le(self, rhs: Self) -> Self::Bool;
fn ge(self, rhs: Self) -> Self::Bool;
}
-
-macro_rules! impl_compare_using_partial_cmp {
- ($($ty:ty),*) => {
- $(
- impl Compare for $ty {
- type Bool = bool;
- fn eq(self, rhs: Self) -> Self::Bool {
- self == rhs
- }
- fn ne(self, rhs: Self) -> Self::Bool {
- self != rhs
- }
- fn lt(self, rhs: Self) -> Self::Bool {
- self < rhs
- }
- fn gt(self, rhs: Self) -> Self::Bool {
- self > rhs
- }
- fn le(self, rhs: Self) -> Self::Bool {
- self <= rhs
- }
- fn ge(self, rhs: Self) -> Self::Bool {
- self >= rhs
- }
- }
- )*
- };
-}
-
-impl_compare_using_partial_cmp![bool, u8, i8, u16, i16, F16, u32, i32, f32, u64, i64, f64];