fastnum/bint/int/impls/
cast.rs1use crate::{
2 bint::{intrinsics, Int, ParseError, UInt},
3 utils::const_generics::{Dimension, Narrow, Widen},
4 Cast, TryCast,
5};
6
7impl<const N: usize, const M: usize> Cast<Int<N>> for Int<M>
8where
9 Dimension<N, M>: Widen,
10{
11 #[inline(always)]
12 fn cast(self) -> Int<N> {
13 #[allow(unsafe_code)]
16 unsafe {
17 self._transmute()
18 }
19 }
20}
21
22impl<const N: usize, const M: usize> TryCast<Int<N>> for Int<M>
23where
24 Dimension<N, M>: Narrow,
25{
26 type Error = ParseError;
27
28 #[inline(always)]
29 fn try_cast(self) -> Result<Int<N>, Self::Error> {
30 let bits = self.to_bits();
34 let digits = bits.digits();
35
36 let sign_digit = digits[N - 1];
39 let expected_digit = ((sign_digit as i64) >> 63) as u64;
41
42 let mut i = N;
44 while i < M {
45 if digits[i] != expected_digit {
46 return Err(ParseError::PosOverflow);
47 }
48 i += 1;
49 }
50
51 #[allow(unsafe_code)]
55 unsafe {
56 let narrow_digits = intrinsics::_transmute::<M, N, N>(digits);
57 Ok(Int::from_digits(narrow_digits))
58 }
59 }
60}
61
62impl<const N: usize, const M: usize> TryCast<UInt<N>> for Int<M> {
63 type Error = ParseError;
64
65 #[inline(always)]
66 fn try_cast(self) -> Result<UInt<N>, Self::Error> {
67 if self.is_negative() {
68 Err(ParseError::Signed)
69 } else if self.bits() <= Int::<N>::BITS {
70 #[allow(unsafe_code)]
73 {
74 Ok(unsafe { self._transmute() }.to_bits())
75 }
76 } else {
77 Err(ParseError::PosOverflow)
78 }
79 }
80}