radix_common/math/
bnum_integer.rs

1//! Definitions of safe integers and uints.
2
3use crate::math::traits::*;
4#[cfg(feature = "fuzzing")]
5use arbitrary::Arbitrary;
6use bnum::{BInt, BUint};
7use num_bigint::BigInt;
8use num_integer::Roots;
9use num_traits::{FromPrimitive, One, Pow, ToPrimitive, Zero};
10use paste::paste;
11use sbor::rust::cmp::{Ord, PartialEq, PartialOrd};
12use sbor::rust::convert::{From, TryFrom};
13use sbor::rust::fmt;
14use sbor::rust::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign};
15use sbor::rust::ops::{BitXor, BitXorAssign, Div, DivAssign};
16use sbor::rust::ops::{Mul, MulAssign, Neg, Not, Rem, RemAssign};
17use sbor::rust::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
18use sbor::rust::str::FromStr;
19use sbor::rust::string::*;
20use sbor::rust::vec::Vec;
21#[cfg(feature = "fuzzing")]
22use serde::{Deserialize, Serialize};
23
24pub mod bits;
25pub mod convert;
26pub mod test;
27pub mod test_macros;
28
29macro_rules! types {
30    ($($t:ident, $wrap:ty),*) => {
31        paste!{
32            $(
33                /// Provides safe integer arithmetic.
34                ///
35                /// Operations like `+`, '-', '*', or '/' sometimes produce overflow
36                /// which is detected and results in a panic, in of silently
37                /// wrapping around.
38                ///
39                /// The bit length of output type will be the greater one in the math operation,
40                /// and if any of the types was signed, then the resulting type will be signed too,
41                /// otherwise the output type is unsigned.
42                ///
43                /// The underlying value can be retrieved through the `.0` index of the
44                #[doc = "`" $t "` tuple."]
45                ///
46                /// # Layout
47                ///
48                #[doc = "`" $t "` will have the same methods and traits as"]
49                /// the built-in counterpart.
50                #[cfg_attr(feature = "fuzzing", derive(Arbitrary, Serialize, Deserialize))]
51                #[derive(Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
52                #[repr(transparent)]
53                pub struct $t(pub $wrap);
54
55                impl $t {
56                    pub const MIN: Self = Self($wrap::MIN);
57                    pub const MAX: Self = Self($wrap::MAX);
58                    pub const ZERO: Self = Self($wrap::ZERO);
59                    pub const ONE: Self = Self($wrap::ONE);
60                    pub const TEN: Self = Self($wrap::TEN);
61                    pub const BITS: u32 = $wrap::BITS as u32;
62                    pub const BYTES: u32 = $wrap::BYTES as u32;
63                    pub const N: usize = ($wrap::BYTES / 8) as usize;
64                }
65
66                impl Default for $t {
67                    fn default() -> Self {
68                        Self::ZERO
69                    }
70                }
71
72                impl fmt::Debug for $t {
73                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74                        self.0.fmt(f)
75                    }
76                }
77
78                impl fmt::Display for $t {
79                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80                        self.0.fmt(f)
81                    }
82                }
83
84                impl Zero for $t {
85                    fn zero() -> Self {
86                        Self::ZERO
87                    }
88
89                    fn is_zero(&self) -> bool {
90                        $wrap::ZERO == self.0
91                    }
92
93                    fn set_zero(&mut self) {
94                        self.0 = $wrap::ZERO;
95                    }
96                }
97
98                impl One for $t {
99                    fn one() -> Self {
100                        Self::ONE
101                    }
102                }
103            )*
104        }
105    };
106}
107types! {
108    I192, BInt::<3>,
109    I256, BInt::<4>,
110    I320, BInt::<5>,
111    I384, BInt::<6>,
112    I448, BInt::<7>,
113    I512, BInt::<8>,
114    I768, BInt::<12>,
115    U192, BUint::<3>,
116    U256, BUint::<4>,
117    U320, BUint::<5>,
118    U384, BUint::<6>,
119    U448, BUint::<7>,
120    U512, BUint::<8>,
121    U768, BUint::<12>
122}
123
124pub trait Sqrt {
125    fn sqrt(self) -> Self;
126}
127
128pub trait Cbrt {
129    fn cbrt(self) -> Self;
130}
131
132pub trait NthRoot {
133    fn nth_root(self, n: u32) -> Self;
134}
135
136macro_rules! forward_ref_unop {
137    (impl $imp:ident, $method:ident for $t:ty) => {
138        impl $imp for &$t {
139            type Output = <$t as $imp>::Output;
140
141            #[inline]
142            fn $method(self) -> <$t as $imp>::Output {
143                $imp::$method(*self)
144            }
145        }
146    };
147}
148
149macro_rules! forward_ref_binop {
150    (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
151        impl<'a> $imp<$u> for &'a $t {
152            type Output = <$t as $imp<$u>>::Output;
153
154            #[inline]
155            fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
156                $imp::$method(*self, other)
157            }
158        }
159
160        impl $imp<&$u> for $t {
161            type Output = <$t as $imp<$u>>::Output;
162
163            #[inline]
164            fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
165                $imp::$method(self, *other)
166            }
167        }
168
169        impl $imp<&$u> for &$t {
170            type Output = <$t as $imp<$u>>::Output;
171
172            #[inline]
173            fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
174                $imp::$method(*self, *other)
175            }
176        }
177    };
178}
179
180macro_rules! forward_ref_op_assign {
181    (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
182        impl $imp<&$u> for $t {
183            #[inline]
184            fn $method(&mut self, other: &$u) {
185                $imp::$method(self, *other);
186            }
187        }
188    };
189}
190
191macro_rules! op_impl {
192    ($($t:ty),*) => {
193        paste! {
194            $(
195                impl Add for $t {
196                    type Output = $t;
197
198                    #[inline]
199                    fn add(self, other: $t) -> Self {
200                        Self(self.0.checked_add(other.0).expect("Overflow"))
201                    }
202                }
203                forward_ref_binop! { impl Add, add for $t, $t }
204
205                impl AddAssign for $t {
206                    #[inline]
207                    fn add_assign(&mut self, other: $t) {
208                        self.0 = self.0.checked_add(other.0).expect("Overflow");
209                    }
210                }
211                forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
212
213                impl Sub for $t {
214                    type Output = $t;
215
216                    #[inline]
217                    fn sub(self, other: $t) -> Self {
218                        Self(self.0.checked_sub(other.0).expect("Overflow"))
219                    }
220                }
221                forward_ref_binop! { impl Sub, sub for $t, $t }
222
223                impl SubAssign for $t {
224                    #[inline]
225                    fn sub_assign(&mut self, other: $t) {
226                        self.0 = self.0.checked_sub(other.0).expect("Overflow");
227                    }
228                }
229                forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
230
231                impl Mul for $t {
232                    type Output = $t;
233
234                    #[inline]
235                    fn mul(self, other: $t) -> Self {
236                        Self(self.0.checked_mul(other.0).expect("Overflow"))
237                    }
238                }
239                forward_ref_binop! { impl Mul, mul for $t, $t }
240
241                impl MulAssign for $t {
242                    #[inline]
243                    fn mul_assign(&mut self, other: $t) {
244                        self.0 = self.0.checked_mul(other.0).expect("Overflow");
245                    }
246                }
247                forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
248
249                impl Div for $t {
250                    type Output = $t;
251
252                    #[inline]
253                    fn div(self, other: $t) -> Self {
254                        Self(self.0.checked_div(other.0).expect("Overflow"))
255                    }
256                }
257                forward_ref_binop! { impl Div, div for $t, $t }
258
259                impl DivAssign for $t {
260                    #[inline]
261                    fn div_assign(&mut self, other: $t) {
262                        self.0 = self.0.checked_div(other.0).expect("Overflow");
263                    }
264                }
265                forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
266
267                impl Rem for $t {
268                    type Output = $t;
269
270                    #[inline]
271                    fn rem(self, other: $t) -> Self {
272                        Self(self.0 % other.0)
273                    }
274                }
275                forward_ref_binop! { impl Rem, rem for $t, $t }
276
277                impl RemAssign for $t {
278                    #[inline]
279                    fn rem_assign(&mut self, other: $t) {
280                        self.0 = self.0 % other.0;
281                    }
282                }
283                forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
284
285                impl Not for $t {
286                    type Output = $t;
287
288                    #[inline]
289                    fn not(self) -> Self {
290                        Self(!self.0)
291                    }
292                }
293                forward_ref_unop! { impl Not, not for $t }
294
295                impl Pow<u32> for $t
296                {
297                    type Output = $t;
298
299                    /// Raises self to the power of `exp`, using exponentiation by squaring.
300                    ///
301                    #[inline]
302                    #[must_use = "this returns the result of the operation, \
303                          without modifying the original"]
304                    fn pow(self, exp: u32) -> Self {
305                        Self(self.0.checked_pow(exp).expect("Overflow"))
306                    }
307                }
308
309                impl Sqrt for $t
310                {
311                    fn sqrt(self) -> Self {
312                        Self(self.0.sqrt())
313                    }
314                }
315
316                impl Cbrt for $t
317                {
318                    fn cbrt(self) -> Self {
319                        Self(self.0.cbrt())
320                    }
321                }
322
323                impl NthRoot for $t
324                {
325                    fn nth_root(self, n: u32) -> Self {
326                        Self(self.0.nth_root(n))
327                    }
328                }
329
330                impl CheckedAdd for $t
331                {
332                    type Output = $t;
333
334                    fn checked_add(self, other: Self) -> Option<Self::Output> {
335                        let opt = self.0.checked_add(other.0);
336                        opt.map(|v| Self(v))
337                    }
338                }
339
340                impl SaturatingAdd for $t
341                {
342                    type Output = $t;
343
344                    fn saturating_add(self, other: Self) -> Self::Output {
345                        Self(self.0.saturating_add(other.0))
346                    }
347                }
348
349                impl CheckedSub for $t
350                {
351                    type Output = $t;
352
353                    fn checked_sub(self, other: Self) -> Option<Self::Output> {
354                        let opt = self.0.checked_sub(other.0);
355                        opt.map(|v| Self(v))
356                    }
357                }
358
359                impl CheckedMul for $t
360                {
361                    type Output = $t;
362
363                    fn checked_mul(self, other: Self) -> Option<Self::Output> {
364                        let opt = self.0.checked_mul(other.0);
365                        opt.map(|v| Self(v))
366                    }
367                }
368
369                impl CheckedDiv for $t
370                {
371                    type Output = $t;
372
373                    fn checked_div(self, other: Self) -> Option<Self::Output> {
374                        let opt = self.0.checked_div(other.0);
375                        opt.map(|v| Self(v))
376                    }
377                }
378            )*
379        }
380    };
381}
382op_impl! { I192 }
383op_impl! { I256 }
384op_impl! { I320 }
385op_impl! { I384 }
386op_impl! { I448 }
387op_impl! { I512 }
388op_impl! { I768 }
389op_impl! { U192 }
390op_impl! { U256 }
391op_impl! { U320 }
392op_impl! { U384 }
393op_impl! { U448 }
394op_impl! { U512 }
395op_impl! { U768 }
396
397macro_rules! op_impl_unsigned {
398    ($($t:ty),*) => {
399        paste! {
400            $(
401                impl $t {
402                    pub fn is_power_of_two(self) -> bool {
403                        self.0.is_power_of_two()
404                    }
405
406                    pub fn next_power_of_two(self) -> Self {
407                        Self(self.0.checked_next_power_of_two().expect("Overflow"))
408                    }
409                }
410            )*
411        }
412    };
413}
414op_impl_unsigned! { U192 }
415op_impl_unsigned! { U256 }
416op_impl_unsigned! { U320 }
417op_impl_unsigned! { U384 }
418op_impl_unsigned! { U448 }
419op_impl_unsigned! { U512 }
420op_impl_unsigned! { U768 }
421
422macro_rules! op_impl_signed {
423    ($($t:ty),*) => {
424        paste! {
425            $(
426                impl Neg for $t {
427                    type Output = Self;
428                    #[inline]
429                    fn neg(self) -> Self {
430                        Self(self.0.neg())
431                    }
432                }
433
434                impl CheckedNeg for $t {
435                    type Output = Self;
436
437                    #[inline]
438                    fn checked_neg(self) -> Option<Self::Output> {
439                        let c = self.0.checked_neg();
440                        c.map(Self)
441                    }
442                }
443
444
445                impl $t {
446
447                    /// Computes the absolute value of `self`, with overflow causing panic.
448                    ///
449                    /// The only case where such overflow can occur is when one takes the absolute value of the negative
450                    /// minimal value for the type this is a positive value that is too large to represent in the type. In
451                    /// such a case, this function panics.
452                    ///
453                    #[inline]
454                    #[must_use = "this returns the result of the operation, \
455                      without modifying the original"]
456                    pub fn abs(self) -> Self {
457                        Self(self.0.abs())
458                    }
459
460                    /// Returns a number representing sign of `self`.
461                    ///
462                    ///  - `0` if the number is zero
463                    ///  - `1` if the number is positive
464                    ///  - `-1` if the number is negative
465                    ///
466                    #[inline]
467                    #[must_use = "this returns the result of the operation, \
468                          without modifying the original"]
469                    pub fn signum(self) -> Self {
470                        Self(self.0.signum())
471                    }
472
473                    /// Returns `true` if `self` is positive and `false` if the number is zero or
474                    /// negative.
475                    ///
476                    #[must_use]
477                    #[inline]
478                    pub fn is_positive(self) -> bool {
479                        self.0.is_positive()
480                    }
481
482                    /// Returns `true` if `self` is negative and `false` if the number is zero or
483                    /// positive.
484                    ///
485                    #[must_use]
486                    #[inline]
487                    pub fn is_negative(self) -> bool {
488                        self.0.is_negative()
489                    }
490                }
491            )*
492        }
493    }
494}
495
496op_impl_signed! { I192 }
497op_impl_signed! { I256 }
498op_impl_signed! { I320 }
499op_impl_signed! { I384 }
500op_impl_signed! { I448 }
501op_impl_signed! { I512 }
502op_impl_signed! { I768 }
503
504macro_rules! error {
505    ($($t:ident),*) => {
506        paste! {
507            $(
508                #[derive(Debug, Clone, PartialEq, Eq)]
509                pub enum [<Parse $t Error>] {
510                    NegativeToUnsigned,
511                    InvalidLength,
512                    InvalidDigit,
513                    Empty,
514                    Overflow,
515                }
516
517                #[cfg(not(feature = "alloc"))]
518                impl std::error::Error for [<Parse $t Error>] {}
519
520                #[cfg(not(feature = "alloc"))]
521                impl fmt::Display for [<Parse $t Error>] {
522                    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
523                        write!(f, "{:?}", self)
524                    }
525                }
526            )*
527        }
528    };
529}
530error! {
531    I192,
532    I256,
533    I320,
534    I384,
535    I448,
536    I512,
537    I768,
538    U192,
539    U256,
540    U320,
541    U384,
542    U448,
543    U512,
544    U768
545}