1#![allow(clippy::useless_conversion)]
27
28use cfg_if::cfg_if;
29use either::{Either, Left, Right};
30use num_bigint::{BigInt, BigUint, ParseBigIntError, ToBigInt, ToBigUint};
31use num_traits::cast::{FromPrimitive, ToPrimitive};
32use num_traits::identities::{One, Zero};
33#[allow(unused_imports)]
34use num_traits::{
35 CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
36};
37use std::borrow::Cow::{self, Borrowed, Owned};
38use std::cmp::Ordering;
39use std::convert::{From, Into, TryFrom, TryInto};
40use std::fmt::Debug;
41use std::hash::{Hash, Hasher};
42use std::ops::{
43 Add, AddAssign, Deref, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
44};
45
46use std::str::FromStr;
47
48mod to_primitive_generic;
49use to_primitive_generic::ToGeneric;
51
52#[allow(non_camel_case_types)]
53type uint = u32;
54#[allow(non_camel_case_types)]
55type int = i32;
56
57cfg_if! {
58 if #[cfg(any(not(feature = "unsafe-opt"), not(target_pointer_width = "64")))] {
59 #[derive(Clone)]
64 pub struct UintInner(Either<uint, Box<BigUint>>);
65 #[derive(Clone)]
66 pub struct IntInner(Either<int, Box<BigInt>>);
67
68 impl UintInner {
69 const fn make_left(i: u32) -> Self {
70 UintInner(Left(i))
71 }
72 fn make(v: Either<u32, Box<BigUint>>) -> Self {
73 UintInner(v)
74 }
75 fn get(self) -> Either<u32, Box<BigUint>> {
76 self.0
77 }
78 fn get_ref(&self) -> Either<u32, &BigUint> {
79 match self.0 {
80 Left(v) => Left(v),
81 Right(ref b) => Right(&*b),
82 }
83 }
84 }
85
86 impl IntInner {
87 const fn make_left(i: i32) -> Self {
88 IntInner(Left(i))
89 }
90 fn make(v: Either<i32, Box<BigInt>>) -> Self {
91 IntInner(v)
92 }
93 fn get(self) -> Either<i32, Box<BigInt>> {
94 self.0
95 }
96 fn get_ref(&self) -> Either<i32, &BigInt> {
97 match self.0 {
98 Left(v) => Left(v),
99 Right(ref b) => Right(&*b),
100 }
101 }
102 }
103 } else {
104 mod unsafeu32orbox;
105
106 type UintInner = unsafeu32orbox::UnsafeU32OrBox<BigUint>;
107 type IntInner = unsafeu32orbox::UnsafeI32OrBox<BigInt>;
108 }
109}
110
111#[derive(Clone)]
112pub struct Uint(UintInner);
113#[derive(Clone)]
114pub struct Int(IntInner);
115
116impl Uint {
117 const fn make_left(i: u32) -> Self {
118 Uint(UintInner::make_left(i))
119 }
120 fn mk(v: Either<u32, Box<BigUint>>) -> Self {
121 Uint(UintInner::make(v))
122 }
123 fn get(self) -> Either<u32, Box<BigUint>> {
124 self.0.get()
125 }
126 fn get_ref(&self) -> Either<u32, &BigUint> {
127 self.0.get_ref()
128 }
129
130 pub const fn zero() -> Self {
131 Self::small(0)
132 }
133 pub const fn small(x: uint) -> Self {
134 Uint::make_left(x)
135 }
136 pub fn big(v: BigUint) -> Self {
137 Uint::mk(Right(Box::new(v)))
138 }
139 pub fn cow_big(&self) -> Cow<BigUint> {
160 match self.get_ref() {
161 Left(x) => Owned(x.into()),
162 Right(ref b) => Borrowed(b),
163 }
164 }
165 pub fn normalize(self) -> Self {
168 match self.get() {
169 Left(x) => Self::mk(Left(x)),
170 Right(b) => {
171 if let Some(x) = b.to_u32() {
172 Self::mk(Left(x)) } else {
174 Self::mk(Right(b))
175 }
176 }
177 }
178 }
179 #[allow(clippy::needless_return)]
181 pub fn normalize_ref(&self) -> Cow<Self> {
182 if let Right(ref b) = self.0.get_ref() {
183 if let Some(x) = b.to_u32() {
184 return Owned(Self::mk(Left(x)));
185 }
186 }
187 return Borrowed(self);
188 }
189 #[allow(dead_code)]
190 fn is_stored_as_big(&self) -> bool {
191 matches!(self.0.get_ref(), Right(_))
192 }
193}
194
195impl Int {
196 const fn make_left(i: i32) -> Self {
197 Int(IntInner::make_left(i))
198 }
199 fn mk(v: Either<i32, Box<BigInt>>) -> Self {
200 Int(IntInner::make(v))
201 }
202 fn get(self) -> Either<i32, Box<BigInt>> {
203 self.0.get()
204 }
205 fn get_ref(&self) -> Either<i32, &BigInt> {
206 self.0.get_ref()
207 }
208
209 pub const fn zero() -> Self {
210 Self::small(0)
211 }
212 pub const fn small(x: int) -> Self {
213 Int::make_left(x)
214 }
215 pub fn big(v: BigInt) -> Self {
216 Int::mk(Right(Box::new(v)))
217 }
218 pub fn cow_big(&self) -> Cow<BigInt> {
239 match self.get_ref() {
240 Left(x) => Owned(x.into()),
241 Right(ref b) => Borrowed(b),
242 }
243 }
244 pub fn normalize(self) -> Self {
247 match self.get() {
248 Left(x) => Self::mk(Left(x)),
249 Right(b) => {
250 if let Some(x) = b.to_i32() {
251 Self::mk(Left(x)) } else {
253 Self::mk(Right(b))
254 }
255 }
256 }
257 }
258 #[allow(clippy::needless_return)]
260 pub fn normalize_ref(&self) -> Cow<Self> {
261 if let Right(ref b) = self.0.get_ref() {
262 if let Some(x) = b.to_i32() {
263 return Owned(Self::mk(Left(x)));
264 }
265 }
266 return Borrowed(self);
267 }
268 #[allow(dead_code)]
269 fn is_stored_as_big(&self) -> bool {
270 matches!(self.0.get_ref(), Right(_))
271 }
272}
273
274trait SmallBig {
277 type Big;
278 type Small;
279
280 fn make_left(i: Self::Small) -> Self;
281 fn mk(v: Either<Self::Small, Box<Self::Big>>) -> Self;
282 fn get(self) -> Either<Self::Small, Box<Self::Big>>;
283 fn get_ref(&self) -> Either<Self::Small, &Self::Big>;
284 fn zero() -> Self;
285 fn small(x: Self::Small) -> Self;
286 fn big(v: Self::Big) -> Self;
287 fn into_big(self) -> Self::Big;
288}
289
290impl SmallBig for Uint {
291 type Big = BigUint;
292 type Small = u32;
293
294 fn make_left(i: Self::Small) -> Self {
295 Self::make_left(i)
296 }
297 fn mk(v: Either<Self::Small, Box<Self::Big>>) -> Self {
298 Self::mk(v)
299 }
300 fn get(self) -> Either<Self::Small, Box<Self::Big>> {
301 self.get()
302 }
303 fn get_ref(&self) -> Either<Self::Small, &Self::Big> {
304 self.get_ref()
305 }
306 fn zero() -> Self {
307 Self::zero()
308 }
309 fn small(x: Self::Small) -> Self {
310 Self::small(x)
311 }
312 fn big(v: Self::Big) -> Self {
313 Self::big(v)
314 }
315 fn into_big(self) -> Self::Big {
316 self.into()
317 }
318}
319impl SmallBig for Int {
320 type Big = BigInt;
321 type Small = i32;
322
323 fn make_left(i: Self::Small) -> Self {
324 Self::make_left(i)
325 }
326 fn mk(v: Either<Self::Small, Box<Self::Big>>) -> Self {
327 Self::mk(v)
328 }
329 fn get(self) -> Either<Self::Small, Box<Self::Big>> {
330 self.get()
331 }
332 fn get_ref(&self) -> Either<Self::Small, &Self::Big> {
333 self.get_ref()
334 }
335 fn zero() -> Self {
336 Self::zero()
337 }
338 fn small(x: Self::Small) -> Self {
339 Self::small(x)
340 }
341 fn big(v: Self::Big) -> Self {
342 Self::big(v)
343 }
344 fn into_big(self) -> Self::Big {
345 self.into()
346 }
347}
348impl Default for Uint {
351 fn default() -> Self {
352 Self::zero()
353 }
354}
355
356impl Default for Int {
357 fn default() -> Self {
358 Self::zero()
359 }
360}
361
362impl Zero for Uint {
363 fn zero() -> Self {
364 Self::small(0)
365 }
366 fn is_zero(&self) -> bool {
367 *self == Self::zero()
368 }
369}
370impl Zero for Int {
371 fn zero() -> Self {
372 Self::small(0)
373 }
374 fn is_zero(&self) -> bool {
375 *self == Self::zero()
376 }
377}
378
379impl One for Uint {
380 fn one() -> Self {
381 Self::small(1)
382 }
383 fn is_one(&self) -> bool {
384 *self == Self::one()
385 }
386}
387impl One for Int {
388 fn one() -> Self {
389 Self::small(1)
390 }
391 fn is_one(&self) -> bool {
392 *self == Self::one()
393 }
394}
395
396trait Transformable: Sized {
399 fn transform(&mut self, f: impl FnOnce(Self) -> Self);
400}
401
402impl<T: Default> Transformable for T {
403 fn transform(&mut self, f: impl FnOnce(Self) -> Self) {
404 let mut tmp = Self::default();
405 std::mem::swap(&mut tmp, self);
406 *self = f(tmp)
407 }
408}
409
410macro_rules! call_with_args {
411 ($macroname:tt, $baseargs:tt, [$($nextarg:tt),*]) => {
412 $(append_macro_call!{$macroname, $baseargs, $nextarg})*
413 };
414}
415
416macro_rules! append_macro_call {
417 ($macroname:tt, ($($baseargs:tt)*), $nextarg:tt) => {
418 $macroname!($($baseargs)* $nextarg)
419 };
420 ($macroname:tt, [$($baseargs:tt)*], $nextarg:tt) => {
421 $macroname![$($baseargs)* $nextarg]
422 };
423 ($macroname:tt, {$($baseargs:tt)*}, $nextarg:tt) => {
424 $macroname!{$($baseargs)* $nextarg}
425 };
426}
427
428macro_rules! impl_fmt_variants {
429 ($trait:path, $selftype:ty) => {
441 impl $trait for $selftype {
442 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
443 match self.0.get_ref() {
444 Left(x) => <<$selftype as SmallBig>::Small as $trait>::fmt(&x, f),
445 Right(b) => <<$selftype as SmallBig>::Big as $trait>::fmt(b, f),
446 }
447 }
448 }
449 };
450}
451
452call_with_args! {impl_fmt_variants, {std::fmt::Binary, }, [Uint, Int]}
453call_with_args! {impl_fmt_variants, {std::fmt::Debug, }, [Uint, Int]}
454call_with_args! {impl_fmt_variants, {std::fmt::Display, }, [Uint, Int]}
455call_with_args! {impl_fmt_variants, {std::fmt::LowerHex, }, [Uint, Int]}
456call_with_args! {impl_fmt_variants, {std::fmt::Octal, }, [Uint, Int]}
457call_with_args! {impl_fmt_variants, {std::fmt::UpperHex, }, [Uint, Int]}
458
459impl From<BigUint> for Uint {
464 fn from(v: BigUint) -> Self {
465 Uint::mk(Right(Box::new(v)))
466 }
467}
468impl From<Uint> for BigUint {
469 fn from(v: Uint) -> BigUint {
470 match v.0.get() {
471 Left(x) => x.into(),
472 Right(b) => *b,
473 }
474 }
475}
476
477impl From<BigInt> for Int {
478 fn from(v: BigInt) -> Self {
479 Int::mk(Right(Box::new(v)))
480 }
481}
482impl From<Int> for BigInt {
483 fn from(v: Int) -> BigInt {
484 match v.0.get() {
485 Left(x) => x.into(),
486 Right(b) => *b,
487 }
488 }
489}
490
491impl FromStr for Uint {
492 type Err = ParseBigIntError;
493 fn from_str(s: &str) -> Result<Self, ParseBigIntError> {
494 Ok(Uint::big(BigUint::from_str(s)?).normalize())
495 }
496}
497
498impl FromStr for Int {
499 type Err = ParseBigIntError;
500 fn from_str(s: &str) -> Result<Self, ParseBigIntError> {
501 Ok(Int::big(BigInt::from_str(s)?).normalize())
502 }
503}
504
505impl Hash for Uint {
506 fn hash<H: Hasher>(&self, state: &mut H) {
507 match self.normalize_ref().get_ref() {
508 Left(x) => x.hash(state),
509 Right(b) => b.hash(state),
510 }
511 }
512}
513
514impl Hash for Int {
515 fn hash<H: Hasher>(&self, state: &mut H) {
516 match self.normalize_ref().get_ref() {
517 Left(x) => x.hash(state),
518 Right(b) => b.hash(state),
519 }
520 }
521}
522
523impl Neg for Int {
524 type Output = Int;
525 fn neg(self) -> Int {
526 Int::big(BigInt::from(self).neg()).normalize()
527 }
528}
529
530impl Neg for &Int {
531 type Output = Int;
532 fn neg(self) -> Int {
533 let self1 = self.cow_big();
534 let self2: &BigInt = self1.deref();
535 Int::big(self2.neg()).normalize()
536 }
537}
538
539impl Ord for Uint {
542 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
543 if let (Left(x), Left(y)) = (self.get_ref(), other.get_ref()) {
544 x.cmp(&y)
545 } else {
546 let self1 = self.cow_big();
547 let self2: &BigUint = self1.deref();
548 let other1 = other.cow_big();
549 let other2: &BigUint = other1.deref();
550 self2.cmp(other2.deref())
551 }
552 }
553}
554
555impl PartialOrd<Uint> for Uint {
556 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
557 if let (Left(x), Left(y)) = (self.get_ref(), other.get_ref()) {
558 x.partial_cmp(&y)
559 } else {
560 let self1 = self.cow_big();
561 let self2: &BigUint = self1.deref();
562 let other1 = other.cow_big();
563 let other2: &BigUint = other1.deref();
564 self2.partial_cmp(other2.deref())
565 }
566 }
567}
568
569impl Ord for Int {
570 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
571 if let (Left(x), Left(y)) = (self.get_ref(), other.get_ref()) {
572 x.cmp(&y)
573 } else {
574 let self1 = self.cow_big();
575 let self2: &BigInt = self1.deref();
576 let other1 = other.cow_big();
577 let other2: &BigInt = other1.deref();
578 self2.cmp(other2.deref())
579 }
580 }
581}
582
583impl PartialOrd<Int> for Int {
584 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
585 if let (Left(x), Left(y)) = (self.get_ref(), other.get_ref()) {
586 x.partial_cmp(&y)
587 } else {
588 let self1 = self.cow_big();
589 let self2: &BigInt = self1.deref();
590 let other1 = other.cow_big();
591 let other2: &BigInt = other1.deref();
592 self2.partial_cmp(other2.deref())
593 }
594 }
595}
596
597impl PartialOrd<Uint> for Int {
598 fn partial_cmp(&self, other: &Uint) -> Option<std::cmp::Ordering> {
599 self.partial_cmp(&Int::from(other.clone()))
600 }
601}
602
603impl PartialOrd<Int> for Uint {
604 fn partial_cmp(&self, other: &Int) -> Option<std::cmp::Ordering> {
605 Int::from(self.clone()).partial_cmp(other)
606 }
607}
608
609impl PartialEq<Uint> for Uint {
610 fn eq(&self, other: &Self) -> bool {
611 if let (Left(x), Left(y)) = (self.get_ref(), other.get_ref()) {
612 x == y
613 } else {
614 let self1 = self.cow_big();
615 let self2: &BigUint = self1.deref();
616 let other1 = other.cow_big();
617 let other2: &BigUint = other1.deref();
618 self2.eq(other2.deref())
619 }
620 }
621}
622impl PartialEq<Int> for Uint {
623 fn eq(&self, other: &Int) -> bool {
625 let self_bigint = BigInt::from(BigUint::from(self.clone()));
626 let other1 = other.cow_big();
627 let other2: &BigInt = other1.deref();
628 self_bigint.eq(other2.deref())
629 }
630}
631impl Eq for Uint {}
632
633impl PartialEq<Int> for Int {
634 fn eq(&self, other: &Self) -> bool {
635 if let (Left(x), Left(y)) = (self.get_ref(), other.get_ref()) {
636 x == y
637 } else {
638 let self1 = self.cow_big();
639 let self2: &BigInt = self1.deref();
640 let other1 = other.cow_big();
641 let other2: &BigInt = other1.deref();
642 self2.eq(other2.deref())
643 }
644 }
645}
646impl PartialEq<Uint> for Int {
647 fn eq(&self, other: &Uint) -> bool {
649 let other_bigint = BigInt::from(BigUint::from(other.clone()));
650 let self1 = self.cow_big();
651 let self2: &BigInt = self1.deref();
652 other_bigint.eq(self2.deref())
653 }
654}
655impl Eq for Int {}
656
657macro_rules! impl_ref_variants {
658 ($trait:tt, $method:tt, $selftype:ty, $othtype:ty, $resulttype:ty) => {
670 impl $trait<&$othtype> for $selftype {
671 #[inline]
672 fn $method(&self, other: &&$othtype) -> $resulttype {
673 self.$method(*other)
674 }
675 }
676 impl $trait<$othtype> for &$selftype {
677 #[inline]
678 fn $method(&self, other: &$othtype) -> $resulttype {
679 (*self).$method(other)
680 }
681 }
682 };
683}
684
685impl_ref_variants! { PartialEq, eq, Uint, Uint, bool }
686impl_ref_variants! { PartialEq, eq, Int, Uint, bool }
687impl_ref_variants! { PartialEq, eq, Uint, Int, bool }
688impl_ref_variants! { PartialEq, eq, Int, Int, bool }
689impl_ref_variants! { PartialOrd, partial_cmp, Uint, Uint, Option<Ordering> }
690impl_ref_variants! { PartialOrd, partial_cmp, Int, Uint, Option<Ordering> }
691impl_ref_variants! { PartialOrd, partial_cmp, Uint, Int, Option<Ordering> }
692impl_ref_variants! { PartialOrd, partial_cmp, Int, Int, Option<Ordering> }
693
694impl Uint {
697 pub fn into_int(self) -> Int {
699 match self.get() {
700 Left(x) => {
701 if let Ok(x1) = x.try_into() {
702 Int::mk(Left(x1))
703 } else {
704 Int::mk(Right(Box::new(x.into())))
705 }
706 }
707 Right(b) => Int::mk(Right(Box::new((*b).into()))),
708 }
709 }
710 pub fn to_int(&self) -> Int {
712 match self.0.get_ref() {
713 Left(x) => {
714 if let Ok(x1) = x.try_into() {
715 Int::mk(Left(x1))
716 } else {
717 Int::mk(Right(Box::new(x.into())))
718 }
719 }
720 Right(b) => Int::mk(Right(Box::new(
721 b.to_bigint()
722 .expect("ToBigInt on BigUint should always succeed"),
723 ))),
724 }
725 }
726}
727impl From<Uint> for Int {
729 fn from(v: Uint) -> Self {
730 v.into_int()
731 }
732}
733
734impl Int {
735 pub fn into_uint(self) -> Option<Uint> {
741 match self.get() {
742 Left(x) => {
743 if let Ok(x1) = x.try_into() {
744 Some(Uint::mk(Left(x1)))
745 } else {
746 Some(Uint::mk(Right(Box::new(x.to_biguint()?))))
747 }
748 }
749 Right(x) => Some(Uint::mk(Right(Box::new(x.to_biguint()?)))),
750 }
751 }
752 pub fn to_uint(&self) -> Option<Uint> {
754 match self.0.get_ref() {
755 Left(x) => {
756 if let Ok(x1) = x.try_into() {
757 Some(Uint::mk(Left(x1)))
758 } else {
759 Some(Uint::mk(Right(Box::new(x.to_biguint()?))))
760 }
761 }
762 Right(x) => Some(Uint::mk(Right(Box::new(x.to_biguint()?)))),
763 }
764 }
765}
766#[non_exhaustive]
767#[derive(Debug)]
768pub struct IntIsNegativeError();
769
770impl TryFrom<Int> for Uint {
772 type Error = IntIsNegativeError;
773 fn try_from(v: Int) -> Result<Self, Self::Error> {
775 v.into_uint().ok_or(IntIsNegativeError())
776 }
777}
778
779impl From<u128> for Uint {
782 fn from(x: u128) -> Self {
783 if let Ok(x) = x.try_into() {
784 Uint::mk(Left(x))
785 } else {
786 Uint::mk(Right(Box::new(x.into())))
787 }
788 }
789}
790impl TryFrom<i128> for Uint {
791 type Error = IntIsNegativeError;
792 fn try_from(x: i128) -> Result<Self, Self::Error> {
793 if let Ok(x) = x.try_into() {
794 Ok(Uint::mk(Left(x)))
795 } else {
796 Ok(Uint::mk(Right(Box::new(
797 BigInt::from(x).to_biguint().ok_or(IntIsNegativeError())?,
798 ))))
799 }
800 }
801}
802impl From<u64> for Uint {
803 fn from(x: u64) -> Self {
804 if let Ok(x) = x.try_into() {
805 Uint::mk(Left(x))
806 } else {
807 Uint::mk(Right(Box::new(x.into())))
808 }
809 }
810}
811impl TryFrom<i64> for Uint {
812 type Error = IntIsNegativeError;
813 fn try_from(x: i64) -> Result<Self, Self::Error> {
814 if let Ok(x) = x.try_into() {
815 Ok(Uint::mk(Left(x)))
816 } else {
817 Ok(Uint::mk(Right(Box::new(
818 BigInt::from(x).to_biguint().ok_or(IntIsNegativeError())?,
819 ))))
820 }
821 }
822}
823impl From<u32> for Uint {
824 fn from(x: u32) -> Self {
825 if let Ok(x) = x.try_into() {
826 Uint::mk(Left(x))
827 } else {
828 Uint::mk(Right(Box::new(x.into())))
829 }
830 }
831}
832impl TryFrom<i32> for Uint {
833 type Error = IntIsNegativeError;
834 fn try_from(x: i32) -> Result<Self, Self::Error> {
835 if let Ok(x) = x.try_into() {
836 Ok(Uint::mk(Left(x)))
837 } else {
838 Ok(Uint::mk(Right(Box::new(
839 BigInt::from(x).to_biguint().ok_or(IntIsNegativeError())?,
840 ))))
841 }
842 }
843}
844
845impl From<u16> for Uint {
846 fn from(x: u16) -> Self {
847 if let Ok(x) = x.try_into() {
848 Uint::mk(Left(x))
849 } else {
850 Uint::mk(Right(Box::new(x.into())))
851 }
852 }
853}
854impl TryFrom<i16> for Uint {
855 type Error = IntIsNegativeError;
856 fn try_from(x: i16) -> Result<Self, Self::Error> {
857 if let Ok(x) = x.try_into() {
858 Ok(Uint::mk(Left(x)))
859 } else {
860 Ok(Uint::mk(Right(Box::new(
861 BigInt::from(x).to_biguint().ok_or(IntIsNegativeError())?,
862 ))))
863 }
864 }
865}
866
867impl From<u8> for Uint {
868 fn from(x: u8) -> Self {
869 if let Ok(x) = x.try_into() {
870 Uint::mk(Left(x))
871 } else {
872 Uint::mk(Right(Box::new(x.into())))
873 }
874 }
875}
876impl TryFrom<i8> for Uint {
877 type Error = IntIsNegativeError;
878 fn try_from(x: i8) -> Result<Self, Self::Error> {
879 if let Ok(x) = x.try_into() {
880 Ok(Uint::mk(Left(x)))
881 } else {
882 Ok(Uint::mk(Right(Box::new(
883 BigInt::from(x).to_biguint().ok_or(IntIsNegativeError())?,
884 ))))
885 }
886 }
887}
888
889impl From<usize> for Uint {
890 fn from(x: usize) -> Self {
891 if let Ok(x) = x.try_into() {
892 Uint::mk(Left(x))
893 } else {
894 Uint::mk(Right(Box::new(x.into())))
895 }
896 }
897}
898impl TryFrom<isize> for Uint {
899 type Error = IntIsNegativeError;
900 fn try_from(x: isize) -> Result<Self, Self::Error> {
901 if let Ok(x) = x.try_into() {
902 Ok(Uint::mk(Left(x)))
903 } else {
904 Ok(Uint::mk(Right(Box::new(
905 BigInt::from(x).to_biguint().ok_or(IntIsNegativeError())?,
906 ))))
907 }
908 }
909}
910
911impl FromPrimitive for Uint {
912 fn from_u128(x: u128) -> Option<Self> {
913 if let Ok(x) = x.try_into() {
914 Some(Uint::mk(Left(x)))
915 } else {
916 Some(Uint::mk(Right(Box::new(x.into()))))
917 }
918 }
919 fn from_i128(x: i128) -> Option<Self> {
920 if let Ok(x) = x.try_into() {
921 Some(Uint::mk(Left(x)))
922 } else {
923 Some(Uint::mk(Right(Box::new(BigInt::from(x).to_biguint()?))))
924 }
925 }
926 fn from_u64(x: u64) -> Option<Self> {
927 if let Ok(x) = x.try_into() {
928 Some(Uint::mk(Left(x)))
929 } else {
930 Some(Uint::mk(Right(Box::new(x.into()))))
931 }
932 }
933 fn from_i64(x: i64) -> Option<Self> {
934 if let Ok(x) = x.try_into() {
935 Some(Uint::mk(Left(x)))
936 } else {
937 Some(Uint::mk(Right(Box::new(BigInt::from(x).to_biguint()?))))
938 }
939 }
940 fn from_u32(x: u32) -> Option<Self> {
941 if let Ok(x) = x.try_into() {
942 Some(Uint::mk(Left(x)))
943 } else {
944 Some(Uint::mk(Right(Box::new(x.into()))))
945 }
946 }
947 fn from_i32(x: i32) -> Option<Self> {
948 if let Ok(x) = x.try_into() {
949 Some(Uint::mk(Left(x)))
950 } else {
951 Some(Uint::mk(Right(Box::new(BigInt::from(x).to_biguint()?))))
952 }
953 }
954}
955
956impl From<u128> for Int {
957 fn from(x: u128) -> Self {
958 if let Ok(x) = x.try_into() {
959 Int::mk(Left(x))
960 } else {
961 Int::mk(Right(Box::new(x.into())))
962 }
963 }
964}
965impl From<i128> for Int {
966 fn from(x: i128) -> Self {
967 if let Ok(x) = x.try_into() {
968 Int::mk(Left(x))
969 } else {
970 Int::mk(Right(Box::new(x.into())))
971 }
972 }
973}
974impl From<u64> for Int {
975 fn from(x: u64) -> Self {
976 if let Ok(x) = x.try_into() {
977 Int::mk(Left(x))
978 } else {
979 Int::mk(Right(Box::new(x.into())))
980 }
981 }
982}
983impl From<i64> for Int {
984 fn from(x: i64) -> Self {
985 if let Ok(x) = x.try_into() {
986 Int::mk(Left(x))
987 } else {
988 Int::mk(Right(Box::new(x.into())))
989 }
990 }
991}
992impl From<u32> for Int {
993 fn from(x: u32) -> Self {
994 if let Ok(x) = x.try_into() {
995 Int::mk(Left(x))
996 } else {
997 Int::mk(Right(Box::new(x.into())))
998 }
999 }
1000}
1001impl From<i32> for Int {
1002 fn from(x: i32) -> Self {
1003 if let Ok(x) = x.try_into() {
1004 Int::mk(Left(x))
1005 } else {
1006 Int::mk(Right(Box::new(x.into())))
1007 }
1008 }
1009}
1010
1011impl From<u16> for Int {
1012 fn from(x: u16) -> Self {
1013 if let Ok(x) = x.try_into() {
1014 Int::mk(Left(x))
1015 } else {
1016 Int::mk(Right(Box::new(x.into())))
1017 }
1018 }
1019}
1020impl From<i16> for Int {
1021 fn from(x: i16) -> Self {
1022 if let Ok(x) = x.try_into() {
1023 Int::mk(Left(x))
1024 } else {
1025 Int::mk(Right(Box::new(x.into())))
1026 }
1027 }
1028}
1029
1030impl From<u8> for Int {
1031 fn from(x: u8) -> Self {
1032 if let Ok(x) = x.try_into() {
1033 Int::mk(Left(x))
1034 } else {
1035 Int::mk(Right(Box::new(x.into())))
1036 }
1037 }
1038}
1039impl From<i8> for Int {
1040 fn from(x: i8) -> Self {
1041 if let Ok(x) = x.try_into() {
1042 Int::mk(Left(x))
1043 } else {
1044 Int::mk(Right(Box::new(x.into())))
1045 }
1046 }
1047}
1048
1049impl From<usize> for Int {
1050 fn from(x: usize) -> Self {
1051 if let Ok(x) = x.try_into() {
1052 Int::mk(Left(x))
1053 } else {
1054 Int::mk(Right(Box::new(x.into())))
1055 }
1056 }
1057}
1058impl From<isize> for Int {
1059 fn from(x: isize) -> Self {
1060 if let Ok(x) = x.try_into() {
1061 Int::mk(Left(x))
1062 } else {
1063 Int::mk(Right(Box::new(x.into())))
1064 }
1065 }
1066}
1067
1068impl FromPrimitive for Int {
1069 fn from_u128(x: u128) -> Option<Self> {
1070 if let Ok(x) = x.try_into() {
1071 Some(Int::mk(Left(x)))
1072 } else {
1073 Some(Int::mk(Right(Box::new(x.into()))))
1074 }
1075 }
1076 fn from_i128(x: i128) -> Option<Self> {
1077 if let Ok(x) = x.try_into() {
1078 Some(Int::mk(Left(x)))
1079 } else {
1080 Some(Int::mk(Right(Box::new(x.into()))))
1081 }
1082 }
1083 fn from_u64(x: u64) -> Option<Self> {
1084 if let Ok(x) = x.try_into() {
1085 Some(Int::mk(Left(x)))
1086 } else {
1087 Some(Int::mk(Right(Box::new(x.into()))))
1088 }
1089 }
1090 fn from_i64(x: i64) -> Option<Self> {
1091 if let Ok(x) = x.try_into() {
1092 Some(Int::mk(Left(x)))
1093 } else {
1094 Some(Int::mk(Right(Box::new(x.into()))))
1095 }
1096 }
1097 fn from_u32(x: u32) -> Option<Self> {
1098 if let Ok(x) = x.try_into() {
1099 Some(Int::mk(Left(x)))
1100 } else {
1101 Some(Int::mk(Right(Box::new(x.into()))))
1102 }
1103 }
1104 fn from_i32(x: i32) -> Option<Self> {
1105 if let Ok(x) = x.try_into() {
1106 Some(Int::mk(Left(x)))
1107 } else {
1108 Some(Int::mk(Right(Box::new(x.into()))))
1109 }
1110 }
1111}
1112
1113impl ToPrimitive for Int {
1114 fn to_u128(&self) -> Option<u128> {
1115 match self.0.get_ref() {
1116 Left(x) => x.try_into().ok(),
1117 Right(b) => b.to_u128(),
1118 }
1119 }
1120 fn to_i128(&self) -> Option<i128> {
1121 match self.0.get_ref() {
1122 Left(x) => x.try_into().ok(),
1123 Right(b) => b.to_i128(),
1124 }
1125 }
1126 fn to_u64(&self) -> Option<u64> {
1127 match self.0.get_ref() {
1128 Left(x) => x.try_into().ok(),
1129 Right(b) => b.to_u64(),
1130 }
1131 }
1132 fn to_i64(&self) -> Option<i64> {
1133 match self.0.get_ref() {
1134 Left(x) => x.try_into().ok(),
1135 Right(b) => b.to_i64(),
1136 }
1137 }
1138 fn to_u32(&self) -> Option<u32> {
1139 match self.0.get_ref() {
1140 Left(x) => x.try_into().ok(),
1141 Right(b) => b.to_u32(),
1142 }
1143 }
1144 fn to_i32(&self) -> Option<i32> {
1145 match self.0.get_ref() {
1146 Left(x) => x.try_into().ok(),
1147 Right(b) => b.to_i32(),
1148 }
1149 }
1150}
1151
1152impl ToPrimitive for Uint {
1153 fn to_u128(&self) -> Option<u128> {
1154 match self.0.get_ref() {
1155 Left(x) => x.try_into().ok(),
1156 Right(b) => b.to_u128(),
1157 }
1158 }
1159 fn to_i128(&self) -> Option<i128> {
1160 match self.0.get_ref() {
1161 Left(x) => x.try_into().ok(),
1162 Right(b) => b.to_i128(),
1163 }
1164 }
1165 fn to_u64(&self) -> Option<u64> {
1166 match self.0.get_ref() {
1167 Left(x) => x.try_into().ok(),
1168 Right(b) => b.to_u64(),
1169 }
1170 }
1171 fn to_i64(&self) -> Option<i64> {
1172 match self.0.get_ref() {
1173 Left(x) => x.try_into().ok(),
1174 Right(b) => b.to_i64(),
1175 }
1176 }
1177 fn to_u32(&self) -> Option<u32> {
1178 match self.0.get_ref() {
1179 Left(x) => x.try_into().ok(),
1180 Right(b) => b.to_u32(),
1181 }
1182 }
1183 fn to_i32(&self) -> Option<i32> {
1184 match self.0.get_ref() {
1185 Left(x) => x.try_into().ok(),
1186 Right(b) => b.to_i32(),
1187 }
1188 }
1189}
1190
1191macro_rules! call_with_all_signed_base_types {
1192 ($macroname:ident, $($token:tt)*) => {
1193 $macroname!{$($token)* i8}
1194 $macroname!{$($token)* i16}
1195 $macroname!{$($token)* i32}
1196 $macroname!{$($token)* i64}
1197 $macroname!{$($token)* i128}
1198 $macroname!{$($token)* isize}
1199 };
1200}
1201
1202macro_rules! call_with_all_unsigned_base_types {
1203 ($macroname:ident, $($token:tt)*) => {
1204 $macroname!{$($token)* u8}
1205 $macroname!{$($token)* u16}
1206 $macroname!{$($token)* u32}
1207 $macroname!{$($token)* u64}
1208 $macroname!{$($token)* u128}
1209 $macroname!{$($token)* usize}
1210 };
1211}
1212
1213macro_rules! call_with_cow_permutations {
1235 ($macroname_value:ident, $macroname_mut:ident, $type:tt, $basetype:tt, $bigtype:tt, both signed and unsigned) => {
1236 call_with_cow_permutations!{$macroname_value, $macroname_mut, $type, $basetype, $bigtype, self case}
1237 call_with_all_signed_base_types!{
1238 call_with_cow_permutations,
1239 $macroname_value, $macroname_mut, $type, $basetype, $bigtype, base type
1240 }
1241 call_with_all_unsigned_base_types!{
1242 call_with_cow_permutations,
1243 $macroname_value, $macroname_mut, $type, $basetype, $bigtype, base type
1244 }
1245 };
1246 ($macroname_value:ident, $macroname_mut:ident, $type:tt, $basetype:tt, $bigtype:tt, only unsigned) => {
1247 call_with_cow_permutations!{$macroname_value, $macroname_mut, $type, $basetype, $bigtype, self case}
1248 call_with_all_unsigned_base_types!{
1249 call_with_cow_permutations,
1250 $macroname_value, $macroname_mut, $type, $basetype, $bigtype, base type
1251 }
1252 };
1253 ($macroname_value:ident, $macroname_mut:ident, $type:tt, $basetype:tt, $bigtype:tt) => {
1254 call_with_cow_permutations!{$macroname_value, $macroname_mut, $type, $basetype, $bigtype, self case}
1255 };
1256
1257 ($macroname_value:ident, $macroname_mut:ident, $type:tt, $basetype:tt, $bigtype:tt, self case) => {
1272 $macroname_value!{
1273 $type, $basetype, $bigtype, self, v, $type, $type, v.get_ref(), {},
1274 $bigtype::from(self), $bigtype::from(v)
1275 }
1276 $macroname_value!{
1277 $type, $basetype, $bigtype, self, v, $type, &$type, v.get_ref(), {
1278 let v1 = v.cow_big()
1279 let v2: &$bigtype = v1.deref()
1280 }, $bigtype::from(self), v2
1281 }
1282 $macroname_value!{
1283 $type, $basetype, $bigtype, self, v, &$type, $type, v.get_ref(), {
1284 let self1 = self.cow_big()
1285 let self2: &$bigtype = self1.deref()
1286 }, self2, $bigtype::from(v)
1287 }
1288 $macroname_value!{
1289 $type, $basetype, $bigtype, self, v, &$type, &$type, v.get_ref(), {
1290 let self1 = self.cow_big()
1291 let self2: &$bigtype = self1.deref()
1292 let v1 = v.cow_big()
1293 let v2: &$bigtype = v1.deref()
1294 }, self2, v2
1295 }
1296 $macroname_mut!{$type, $type}
1297 $macroname_mut!{$type, &$type}
1298 };
1299
1300 ($macroname_value:ident, $macroname_mut:ident, $type:tt, $basetype:ty, $bigtype:tt, base type $baseothertype:ty) => {
1303 $macroname_value!{
1304 $type, $basetype, $bigtype, self, v, $type, $baseothertype, Either::<$baseothertype, $type>::Left(v), {},
1305 $bigtype::from(self), v
1306 }
1307 $macroname_value!{
1308 $type, $basetype, $bigtype, self, v, $type, &$baseothertype, Either::<$baseothertype, $type>::Left(*v), {},
1309 $bigtype::from(self), *v
1310 }
1311 $macroname_value!{
1312 $type, $basetype, $bigtype, self, v, &$type, $baseothertype, Either::<$baseothertype, $type>::Left(v), {
1313 let self1 = self.cow_big()
1314 let self2: &$bigtype = self1.deref()
1315 }, self2, v
1316 }
1317 $macroname_value!{
1318 $type, $basetype, $bigtype, self, v, &$type, &$baseothertype, Either::<$baseothertype, $type>::Left(*v), {
1319 let self1 = self.cow_big()
1320 let self2: &$bigtype = self1.deref()
1321 }, self2, *v
1322 }
1323 $macroname_mut!{$type, $baseothertype}
1324 $macroname_mut!{$type, &$baseothertype}
1325 };
1326}
1327
1328macro_rules! trait_add_value {
1329 ($type:tt, $basetype:ty, $bigtype:ty, $selfvar:tt, $othvar:ident,
1330 $selftype:ty, $othtype:ty, $otheitherref:expr,
1331 {$($makecows:stmt)*}, $bigexpr1:expr, $bigexpr2:expr) => {
1332 impl Add<$othtype> for $selftype {
1333 type Output = $type;
1334 fn add($selfvar, $othvar: $othtype) -> $type {
1335 if let (Left(x), Left(y)) = ($selfvar.get_ref(), $otheitherref) {
1336 if let Ok(y_base) = <$basetype>::try_from(y) {
1337 if let Some(z) = <$basetype>::checked_add(x, y_base) {
1338 return $type::small(z);
1339 }
1340 }
1341 }
1342 $($makecows)*
1343 $type::big($bigexpr1.add($bigexpr2))
1344 }
1345 }
1346 };
1347}
1348
1349macro_rules! trait_add_mut {
1350 ($type:tt, $othtype:ty) => {
1351 impl AddAssign<$othtype> for $type {
1352 fn add_assign(&mut self, other: $othtype) {
1353 self.transform(|sf| sf.add(other));
1354 }
1355 }
1356 };
1357}
1358
1359call_with_cow_permutations! {trait_add_value, trait_add_mut, Int, int, BigInt, both signed and unsigned}
1360call_with_cow_permutations! {trait_add_value, trait_add_mut, Uint, uint, BigUint, only unsigned}
1361
1362macro_rules! trait_div_value {
1363 ($type:tt, $basetype:ty, $bigtype:ty, $selfvar:tt, $othvar:ident,
1364 $selftype:ty, $othtype:ty, $otheitherref:expr,
1365 {$($makecows:stmt)*}, $bigexpr1:expr, $bigexpr2:expr) => {
1366 impl Div<$othtype> for $selftype {
1367 type Output = $type;
1368 fn div($selfvar, $othvar: $othtype) -> $type {
1369 if let (Left(x), Left(y)) = ($selfvar.get_ref(), $otheitherref) {
1370 if let Ok(y_base) = <$basetype>::try_from(y) {
1371 if let Some(z) = <$basetype>::checked_div(x, y_base) {
1372 return $type::small(z);
1373 }
1374 }
1375 }
1376 $($makecows)*
1377 $type::big($bigexpr1.div($bigexpr2))
1378 }
1379 }
1380 };
1381}
1382
1383macro_rules! trait_div_mut {
1384 ($type:tt, $othtype:ty) => {
1385 impl DivAssign<$othtype> for $type {
1386 fn div_assign(&mut self, other: $othtype) {
1387 self.transform(|sf| sf.div(other));
1388 }
1389 }
1390 };
1391}
1392
1393call_with_cow_permutations! {trait_div_value, trait_div_mut, Int, int, BigInt, both signed and unsigned}
1394call_with_cow_permutations! {trait_div_value, trait_div_mut, Uint, uint, BigUint, only unsigned}
1395
1396macro_rules! trait_mul_value {
1397 ($type:tt, $basetype:ty, $bigtype:ty, $selfvar:tt, $othvar:ident,
1398 $selftype:ty, $othtype:ty, $otheitherref:expr,
1399 {$($makecows:stmt)*}, $bigexpr1:expr, $bigexpr2:expr) => {
1400 impl Mul<$othtype> for $selftype {
1401 type Output = $type;
1402 fn mul($selfvar, $othvar: $othtype) -> $type {
1403 if let (Left(x), Left(y)) = ($selfvar.get_ref(), $otheitherref) {
1404 if let Ok(y_base) = <$basetype>::try_from(y) {
1405 if let Some(z) = <$basetype>::checked_mul(x, y_base) {
1406 return $type::small(z);
1407 }
1408 }
1409 }
1410 $($makecows)*
1411 $type::big($bigexpr1.mul($bigexpr2))
1412 }
1413 }
1414 };
1415}
1416
1417macro_rules! trait_mul_mut {
1418 ($type:tt, $othtype:ty) => {
1419 impl MulAssign<$othtype> for $type {
1420 fn mul_assign(&mut self, other: $othtype) {
1421 self.transform(|sf| sf.mul(other));
1422 }
1423 }
1424 };
1425}
1426
1427call_with_cow_permutations! {trait_mul_value, trait_mul_mut, Int, int, BigInt, both signed and unsigned}
1428call_with_cow_permutations! {trait_mul_value, trait_mul_mut, Uint, uint, BigUint, only unsigned}
1429
1430macro_rules! trait_rem_value {
1431 ($type:tt, $basetype:ty, $bigtype:ty, $selfvar:tt, $othvar:ident,
1432 $selftype:ty, $othtype:ty, $otheitherref:expr,
1433 {$($makecows:stmt)*}, $bigexpr1:expr, $bigexpr2:expr) => {
1434 impl Rem<$othtype> for $selftype {
1435 type Output = $type;
1436 fn rem($selfvar, $othvar: $othtype) -> $type {
1437 if let (Left(x), Left(y)) = ($selfvar.get_ref(), $otheitherref) {
1438 if let Ok(y_base) = <$basetype>::try_from(y) {
1439 if let Some(z) = <$basetype>::checked_rem(x, y_base) {
1440 return $type::small(z);
1441 }
1442 }
1443 }
1444 $($makecows)*
1445 $type::big($bigexpr1.rem($bigexpr2))
1446 }
1447 }
1448 };
1449}
1450
1451macro_rules! trait_rem_mut {
1452 ($type:tt, $othtype:ty) => {
1453 impl RemAssign<$othtype> for $type {
1454 fn rem_assign(&mut self, other: $othtype) {
1455 self.transform(|sf| sf.rem(other));
1456 }
1457 }
1458 };
1459}
1460
1461call_with_cow_permutations! {trait_rem_value, trait_rem_mut, Int, int, BigInt, both signed and unsigned}
1462call_with_cow_permutations! {trait_rem_value, trait_rem_mut, Uint, uint, BigUint, only unsigned}
1463
1464macro_rules! trait_sub_value {
1465 ($type:tt, $basetype:ty, $bigtype:ty, $selfvar:tt, $othvar:ident,
1466 $selftype:ty, $othtype:ty, $otheitherref:expr,
1467 {$($makecows:stmt)*}, $bigexpr1:expr, $bigexpr2:expr) => {
1468 impl Sub<$othtype> for $selftype {
1469 type Output = $type;
1470 fn sub($selfvar, $othvar: $othtype) -> $type {
1471 if let (Left(x), Left(y)) = ($selfvar.get_ref(), $otheitherref) {
1472 if let Ok(y_base) = <$basetype>::try_from(y) {
1473 if let Some(z) = <$basetype>::checked_sub(x, y_base) {
1474 return $type::small(z);
1475 }
1476 }
1477 }
1478 $($makecows)*
1479 $type::big($bigexpr1.sub($bigexpr2))
1480 }
1481 }
1482 };
1483}
1484
1485macro_rules! trait_sub_mut {
1486 ($type:tt, $othtype:ty) => {
1487 impl SubAssign<$othtype> for $type {
1488 fn sub_assign(&mut self, other: $othtype) {
1489 self.transform(|sf| sf.sub(other));
1490 }
1491 }
1492 };
1493}
1494
1495call_with_cow_permutations! {trait_sub_value, trait_sub_mut, Int, int, BigInt, both signed and unsigned}
1496call_with_cow_permutations! {trait_sub_value, trait_sub_mut, Uint, uint, BigUint, only unsigned}
1497
1498macro_rules! checked_trait {
1504 ($trait:tt, $method:tt, $type:tt) => {
1505 impl $trait for $type {
1506 fn $method(&self, other: &Self) -> Option<Self> {
1507 if let (Left(x), Left(y)) = (self.get_ref(), other.get_ref()) {
1509 if let Some(res) = x.$method(y) {
1510 return Some($type::small(res));
1511 }
1512 }
1513 let x_big = self.cow_big();
1515 let y_big = other.cow_big();
1516 if let Some(z_big) = x_big.$method(y_big.deref()) {
1517 return Some($type::big(z_big));
1518 } else {
1519 return None;
1520 }
1521 }
1522 }
1523 };
1524}
1525
1526call_with_args! {checked_trait, {CheckedAdd, checked_add, }, [Uint, Int]}
1527call_with_args! {checked_trait, {CheckedDiv, checked_div, }, [Uint, Int]}
1528call_with_args! {checked_trait, {CheckedMul, checked_mul, }, [Uint, Int]}
1529call_with_args! {checked_trait, {CheckedSub, checked_sub, }, [Uint, Int]}
1535
1536macro_rules! trait_partialeq {
1537 (base, $type:tt, $basetype:ty) => {
1538 impl PartialEq<$basetype> for $type {
1540 fn eq(&self, other: &$basetype) -> bool {
1541 ToGeneric::<$basetype>::to_generic(self).map_or(false, |x| x.eq(other))
1542 }
1543 }
1544
1545 impl PartialEq<$type> for $basetype {
1547 fn eq(&self, other: &$type) -> bool {
1548 ToGeneric::<$basetype>::to_generic(other).map_or(false, |x| x.eq(self))
1549 }
1550 }
1551
1552 impl_ref_variants! {PartialEq, eq, $type, $basetype, bool}
1555 impl_ref_variants! {PartialEq, eq, $basetype, $type, bool}
1556 };
1557}
1558
1559call_with_all_unsigned_base_types!(trait_partialeq, base, Uint,);
1560call_with_all_unsigned_base_types!(trait_partialeq, base, Int,);
1561call_with_all_signed_base_types!(trait_partialeq, base, Uint,);
1562call_with_all_signed_base_types!(trait_partialeq, base, Int,);
1563
1564macro_rules! trait_partialord_straight {
1565 ($type:tt $basetype:tt) => {
1566 impl PartialOrd<$basetype> for $type {
1568 fn partial_cmp(&self, other: &$basetype) -> Option<Ordering> {
1569 match ToGeneric::<$basetype>::to_generic(self) {
1571 Some(x) => x.partial_cmp(other),
1572 None => {
1573 match $type::try_from(other.clone()) {
1575 Ok(other2) => self.partial_cmp(&other2),
1576 Err(_) => {
1577 Some(Ordering::Greater)
1581 }
1582 }
1583 }
1584 }
1585 }
1586 }
1587
1588 impl PartialOrd<$type> for $basetype {
1590 fn partial_cmp(&self, other: &$type) -> Option<Ordering> {
1591 other.partial_cmp(self).map(|ord| ord.reverse())
1592 }
1593 }
1594
1595 impl_ref_variants! {PartialOrd, partial_cmp, $type, $basetype, Option<Ordering>}
1596 impl_ref_variants! {PartialOrd, partial_cmp, $basetype, $type, Option<Ordering>}
1597 };
1598}
1599
1600call_with_all_unsigned_base_types!(trait_partialord_straight, Uint);
1601call_with_all_unsigned_base_types!(trait_partialord_straight, Int);
1602call_with_all_signed_base_types!(trait_partialord_straight, Uint);
1603call_with_all_signed_base_types!(trait_partialord_straight, Int);
1604
1605#[cfg(test)]
1606mod test {
1607 #![allow(clippy::redundant_clone, clippy::cognitive_complexity, clippy::op_ref)]
1608
1609 use super::*;
1610 #[test]
1611 fn test_unsigned() {
1612 println!("Size of Uint: {}", std::mem::size_of::<Uint>());
1613
1614 let eleven = Uint::small(11);
1615 assert_eq!(eleven, 11u8);
1616 assert_eq!(&eleven, 11u8);
1617 assert_eq!(eleven, &11u8);
1618 assert_ne!(eleven, 10u8);
1619 assert_eq!(11u8, eleven);
1620 assert_ne!(10u8, eleven);
1621 assert_eq!(eleven, 11i8);
1622 assert_ne!(eleven, 10i8);
1623 assert_eq!(11i8, eleven);
1624 assert_ne!(10i8, eleven);
1625 assert!(eleven.get_ref().is_left());
1626 assert!(eleven.clone().get_ref().is_left());
1627 assert!(eleven.clone().normalize().get_ref().is_left());
1628
1629 let eleven_pow11 = &eleven
1630 * &eleven
1631 * &eleven
1632 * &eleven
1633 * &eleven
1634 * &eleven
1635 * &eleven
1636 * &eleven
1637 * &eleven
1638 * &eleven
1639 * &eleven;
1640 assert!(eleven_pow11.get_ref().is_right());
1641 assert!(eleven_pow11.clone().get_ref().is_right());
1642 assert!(eleven_pow11.clone().normalize().get_ref().is_right());
1643 assert!(eleven < eleven_pow11);
1644 assert!(&eleven < eleven_pow11);
1645 assert!(eleven < &eleven_pow11);
1646 assert!(11u8 < eleven_pow11);
1647 assert!(11i8 < eleven_pow11);
1648 let eleven_big = Uint::big(BigUint::from(11u8));
1649 let eleven_big_norm = eleven_big.clone().normalize();
1650 let eleven_big_norm_ref = eleven_big.normalize_ref();
1651 assert_eq!(eleven, eleven_big);
1652 assert_eq!(&eleven, eleven_big);
1653 assert_eq!(eleven, &eleven_big);
1654 assert_eq!(eleven, eleven_big_norm);
1655 assert_eq!(eleven, *eleven_big_norm_ref);
1656 assert_eq!(eleven_big.is_stored_as_big(), true);
1657 assert_eq!(eleven_big_norm.is_stored_as_big(), false);
1658 assert_eq!(eleven_big_norm_ref.is_stored_as_big(), false);
1659 let eleven_pow11_norm = eleven_pow11.clone().normalize();
1660 let eleven_pow11_norm_ref = eleven_pow11.normalize_ref();
1661 assert_eq!(eleven_pow11, eleven_pow11_norm);
1662 assert_eq!(eleven_pow11, *eleven_pow11_norm_ref);
1663 assert_eq!(
1664 &eleven_pow11 + &eleven_pow11,
1665 eleven_pow11.checked_add(&eleven_pow11).unwrap()
1666 );
1667
1668 for x in &[
1669 &eleven,
1670 &eleven_pow11,
1671 &eleven_big,
1672 &eleven_big_norm,
1673 &eleven_big_norm_ref,
1674 ] {
1675 let x_big: BigUint = (*x).clone().into_big();
1676
1677 assert_eq!(format!("{}", x), format!("{}", x_big),);
1678 assert_eq!(format!("{:3.2}", x), format!("{:3.2}", x_big),);
1679 assert_eq!(format!("{:b}", x), format!("{:b}", x_big),);
1680 assert_eq!(format!("{:3.2b}", x), format!("{:3.2b}", x_big),);
1681 assert_eq!(format!("{:x}", x), format!("{:x}", x_big),);
1682 assert_eq!(format!("{:3.2x}", x), format!("{:3.2x}", x_big),);
1683 assert_eq!(format!("{:o}", x), format!("{:o}", x_big),);
1684 assert_eq!(format!("{:3.2o}", x), format!("{:3.2o}", x_big),);
1685 }
1686 }
1687 #[test]
1688 fn test_signed() {
1689 println!("Size of Int: {}", std::mem::size_of::<Int>());
1690
1691 let eleven = Int::small(11);
1692 assert_eq!(eleven, 11u8);
1693 assert_eq!(&eleven, 11u8);
1694 assert_eq!(eleven, &11u8);
1695 assert_ne!(eleven, 10u8);
1696 assert_eq!(11u8, eleven);
1697 assert_ne!(10u8, eleven);
1698 assert_eq!(eleven, 11i8);
1699 assert_ne!(eleven, 10i8);
1700 assert_eq!(11i8, eleven);
1701 assert_ne!(10i8, eleven);
1702 assert!(eleven.get_ref().is_left());
1703 assert!(eleven.clone().get_ref().is_left());
1704 assert!(eleven.clone().normalize().get_ref().is_left());
1705
1706 let eleven_pow11 = &eleven
1707 * &eleven
1708 * &eleven
1709 * &eleven
1710 * &eleven
1711 * &eleven
1712 * &eleven
1713 * &eleven
1714 * &eleven
1715 * &eleven
1716 * &eleven;
1717 assert!(eleven_pow11.get_ref().is_right());
1718 assert!(eleven_pow11.clone().get_ref().is_right());
1719 assert!(eleven_pow11.clone().normalize().get_ref().is_right());
1720 assert!(eleven < eleven_pow11);
1721 assert!(&eleven < eleven_pow11);
1722 assert!(eleven < &eleven_pow11);
1723 assert!(-eleven.clone() < eleven_pow11);
1724 assert!(-eleven_pow11.clone() < eleven);
1725 assert!(-eleven_pow11.clone() < -eleven.clone());
1726 assert!(11u8 < eleven_pow11);
1727 assert!(11i8 < eleven_pow11);
1728 assert!(-11i8 < eleven_pow11);
1729 assert!(-eleven_pow11.clone() < 11i8);
1730 assert!(-eleven_pow11.clone() < -11i8);
1731 let eleven_big = Int::big(BigInt::from(11i8));
1732 let eleven_big_norm = eleven_big.clone().normalize();
1733 let eleven_big_norm_ref = eleven_big.normalize_ref();
1734 assert_eq!(eleven, eleven_big);
1735 assert_eq!(&eleven, eleven_big);
1736 assert_eq!(eleven, &eleven_big);
1737 assert_eq!(eleven, eleven_big_norm);
1738 assert_eq!(eleven, *eleven_big_norm_ref);
1739 assert_eq!(eleven_big.is_stored_as_big(), true);
1740 assert_eq!(eleven_big_norm.is_stored_as_big(), false);
1741 assert_eq!(eleven_big_norm_ref.is_stored_as_big(), false);
1742 let eleven_pow11_norm = eleven_pow11.clone().normalize();
1743 let eleven_pow11_norm_ref = eleven_pow11.normalize_ref();
1744 assert_eq!(eleven_pow11, eleven_pow11_norm);
1745 assert_eq!(eleven_pow11, *eleven_pow11_norm_ref);
1746 assert_eq!(
1747 &eleven_pow11 + &eleven_pow11,
1748 eleven_pow11.checked_add(&eleven_pow11).unwrap()
1749 );
1750
1751 for x in &[
1752 &eleven,
1753 &eleven_pow11,
1754 &eleven_big,
1755 &eleven_big_norm,
1756 &eleven_big_norm_ref,
1757 ] {
1758 let x_big: BigInt = (*x).clone().into_big();
1759
1760 assert_eq!(format!("{}", x), format!("{}", x_big),);
1761 assert_eq!(format!("{:3.2}", x), format!("{:3.2}", x_big),);
1762 assert_eq!(format!("{:b}", x), format!("{:b}", x_big),);
1763 assert_eq!(format!("{:3.2b}", x), format!("{:3.2b}", x_big),);
1764 assert_eq!(format!("{:x}", x), format!("{:x}", x_big),);
1765 assert_eq!(format!("{:3.2x}", x), format!("{:3.2x}", x_big),);
1766 assert_eq!(format!("{:o}", x), format!("{:o}", x_big),);
1767 assert_eq!(format!("{:3.2o}", x), format!("{:3.2o}", x_big),);
1768 }
1769 }
1770}