Files
GeometryLibrary/src/traits/primitives.rs
2025-05-05 13:59:13 -04:00

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]);