1use crate::digit;
2use crate::ExpType;
3use core::ops::{
4 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
5 Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
6};
7
8macro_rules! ops {
9 ($BUint: ident, $BInt: ident, $Digit: ident) => {
10 impl<const N: usize> Add<$Digit> for $BUint<N> {
11 type Output = Self;
12
13 #[inline]
14 fn add(self, rhs: $Digit) -> Self {
15 let mut out = self;
16 let result = digit::$Digit::carrying_add(out.digits[0], rhs, false);
17 out.digits[0] = result.0;
18 let mut carry = result.1;
19 let mut i = 1;
20 while i < N && carry {
21 let result = out.digits[i].overflowing_add(1);
22 out.digits[i] = result.0;
23 carry = result.1;
24 i += 1;
25 }
26 out
27 }
28 }
29
30 impl<const N: usize> BitAnd for $BUint<N> {
31 type Output = Self;
32
33 #[inline]
34 fn bitand(self, rhs: Self) -> Self {
35 Self::bitand(self, rhs)
36 }
37 }
38
39 impl<const N: usize> BitOr for $BUint<N> {
40 type Output = Self;
41
42 #[inline]
43 fn bitor(self, rhs: Self) -> Self {
44 Self::bitor(self, rhs)
45 }
46 }
47
48 impl<const N: usize> BitXor for $BUint<N> {
49 type Output = Self;
50
51 #[inline]
52 fn bitxor(self, rhs: Self) -> Self {
53 Self::bitxor(self, rhs)
54 }
55 }
56
57 impl<const N: usize> Div for $BUint<N> {
58 type Output = Self;
59
60 #[inline]
61 fn div(self, rhs: Self) -> Self {
62 Self::div(self, rhs)
63 }
64 }
65
66 impl<const N: usize> Div<$Digit> for $BUint<N> {
67 type Output = Self;
68
69 #[inline]
70 fn div(self, rhs: $Digit) -> Self {
71 self.div_rem_digit(rhs).0
72 }
73 }
74
75 impl<const N: usize> Not for $BUint<N> {
76 type Output = Self;
77
78 #[inline]
79 fn not(self) -> Self {
80 Self::not(self)
81 }
82 }
83
84 impl<const N: usize> Rem for $BUint<N> {
85 type Output = Self;
86
87 #[inline]
88 fn rem(self, rhs: Self) -> Self {
89 Self::rem(self, rhs)
90 }
91 }
92
93 impl<const N: usize> Rem<$Digit> for $BUint<N> {
94 type Output = $Digit;
95
96 #[inline]
97 fn rem(self, rhs: $Digit) -> $Digit {
98 self.div_rem_digit(rhs).1
99 }
100 }
101
102 crate::int::ops::impls!($BUint, $BUint, $BInt);
103
104 #[cfg(all(test, test_int_bits = "64"))]
105 paste::paste! {
106 mod [<$Digit _add_digit_test>] {
107 use super::*;
108 use crate::test::{test_bignum, types::utest};
109 use crate::test::types::big_types::$Digit::*;
110
111 quickcheck::quickcheck! {
112 fn add_digit(a: utest, b: $Digit) -> quickcheck::TestResult {
113 use crate::cast::As;
114
115 let c: utest = b.as_();
116 match a.checked_add(c) {
117 None => quickcheck::TestResult::discard(),
118 Some(_d) => {
119 let e: UTEST = b.as_();
120 let f: UTEST = a.as_();
121 quickcheck::TestResult::from_bool(f + e == f + b)
122 }
123 }
124 }
125 }
126 }
127 }
128 };
129}
130
131#[cfg(test)]
132crate::test::all_digit_tests! {
133 use crate::test::{test_bignum, types::utest};
134
135 crate::int::ops::tests!(utest);
136}
137
138crate::macro_impl!(ops);