pub trait Cast { fn to(val: T) -> Self; } pub use half::f16; pub mod matrix; macro_rules! to_int { ($t: ty, $($f: ty),+) => { $(impl Cast<$f> for $t { fn to(v: $f) -> Self { #[cfg(debug_assertions)] { <$t>::try_from(v).unwrap_or_else(|_| ERROR!("Error casting {v} to {}", stringify!($t))) } #[cfg(not(debug_assertions))] { v as $t } } })+ }; } macro_rules! to_float { ($t: ty, $($f: ty),+) => { $(impl Cast<$f> for $t { fn to(v: $f) -> Self { ASSERT!( v.trunc() >= Self::MIN as $f && v.trunc() <= Self::MAX as $f, "Error casting {v} to {}", super::super::pre::type_name::() ); unsafe { v.to_int_unchecked() } } })+ }; } macro_rules! impl_self { ($t: ty, $($f: ty),+) => { $(impl Cast<$f> for $t { fn to(v: $f) -> Self { v as Self } })+ }; } macro_rules! impl_to_half { ($($t: ty),+) => { $(impl Cast<$t> for f16 { fn to(v: $t) -> f16 { f16::from_f32(v as f32) } })+ }; } macro_rules! impl_from_half { ($($t: ty),+) => { $(impl Cast for $t { fn to(v: f16) -> Self { Self::to(v.to_f32()) } })+ }; } macro_rules! impl_cast { ($($t: ty),+) => { $( to_int!($t, bool, u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize); to_float!($t, f32, f64); impl_from_half!($t); impl_to_half!($t); impl_self!(f32, $t); impl_self!(f64, $t); )+ }; } impl_cast!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize); impl_self!(f32, f32, f64); impl_self!(f64, f32, f64); impl_self!(f16, f16); impl_from_half!(f32); impl_to_half!(f32); impl Cast for f64 { fn to(v: f16) -> Self { v.to_f64() } } impl Cast for f16 { fn to(v: f64) -> Self { Self::from_f64(v) } } impl Cast for f16 { fn to(v: bool) -> Self { Self::from_f32(v as u32 as f32) } } impl Cast for f32 { fn to(v: bool) -> Self { v as u32 as Self } } impl Cast for f64 { fn to(v: bool) -> Self { v as u32 as Self } } mod nalgebra; mod tuples;