Fri, 13 Oct 2023 13:32:46 -0500
feature(binary_heap_retain) is stable now
/*! Some useful (numerical) types and traits. The traits are based on corresponding ones in [`num_traits`], but try to fill some gaps in the super-traits and available constants. As [`nalgebra`] unnecessarily provides many of the same methods as [`num_traits`], to avoid having to refer to the methods with the full path, it is often necesary to use [`ToNalgebraRealField`][crate::nalgebra_support::ToNalgebraRealField] to hide the nalgebra implementations until absolutely necessary to use nalgebra. */ //use trait_set::trait_set; pub use num_traits::Float as NumTraitsFloat; // needed to re-export functions. pub use num_traits::cast::AsPrimitive; /// Typical integer type #[allow(non_camel_case_types)] pub type int = i64; /// Typical unsigned integer type #[allow(non_camel_case_types)] pub type uint = u64; /// Typical floating point number type #[allow(non_camel_case_types)] pub type float = f64; /// Casts of abstract numerical types to others via the standard `as` keyword. pub trait CastFrom<T : 'static + Copy> : num_traits::cast::AsPrimitive<T> { fn cast_from(other : T) -> Self; } macro_rules! impl_casts { ($($type:ty)*) => { $( impl_casts!(@phase2, $type, u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64); )* }; (@phase2, $type:ty, $($type2:ty)*) => { $( impl CastFrom<$type2> for $type { #[inline] fn cast_from(other : $type2) -> Self { other as $type } } )* }; } impl_casts!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64); /// Trait for general numeric types pub trait Num : 'static + Copy + Sync + Send + num::Num + num_traits::NumAssign + std::iter::Sum + std::iter::Product + std::fmt::Debug + std::fmt::Display + serde::Serialize + CastFrom<u8> + CastFrom<u16> + CastFrom<u32> + CastFrom<u64> + CastFrom<u128> + CastFrom<usize> + CastFrom<i8> + CastFrom<i16> + CastFrom<i32> + CastFrom<i64> + CastFrom<i128> + CastFrom<isize> + CastFrom<f32> + CastFrom<f64> { const ZERO : Self; const ONE : Self; const TWO : Self; /// Generic version of `Self::MAX` const RANGE_MAX : Self; /// Generic version of `Self::MIN` const RANGE_MIN : Self; } /// Trait for signed numeric types pub trait SignedNum : Num + num::Signed + std::ops::Neg<Output=Self> {} impl<U : Num + num::Signed + std::ops::Neg<Output=Self>> SignedNum for U { } /// Trait for floating point numbers pub trait Float : SignedNum + num::Float /*+ From<Self::CompatibleSize>*/ { // An unsigned integer that can be used for indexing operations and // converted to F without loss. //type CompatibleSize : CompatibleUnsigned<Self>; const PI : Self; const E : Self; const EPSILON : Self; const SQRT_2 : Self; const INFINITY : Self; const NEG_INFINITY : Self; const FRAC_2_SQRT_PI : Self; } /// Trait for integers pub trait Integer : Num + num::Integer {} /// Trait for unsigned integers pub trait Unsigned : Num + Integer + num::Unsigned {} /// Trait for signed integers pub trait Signed : SignedNum + Integer {} macro_rules! impl_num_consts { ($($type:ty)*) => { $( impl Num for $type { const ZERO : Self = 0 as $type; const ONE : Self = 1 as $type; const TWO : Self = 2 as $type; const RANGE_MAX : Self = <$type>::MAX; const RANGE_MIN : Self = <$type>::MIN; } )* } } macro_rules! impl_integers { ($signed:ty : $($type:ty)*) => { $( impl_num_consts!($type); impl Integer for $type {} impl $signed for $type {} )* } } impl_integers!(Signed: i8 i16 i32 i64 i128 isize); impl_integers!(Unsigned: u8 u16 u32 u64 u128 usize); impl_num_consts!(f32 f64); impl Float for f64 { /*#[cfg(any(target_pointer_width = "128", target_pointer_width = "64"))] type CompatibleSize = u32; #[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))] type CompatibleSize = usize;*/ const PI : Self = std::f64::consts::PI; const E : Self = std::f64::consts::E; const EPSILON : Self = std::f64::EPSILON; const SQRT_2 : Self = std::f64::consts::SQRT_2; const INFINITY : Self = std::f64::INFINITY; const NEG_INFINITY : Self = std::f64::NEG_INFINITY; const FRAC_2_SQRT_PI : Self = std::f64::consts::FRAC_2_SQRT_PI; } impl Float for f32 { /* #[cfg(any(target_pointer_width = "128", target_pointer_width = "64", target_pointer_width = "32"))] type CompatibleSize = u16; #[cfg(any(target_pointer_width = "16"))] type CompatibleSize = usize; */ const PI : Self = std::f32::consts::PI; const E : Self = std::f32::consts::E; const EPSILON : Self = std::f32::EPSILON; const SQRT_2 : Self = std::f32::consts::SQRT_2; const INFINITY : Self = std::f32::INFINITY; const NEG_INFINITY : Self = std::f32::NEG_INFINITY; const FRAC_2_SQRT_PI : Self = std::f32::consts::FRAC_2_SQRT_PI; } /* trait_set! { pub trait CompatibleUnsigned<F : Float> = Unsigned + Into<F>; pub trait CompatibleSigned<F : Float> = Signed + Into<F>; } */