192 lines
4.8 KiB
Rust
192 lines
4.8 KiB
Rust
use private::PrimitiveNumSealed;
|
|
|
|
use super::{Float, Integer, Numeric, Signed, SqrtReal, SqrtUnit, Unsigned, Widen, WidenInto};
|
|
|
|
mod private {
|
|
pub trait PrimitiveNumSealed: Copy + Clone {}
|
|
}
|
|
|
|
impl PrimitiveNumSealed for u8 {}
|
|
impl PrimitiveNumSealed for u16 {}
|
|
impl PrimitiveNumSealed for u32 {}
|
|
impl PrimitiveNumSealed for u64 {}
|
|
impl PrimitiveNumSealed for u128 {}
|
|
impl PrimitiveNumSealed for usize {}
|
|
impl PrimitiveNumSealed for i8 {}
|
|
impl PrimitiveNumSealed for i16 {}
|
|
impl PrimitiveNumSealed for i32 {}
|
|
impl PrimitiveNumSealed for i64 {}
|
|
impl PrimitiveNumSealed for i128 {}
|
|
impl PrimitiveNumSealed for isize {}
|
|
impl PrimitiveNumSealed for f32 {}
|
|
impl PrimitiveNumSealed for f64 {}
|
|
|
|
/// A marker trait used to define only primitive Rust number types.
|
|
pub trait PrimitiveNum: Numeric {}
|
|
impl<T: PrimitiveNumSealed + Numeric> PrimitiveNum for T {}
|
|
|
|
macro_rules! impl_numeric_for_primitive_int {
|
|
($unit:ty) => {
|
|
impl Numeric for $unit {
|
|
const ZERO: Self = 0;
|
|
const ONE: Self = 1;
|
|
const TWO: Self = 2;
|
|
const MAX: Self = <$unit>::MAX;
|
|
const MIN: Self = <$unit>::MIN;
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! impl_numeric_for_primitive_float {
|
|
($unit:ty) => {
|
|
impl Numeric for $unit {
|
|
const ZERO: Self = 0.0;
|
|
const ONE: Self = 1.0;
|
|
const TWO: Self = 2.0;
|
|
const MAX: Self = <$unit>::MAX;
|
|
const MIN: Self = <$unit>::MIN;
|
|
}
|
|
};
|
|
}
|
|
|
|
impl_numeric_for_primitive_int!(u8);
|
|
impl_numeric_for_primitive_int!(u16);
|
|
impl_numeric_for_primitive_int!(u32);
|
|
impl_numeric_for_primitive_int!(u64);
|
|
impl_numeric_for_primitive_int!(u128);
|
|
impl_numeric_for_primitive_int!(usize);
|
|
impl_numeric_for_primitive_int!(i8);
|
|
impl_numeric_for_primitive_int!(i16);
|
|
impl_numeric_for_primitive_int!(i32);
|
|
impl_numeric_for_primitive_int!(i64);
|
|
impl_numeric_for_primitive_int!(i128);
|
|
impl_numeric_for_primitive_int!(isize);
|
|
impl_numeric_for_primitive_float!(f32);
|
|
impl_numeric_for_primitive_float!(f64);
|
|
|
|
impl Integer for u8 {}
|
|
impl Integer for u16 {}
|
|
impl Integer for u32 {}
|
|
impl Integer for u64 {}
|
|
impl Integer for u128 {}
|
|
impl Integer for usize {}
|
|
impl Integer for i8 {}
|
|
impl Integer for i16 {}
|
|
impl Integer for i32 {}
|
|
impl Integer for i64 {}
|
|
impl Integer for i128 {}
|
|
impl Integer for isize {}
|
|
|
|
impl Float for f32 {}
|
|
impl Float for f64 {}
|
|
|
|
impl Signed for i8 {}
|
|
impl Signed for i16 {}
|
|
impl Signed for i32 {}
|
|
impl Signed for i64 {}
|
|
impl Signed for i128 {}
|
|
impl Signed for isize {}
|
|
impl Signed for f32 {}
|
|
impl Signed for f64 {}
|
|
|
|
impl Unsigned for u8 {}
|
|
impl Unsigned for u16 {}
|
|
impl Unsigned for u32 {}
|
|
impl Unsigned for u64 {}
|
|
impl Unsigned for u128 {}
|
|
impl Unsigned for usize {}
|
|
|
|
macro_rules! impl_unit_isqrt_unit {
|
|
($unit:ty) => {
|
|
impl SqrtUnit for $unit {
|
|
fn sqrt_unit(self) -> Self {
|
|
self.isqrt()
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! impl_unit_sqrt_unit {
|
|
($unit:ty) => {
|
|
impl SqrtUnit for $unit {
|
|
fn sqrt_unit(self) -> Self {
|
|
self.sqrt()
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! impl_sqrt_real {
|
|
($unit:ty) => {
|
|
impl SqrtReal for $unit {
|
|
fn sqrt_real(self) -> f64 {
|
|
Into::<f64>::into(self).sqrt()
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
impl_unit_isqrt_unit!(u8);
|
|
impl_unit_isqrt_unit!(u16);
|
|
impl_unit_isqrt_unit!(u32);
|
|
impl_unit_isqrt_unit!(u64);
|
|
impl_unit_isqrt_unit!(u128);
|
|
impl_unit_isqrt_unit!(usize);
|
|
impl_unit_isqrt_unit!(i8);
|
|
impl_unit_isqrt_unit!(i16);
|
|
impl_unit_isqrt_unit!(i32);
|
|
impl_unit_isqrt_unit!(i64);
|
|
impl_unit_isqrt_unit!(i128);
|
|
impl_unit_isqrt_unit!(isize);
|
|
impl_unit_sqrt_unit!(f32);
|
|
impl_unit_sqrt_unit!(f64);
|
|
|
|
impl_sqrt_real!(u8);
|
|
impl_sqrt_real!(u16);
|
|
impl_sqrt_real!(u32);
|
|
impl_sqrt_real!(i8);
|
|
impl_sqrt_real!(i16);
|
|
impl_sqrt_real!(i32);
|
|
impl_sqrt_real!(f32);
|
|
impl_sqrt_real!(f64);
|
|
|
|
macro_rules! impl_widen_into {
|
|
($from:ty => [$($to:ty),+]) => {
|
|
$(
|
|
impl WidenInto<$to> for $from { fn widen_into(self) -> $to { self as $to } }
|
|
)+
|
|
};
|
|
}
|
|
|
|
macro_rules! impl_widen {
|
|
($from:ty => $to:ty) => {
|
|
impl Widen for $from {
|
|
type Target=$to;
|
|
|
|
fn widen(self) -> $to {
|
|
self as $to
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
impl_widen!(u8 => u16);
|
|
impl_widen!(u16 => u32);
|
|
impl_widen!(u32 => u64);
|
|
impl_widen!(u64 => u128);
|
|
impl_widen!(i8 => i16);
|
|
impl_widen!(i16 => i32);
|
|
impl_widen!(i32 => i64);
|
|
impl_widen!(i64 => i128);
|
|
impl_widen!(f32 => f64);
|
|
|
|
// Additional widen options for the primitive types
|
|
impl_widen_into!(u8 => [u32, u64, u128, usize]);
|
|
impl_widen_into!(u16 => [u64, u128, usize]);
|
|
impl_widen_into!(u32 => [u128, usize]);
|
|
impl_widen_into!(u64 => [usize]);
|
|
impl_widen_into!(i8 => [i32, i64, i128, isize]);
|
|
impl_widen_into!(i16 => [i64, i128, isize]);
|
|
impl_widen_into!(i32 => [i128, isize]);
|
|
impl_widen_into!(i64 => [isize]);
|