reweb3_num/bint/
convert.rs1macro_rules! from_int {
2 ($BInt: ident, $Digit: ident; $($int: tt),*) => {
3 $(impl_const! {
4 impl<const N: usize> const From<$int> for $BInt<N> {
5 #[inline]
6 fn from(int: $int) -> Self {
7 let mut out = if int.is_negative() {
8 !Self::ZERO
9 } else {
10 Self::ZERO
11 };
12 let mut i = 0;
13 while i << crate::digit::$Digit::BIT_SHIFT < $int::BITS as usize {
14 let d = (int >> (i << crate::digit::$Digit::BIT_SHIFT)) as $Digit;
15 out.bits.digits[i] = d;
16 i += 1;
17 }
18 out
19 }
20 }
21 })*
22 }
23}
24
25macro_rules! from_uint {
26 ($BInt: ident, $BUint: ident; $($from: tt), *) => {
27 $(impl_const! {
28 impl<const N: usize> const From<$from> for $BInt<N> {
29 #[inline]
30 fn from(int: $from) -> Self {
31 let out = Self::from_bits($BUint::from(int));
32 out
33 }
34 }
35 })*
36 }
37}
38
39macro_rules! int_try_from_bint {
40 { $BInt: ident, $Digit: ident; $($int: ty), * } => {
41 $(crate::nightly::impl_const! {
42 impl<const N: usize> const TryFrom<$BInt<N>> for $int {
43 type Error = TryFromIntError;
44
45 fn try_from(int: $BInt<N>) -> Result<$int, Self::Error> {
46 let neg = int.is_negative();
47 let (mut out, padding) = if neg {
48 (-1, $Digit::MAX)
49 } else {
50 (0, $Digit::MIN)
51 };
52 let mut i = 0;
53 if $Digit::BITS > <$int>::BITS {
54 let small = int.bits.digits[i] as $int;
55 let trunc = small as $Digit;
56 if int.bits.digits[i] != trunc {
57 return Err(TryFromIntError(()));
58 }
59 out = small;
60 i = 1;
61 } else {
62 if neg {
63 loop {
64 let shift = i << digit::$Digit::BIT_SHIFT;
65 if i >= N || shift >= <$int>::BITS as usize {
66 break;
67 }
68 out &= !((!int.bits.digits[i]) as $int << shift);
69 i += 1;
70 }
71 } else {
72 loop {
73 let shift = i << digit::$Digit::BIT_SHIFT;
74 if i >= N || shift >= <$int>::BITS as usize {
75 break;
76 }
77 out |= int.bits.digits[i] as $int << shift;
78 i += 1;
79 }
80 }
81 }
82
83 while i < N {
84 if int.bits.digits[i] != padding {
85 return Err(TryFromIntError(()));
86 }
87 i += 1;
88 }
89
90 if out.is_negative() != neg {
91 return Err(TryFromIntError(()));
92 }
93
94 Ok(out)
95 }
96 }
97 })*
98 };
99}
100
101macro_rules! uint_try_from_bint {
102 ($BInt: ident; $($uint: ty), *) => {
103 $(crate::nightly::impl_const! {
104 impl<const N: usize> const TryFrom<$BInt<N>> for $uint {
105 type Error = TryFromIntError;
106
107 #[inline]
108 fn try_from(int: $BInt<N>) -> Result<$uint, Self::Error> {
109 if int.is_negative() {
110 Err(TryFromIntError(()))
111 } else {
112 <$uint>::try_from(int.bits)
113 }
114 }
115 }
116 })*
117 };
118}
119
120use crate::cast::CastFrom;
121use crate::digit;
122use crate::errors::{ParseIntError, TryFromIntError};
123use crate::nightly::impl_const;
124use core::str::FromStr;
125
126macro_rules! convert {
127 ($BUint: ident, $BInt: ident, $Digit: ident) => {
128 impl<const N: usize> FromStr for $BInt<N> {
129 type Err = ParseIntError;
130
131 #[inline]
132 fn from_str(src: &str) -> Result<Self, Self::Err> {
133 Self::from_str_radix(src, 10)
134 }
135 }
136
137 from_int!($BInt, $Digit; i8, i16, i32, i64, i128, isize);
138
139 from_uint!($BInt, $BUint; u8, u16, u32, u64, u128, usize);
140
141 impl_const! {
142 impl<const N: usize> const From<bool> for $BInt<N> {
143 #[inline]
144 fn from(small: bool) -> Self {
145 Self::cast_from(small)
146 }
147 }
148 }
149
150 int_try_from_bint!($BInt, $Digit; i8, i16, i32, i64, i128, isize);
151 uint_try_from_bint!($BInt; u8, u16, u32, u64, u128, usize);
152
153 };
169}
170
171crate::macro_impl!(convert);