fastnum/bint/uint/impls/
cast.rs

1use crate::{
2    bint::{Int, ParseError, UInt},
3    utils::const_generics::{Dimension, Narrow, Widen},
4    Cast, TryCast,
5};
6
7impl<const N: usize, const M: usize> Cast<UInt<N>> for UInt<M>
8where
9    Dimension<N, M>: Widen,
10{
11    #[inline(always)]
12    fn cast(self) -> UInt<N> {
13        // SAFETY: `N` is always greater or equal than `M`. So we can safely cast to the
14        // widest type.
15        #[allow(unsafe_code)]
16        unsafe {
17            self._transmute()
18        }
19    }
20}
21
22impl<const N: usize, const M: usize> Cast<Int<N>> for UInt<M>
23where
24    Dimension<N, M>: Widen,
25{
26    #[inline(always)]
27    fn cast(self) -> Int<N> {
28        // SAFETY: `N` is always greater or equal than `M`. So we can safely cast to the
29        // widest type.
30        #[allow(unsafe_code)]
31        {
32            Int::from_bits(unsafe { self._transmute() })
33        }
34    }
35}
36
37impl<const N: usize, const M: usize> TryCast<UInt<N>> for UInt<M>
38where
39    Dimension<N, M>: Narrow,
40{
41    type Error = ParseError;
42
43    #[inline(always)]
44    fn try_cast(self) -> Result<UInt<N>, Self::Error> {
45        if self.bits() <= UInt::<N>::BITS {
46            // SAFETY: UInt<M> is wider (`N` < `M`) but its value fit to UInt<N>. So we can
47            // safely cast to the narrow type.
48            #[allow(unsafe_code)]
49            {
50                Ok(unsafe { self._transmute() })
51            }
52        } else {
53            Err(ParseError::PosOverflow)
54        }
55    }
56}
57
58impl<const N: usize> TryCast<Int<N>> for UInt<N> {
59    type Error = ParseError;
60
61    #[inline(always)]
62    fn try_cast(self) -> Result<Int<N>, Self::Error> {
63        if self.bits() < Int::<N>::BITS {
64            Ok(Int::from_bits(self))
65        } else {
66            Err(ParseError::PosOverflow)
67        }
68    }
69}
70
71impl<const N: usize, const M: usize> TryCast<Int<N>> for UInt<M>
72where
73    Dimension<N, M>: Narrow,
74{
75    type Error = ParseError;
76
77    #[inline(always)]
78    fn try_cast(self) -> Result<Int<N>, Self::Error> {
79        if self.bits() < Int::<N>::BITS {
80            // SAFETY: UInt<M> is wider (`N` < `M`) but its value fit to Int<N>. So we can
81            // safely cast to the narrow type.
82            #[allow(unsafe_code)]
83            {
84                Ok(Int::from_bits(unsafe { self._transmute() }))
85            }
86        } else {
87            Err(ParseError::PosOverflow)
88        }
89    }
90}