1use crate::math::traits::*;
4
5use bnum::{BInt, BUint};
6use num_bigint::BigInt;
7use num_integer::Roots;
8use num_traits::{FromPrimitive, One, Pow, ToPrimitive, Zero};
9use paste::paste;
10use sbor::rust::cmp::{Ord, PartialEq, PartialOrd};
11use sbor::rust::convert::{From, TryFrom};
12use sbor::rust::fmt;
13use sbor::rust::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign};
14use sbor::rust::ops::{BitXor, BitXorAssign, Div, DivAssign};
15use sbor::rust::ops::{Mul, MulAssign, Neg, Not, Rem, RemAssign};
16use sbor::rust::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
17use sbor::rust::str::FromStr;
18use sbor::rust::string::*;
19use sbor::rust::vec::Vec;
20
21pub mod bits;
22pub mod convert;
23pub mod test;
24pub mod test_macros;
25
26macro_rules! types {
27 ($($t:ident, $wrap:ty),*) => {
28 paste!{
29 $(
30 #[doc = "`" $t "` tuple."]
42 #[doc = "`" $t "` will have the same methods and traits as"]
46 #[cfg_attr(
48 feature = "fuzzing",
49 derive(::arbitrary::Arbitrary, ::serde::Serialize, ::serde::Deserialize)
50 )]
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
303 fn pow(self, exp: u32) -> Self {
304 Self(self.0.checked_pow(exp).expect("Overflow"))
305 }
306 }
307
308 impl Sqrt for $t
309 {
310 fn sqrt(self) -> Self {
311 Self(self.0.sqrt())
312 }
313 }
314
315 impl Cbrt for $t
316 {
317 fn cbrt(self) -> Self {
318 Self(self.0.cbrt())
319 }
320 }
321
322 impl NthRoot for $t
323 {
324 fn nth_root(self, n: u32) -> Self {
325 Self(self.0.nth_root(n))
326 }
327 }
328
329 impl CheckedAdd for $t
330 {
331 type Output = $t;
332
333 fn checked_add(self, other: Self) -> Option<Self::Output> {
334 let opt = self.0.checked_add(other.0);
335 opt.map(|v| Self(v))
336 }
337 }
338
339 impl SaturatingAdd for $t
340 {
341 type Output = $t;
342
343 fn saturating_add(self, other: Self) -> Self::Output {
344 Self(self.0.saturating_add(other.0))
345 }
346 }
347
348 impl CheckedSub for $t
349 {
350 type Output = $t;
351
352 fn checked_sub(self, other: Self) -> Option<Self::Output> {
353 let opt = self.0.checked_sub(other.0);
354 opt.map(|v| Self(v))
355 }
356 }
357
358 impl CheckedMul for $t
359 {
360 type Output = $t;
361
362 fn checked_mul(self, other: Self) -> Option<Self::Output> {
363 let opt = self.0.checked_mul(other.0);
364 opt.map(|v| Self(v))
365 }
366 }
367
368 impl CheckedDiv for $t
369 {
370 type Output = $t;
371
372 fn checked_div(self, other: Self) -> Option<Self::Output> {
373 let opt = self.0.checked_div(other.0);
374 opt.map(|v| Self(v))
375 }
376 }
377 )*
378 }
379 };
380}
381op_impl! { I192 }
382op_impl! { I256 }
383op_impl! { I320 }
384op_impl! { I384 }
385op_impl! { I448 }
386op_impl! { I512 }
387op_impl! { I768 }
388op_impl! { U192 }
389op_impl! { U256 }
390op_impl! { U320 }
391op_impl! { U384 }
392op_impl! { U448 }
393op_impl! { U512 }
394op_impl! { U768 }
395
396macro_rules! op_impl_unsigned {
397 ($($t:ty),*) => {
398 paste! {
399 $(
400 impl $t {
401 pub fn is_power_of_two(self) -> bool {
402 self.0.is_power_of_two()
403 }
404
405 pub fn next_power_of_two(self) -> Self {
406 Self(self.0.checked_next_power_of_two().expect("Overflow"))
407 }
408 }
409 )*
410 }
411 };
412}
413op_impl_unsigned! { U192 }
414op_impl_unsigned! { U256 }
415op_impl_unsigned! { U320 }
416op_impl_unsigned! { U384 }
417op_impl_unsigned! { U448 }
418op_impl_unsigned! { U512 }
419op_impl_unsigned! { U768 }
420
421macro_rules! op_impl_signed {
422 ($($t:ty),*) => {
423 paste! {
424 $(
425 impl Neg for $t {
426 type Output = Self;
427 #[inline]
428 fn neg(self) -> Self {
429 Self(self.0.neg())
430 }
431 }
432
433 impl CheckedNeg for $t {
434 type Output = Self;
435
436 #[inline]
437 fn checked_neg(self) -> Option<Self::Output> {
438 let c = self.0.checked_neg();
439 c.map(Self)
440 }
441 }
442
443
444 impl $t {
445
446 #[inline]
453 #[must_use = "this returns the result of the operation, \
454 without modifying the original"]
455 pub fn abs(self) -> Self {
456 Self(self.0.abs())
457 }
458
459 #[inline]
466 #[must_use = "this returns the result of the operation, \
467 without modifying the original"]
468 pub fn signum(self) -> Self {
469 Self(self.0.signum())
470 }
471
472 #[must_use]
476 #[inline]
477 pub fn is_positive(self) -> bool {
478 self.0.is_positive()
479 }
480
481 #[must_use]
485 #[inline]
486 pub fn is_negative(self) -> bool {
487 self.0.is_negative()
488 }
489 }
490 )*
491 }
492 }
493}
494
495op_impl_signed! { I192 }
496op_impl_signed! { I256 }
497op_impl_signed! { I320 }
498op_impl_signed! { I384 }
499op_impl_signed! { I448 }
500op_impl_signed! { I512 }
501op_impl_signed! { I768 }
502
503macro_rules! error {
504 ($($t:ident),*) => {
505 paste! {
506 $(
507 #[derive(Debug, Clone, PartialEq, Eq)]
508 pub enum [<Parse $t Error>] {
509 NegativeToUnsigned,
510 InvalidLength,
511 InvalidDigit,
512 Empty,
513 Overflow,
514 }
515
516 #[cfg(not(feature = "alloc"))]
517 impl std::error::Error for [<Parse $t Error>] {}
518
519 #[cfg(not(feature = "alloc"))]
520 impl fmt::Display for [<Parse $t Error>] {
521 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
522 write!(f, "{:?}", self)
523 }
524 }
525 )*
526 }
527 };
528}
529error! {
530 I192,
531 I256,
532 I320,
533 I384,
534 I448,
535 I512,
536 I768,
537 U192,
538 U256,
539 U320,
540 U384,
541 U448,
542 U512,
543 U768
544}