1use paste::paste;
2
3use crate::muldiv::MulDiv;
4use crate::typenum::{NInt, NonZero, Unsigned, U10};
5use crate::Fix;
6
7pub trait FixExt: Sized {
9 const ONE: Self;
11}
12
13macro_rules! impl_fix_ext {
14 ($bits:ident) => {
15 paste! {
16 impl<U> FixExt for Fix<$bits, U10, NInt<U>>
17 where
18 U: Unsigned + NonZero,
19 {
20 const ONE: Self =
21 Fix::constant((10 as $bits).pow(U::U32));
22 }
23 }
24 };
25}
26
27impl_fix_ext!(u8);
28impl_fix_ext!(u16);
29impl_fix_ext!(u32);
30impl_fix_ext!(u64);
31impl_fix_ext!(u128);
32impl_fix_ext!(usize);
33impl_fix_ext!(i8);
34impl_fix_ext!(i16);
35impl_fix_ext!(i32);
36impl_fix_ext!(i64);
37impl_fix_ext!(i128);
38impl_fix_ext!(isize);
39
40impl<Bits, Base, Exp> Fix<Bits, Base, Exp>
41where
42 Self: FixExt,
43{
44 #[must_use]
46 pub const fn one() -> Self {
47 <Self as FixExt>::ONE
48 }
49}
50
51impl<Bits, Exp> Fix<Bits, U10, Exp>
52where
53 Self: FixExt,
54 Bits: MulDiv<Output = Bits>,
55{
56 pub fn checked_convert<ToExp>(self) -> Option<Fix<Bits, U10, ToExp>>
65 where
66 Fix<Bits, U10, ToExp>: FixExt,
67 {
68 let target_one = Fix::<Bits, U10, ToExp>::one();
69 let source_one = Self::one();
70 target_one.mul_div_floor(self, source_one)
71 }
72}