use paste::paste;
use crate::muldiv::MulDiv;
use crate::typenum::{NInt, NonZero, Unsigned, U10};
use crate::Fix;
pub trait FixExt: Sized {
const ONE: Self;
}
macro_rules! impl_fix_ext {
($bits:ident) => {
paste! {
impl<U> FixExt for Fix<$bits, U10, NInt<U>>
where
U: Unsigned + NonZero,
{
const ONE: Self =
Fix::constant((10 as $bits).pow(U::U32));
}
}
};
}
impl_fix_ext!(u8);
impl_fix_ext!(u16);
impl_fix_ext!(u32);
impl_fix_ext!(u64);
impl_fix_ext!(u128);
impl_fix_ext!(usize);
impl_fix_ext!(i8);
impl_fix_ext!(i16);
impl_fix_ext!(i32);
impl_fix_ext!(i64);
impl_fix_ext!(i128);
impl_fix_ext!(isize);
impl<Bits, Base, Exp> Fix<Bits, Base, Exp>
where
Self: FixExt,
{
#[must_use]
pub const fn one() -> Self {
<Self as FixExt>::ONE
}
}
impl<Bits, Exp> Fix<Bits, U10, Exp>
where
Self: FixExt,
Bits: MulDiv<Output = Bits>,
{
pub fn checked_convert<ToExp>(self) -> Option<Fix<Bits, U10, ToExp>>
where
Fix<Bits, U10, ToExp>: FixExt,
{
let target_one = Fix::<Bits, U10, ToExp>::one();
let source_one = Self::one();
target_one.mul_div_floor(self, source_one)
}
}