1use 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 #[doc = "`" $t "` tuple."]
45 #[doc = "`" $t "` will have the same methods and traits as"]
49 #[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 #[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 #[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 #[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 #[must_use]
477 #[inline]
478 pub fn is_positive(self) -> bool {
479 self.0.is_positive()
480 }
481
482 #[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}