1 use super::{BigUint, IntDigits};
2 
3 use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
4 
5 forward_val_val_binop!(impl BitAnd for BigUint, bitand);
6 forward_ref_val_binop!(impl BitAnd for BigUint, bitand);
7 
8 // do not use forward_ref_ref_binop_commutative! for bitand so that we can
9 // clone the smaller value rather than the larger, avoiding over-allocation
10 impl BitAnd<&BigUint> for &BigUint {
11     type Output = BigUint;
12 
13     #[inline]
bitand(self, other: &BigUint) -> BigUint14     fn bitand(self, other: &BigUint) -> BigUint {
15         // forward to val-ref, choosing the smaller to clone
16         if self.data.len() <= other.data.len() {
17             self.clone() & other
18         } else {
19             other.clone() & self
20         }
21     }
22 }
23 
24 forward_val_assign!(impl BitAndAssign for BigUint, bitand_assign);
25 
26 impl BitAnd<&BigUint> for BigUint {
27     type Output = BigUint;
28 
29     #[inline]
bitand(mut self, other: &BigUint) -> BigUint30     fn bitand(mut self, other: &BigUint) -> BigUint {
31         self &= other;
32         self
33     }
34 }
35 impl BitAndAssign<&BigUint> for BigUint {
36     #[inline]
bitand_assign(&mut self, other: &BigUint)37     fn bitand_assign(&mut self, other: &BigUint) {
38         for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) {
39             *ai &= bi;
40         }
41         self.data.truncate(other.data.len());
42         self.normalize();
43     }
44 }
45 
46 forward_all_binop_to_val_ref_commutative!(impl BitOr for BigUint, bitor);
47 forward_val_assign!(impl BitOrAssign for BigUint, bitor_assign);
48 
49 impl BitOr<&BigUint> for BigUint {
50     type Output = BigUint;
51 
bitor(mut self, other: &BigUint) -> BigUint52     fn bitor(mut self, other: &BigUint) -> BigUint {
53         self |= other;
54         self
55     }
56 }
57 impl BitOrAssign<&BigUint> for BigUint {
58     #[inline]
bitor_assign(&mut self, other: &BigUint)59     fn bitor_assign(&mut self, other: &BigUint) {
60         for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) {
61             *ai |= bi;
62         }
63         if other.data.len() > self.data.len() {
64             let extra = &other.data[self.data.len()..];
65             self.data.extend(extra.iter().cloned());
66         }
67     }
68 }
69 
70 forward_all_binop_to_val_ref_commutative!(impl BitXor for BigUint, bitxor);
71 forward_val_assign!(impl BitXorAssign for BigUint, bitxor_assign);
72 
73 impl BitXor<&BigUint> for BigUint {
74     type Output = BigUint;
75 
bitxor(mut self, other: &BigUint) -> BigUint76     fn bitxor(mut self, other: &BigUint) -> BigUint {
77         self ^= other;
78         self
79     }
80 }
81 impl BitXorAssign<&BigUint> for BigUint {
82     #[inline]
bitxor_assign(&mut self, other: &BigUint)83     fn bitxor_assign(&mut self, other: &BigUint) {
84         for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) {
85             *ai ^= bi;
86         }
87         if other.data.len() > self.data.len() {
88             let extra = &other.data[self.data.len()..];
89             self.data.extend(extra.iter().cloned());
90         }
91         self.normalize();
92     }
93 }
94