pub use float::*;
pub use signed::*;
pub use unsigned::*;
mod float;
mod signed;
mod unsigned;
pub trait Numeric:
Sized
+ Copy
+ PartialEq
+ PartialOrd
+ CastFrom<Self>
+ bytemuck::Pod
+ std::fmt::Debug
+ Sync
+ Send
+ 'static
{
const BITS: usize;
const ZERO: Self;
const ONE: Self;
const TWO: Self;
const MAX: Self;
}
pub trait UnsignedNumeric: Numeric {
type NumericSignedType: SignedNumeric<NumericUnsignedType = Self> + CastFrom<Self>;
}
pub trait SignedNumeric: Numeric {
type NumericUnsignedType: UnsignedNumeric<NumericSignedType = Self> + CastFrom<Self>;
}
pub trait CastFrom<Input> {
fn cast_from(input: Input) -> Self;
}
pub trait CastInto<Output> {
fn cast_into(self) -> Output;
}
impl<Input, Output> CastInto<Output> for Input
where
Output: CastFrom<Input>,
{
fn cast_into(self) -> Output {
Output::cast_from(self)
}
}
macro_rules! implement_cast {
($Input:ty, {$($Output:ty),*}) => {
$(
impl CastFrom<$Input> for $Output {
#[inline]
fn cast_from(input: $Input) -> $Output {
input as $Output
}
}
)*
};
($Input: ty) => {
implement_cast!($Input, {f32, f64, usize, u8, u16, u32, u64, u128, isize, i8, i16, i32,
i64, i128});
};
($($Input: ty),*) => {
$(
implement_cast!($Input);
)*
}
}
implement_cast!(f32, f64, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize);
impl<Num> CastFrom<bool> for Num
where
Num: Numeric,
{
#[inline]
fn cast_from(input: bool) -> Num {
if input {
Num::ONE
} else {
Num::ZERO
}
}
}
pub trait OverflowingAdd<Rhs> {
type Output;
fn overflowing_add(self, other: Rhs) -> (Self::Output, bool);
}