reweb3_num/buint/
convert.rs1macro_rules! from_uint {
2 ($BUint: ident, $Digit: ident; $($uint: tt),*) => {
3 $(impl_const! {
4 impl<const N: usize> const From<$uint> for $BUint<N> {
5 #[inline]
6 fn from(int: $uint) -> Self {
7 const UINT_BITS: usize = $uint::BITS as usize;
8 let mut out = Self::ZERO;
9 let mut i = 0;
10 while i << crate::digit::$Digit::BIT_SHIFT < UINT_BITS {
11 let d = (int >> (i << crate::digit::$Digit::BIT_SHIFT)) as $Digit;
12 if d != 0 {
13 out.digits[i] = d;
14 }
15 i += 1;
16 }
17 out
18 }
19 }
20 })*
21 }
22}
23
24macro_rules! try_from_iint {
25 ($BUint: ident; $($int: tt -> $uint: tt),*) => {
26 $(impl_const! {
27 impl<const N: usize> const TryFrom<$int> for $BUint<N> {
28 type Error = TryFromIntError;
29
30 #[inline]
31 fn try_from(int: $int) -> Result<Self, Self::Error> {
32 if int.is_negative() {
33 return Err(TryFromIntError(()));
34 }
35 let bits = int as $uint;
36 Ok(Self::from(bits))
37 }
38 }
39 })*
40 }
41}
42
43macro_rules! try_from_buint {
44 ($BUint: ident, $Digit: ident; $($int: ty), *) => {
45 $(crate::nightly::impl_const! {
46 impl<const N: usize> const TryFrom<$BUint<N>> for $int {
47 type Error = TryFromIntError;
48
49 #[inline]
50 fn try_from(u: $BUint<N>) -> Result<$int, Self::Error> {
51 let mut out = 0;
52 let mut i = 0;
53 if $Digit::BITS > <$int>::BITS {
54 let small = u.digits[i] as $int;
55 let trunc = small as $Digit;
56 if u.digits[i] != trunc {
57 return Err(TryFromIntError(()));
58 }
59 out = small;
60 i = 1;
61 } else {
62 loop {
63 let shift = i << crate::digit::$Digit::BIT_SHIFT;
64 if i >= N || shift >= <$int>::BITS as usize {
65 break;
66 }
67 out |= u.digits[i] as $int << shift;
68 i += 1;
69 }
70 }
71
72 #[allow(unused_comparisons)]
73 if out < 0 {
74 return Err(TryFromIntError(()));
75 }
76
77 while i < N {
78 if u.digits[i] != 0 {
79 return Err(TryFromIntError(()));
80 }
81 i += 1;
82 }
83
84 Ok(out)
85 }
86 }
87 })*
88 };
89}
90
91macro_rules! uint_try_from_uint {
92 ($Trait: ident; $To: ident; $($From: ident $(<$N: ident>)?), *) => {
93 $(
94 impl<$(const $N: usize,)? const M: usize> $Trait<$From $(<$N>)?> for $To<M> {
95 type Error = TryFromIntError;
96
97 fn try_from(from: $From $(<$N>)?) -> Result<Self, Self::Error> {
98 if $From $(::<$N>)?::BITS <= Self::BITS || $From $(::<$N>)?::BITS - from.leading_zeros() <= Self::BITS {
99 Ok(Self::cast_from(from))
100 } else {
101 Err(TryFromIntError(()))
102 }
103 }
104 }
105 )*
106 };
107}
108
109macro_rules! uint_try_from_int {
110 ($Trait: ident; $To: ident; $($From: ident $(<$N: ident>)?), *) => {
111 $(
112 impl<$(const $N: usize,)? const M: usize> $Trait<$From $(<$N>)?> for $To<M> {
113 type Error = TryFromIntError;
114
115 fn try_from(from: $From $(<$N>)?) -> Result<Self, Self::Error> {
116 if from.is_negative() {
117 Err(TryFromIntError(()))
118 } else {
119 if $From $(::<$N>)?::BITS.saturating_sub(1) <= Self::BITS || $From $(::<$N>)?::BITS - from.leading_zeros() <= Self::BITS {
120 Ok(Self::cast_from(from))
121 } else {
122 Err(TryFromIntError(()))
123 }
124 }
125 }
126 }
127 )*
128 };
129}
130
131macro_rules! int_try_from_uint {
132 ($Trait: ident; $To: ident; $($From: ident $(<$N: ident>)?), *) => {
133 $(
134 impl<$(const $N: usize,)? const M: usize> $Trait<$From $(<$N>)?> for $To<M> {
135 type Error = TryFromIntError;
136
137 fn try_from(from: $From $(<$N>)?) -> Result<Self, Self::Error> {
138 if $From $(::<$N>)?::BITS <= Self::BITS - 1 || $From $(::<$N>)?::BITS - from.leading_zeros() <= Self::BITS - 1 { Ok(Self::cast_from(from))
140 } else {
141 Err(TryFromIntError(()))
142 }
143 }
144 }
145 )*
146 };
147}
148
149macro_rules! int_try_from_int {
150 ($Trait: ident; $To: ident; $($From: ident $(<$N: ident>)?), *) => {
151 $(
152 impl<$(const $N: usize,)? const M: usize> $Trait<$From $(<$N>)?> for $To<M> {
153 type Error = TryFromIntError;
154
155 fn try_from(from: $From $(<$N>)?) -> Result<Self, Self::Error> {
156 if $From $(::<$N>)?::BITS <= Self::BITS {
157 return Ok(Self::cast_from(from));
158 }
159 if from.is_negative() {
160 if $From $(::<$N>)?::BITS - from.leading_ones() <= Self::BITS - 1 {
161 Ok(Self::cast_from(from))
162 } else {
163 Err(TryFromIntError(()))
164 }
165 } else {
166 if $From $(::<$N>)?::BITS - from.leading_zeros() <= Self::BITS - 1 {
167 Ok(Self::cast_from(from))
168 } else {
169 Err(TryFromIntError(()))
170 }
171 }
172 }
173 }
174 )*
175 };
176}
177
178use crate::BTryFrom;
179
180macro_rules! mixed_try_from {
181 ($BUint: ident, $BInt: ident) => {
182 uint_try_from_uint!(BTryFrom; $BUint; BUint<N>, BUintD32<N>, BUintD16<N>, BUintD8<N>);
183 uint_try_from_int!(BTryFrom; $BUint; BInt<N>, BIntD32<N>, BIntD16<N>, BIntD8<N>);
184 int_try_from_uint!(BTryFrom; $BInt; BUint<N>, BUintD32<N>, BUintD16<N>, BUintD8<N>);
185 int_try_from_int!(BTryFrom; $BInt; BInt<N>, BIntD32<N>, BIntD16<N>, BIntD8<N>);
186 };
187}
188
189use crate::cast::CastFrom;
190use crate::errors::TryFromIntError;
191use crate::nightly::impl_const;
192
193macro_rules! convert {
194 ($BUint: ident, $BInt: ident, $Digit: ident) => {
195 impl_const! {
196 impl<const N: usize> const From<bool> for $BUint<N> {
197 #[inline]
198 fn from(small: bool) -> Self {
199 Self::cast_from(small)
200 }
201 }
202 }
203
204 impl_const! {
205 impl<const N: usize> const From<char> for $BUint<N> {
206 #[inline]
207 fn from(c: char) -> Self {
208 Self::cast_from(c)
209 }
210 }
211 }
212
213 from_uint!($BUint, $Digit; u8, u16, u32, u64, u128, usize);
214
215 try_from_iint!($BUint; i8 -> u8, i16 -> u16, i32 -> u32, isize -> usize, i64 -> u64, i128 -> u128);
216
217 try_from_buint!($BUint, $Digit; u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
218
219 mixed_try_from!($BUint, $BInt);
220
221 impl_const! {
222 impl<const N: usize> const From<[$Digit; N]> for $BUint<N> {
223 #[inline]
224 fn from(digits: [$Digit; N]) -> Self {
225 Self::from_digits(digits)
226 }
227 }
228 }
229
230 impl_const! {
231 impl<const N: usize> const From<$BUint<N>> for [$Digit; N] {
232 #[inline]
233 fn from(uint: $BUint<N>) -> Self {
234 uint.digits
235 }
236 }
237 }
238 };
239}
240
241crate::macro_impl!(convert);