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 ] |
14 | 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 ] |
30 | fn bitand(mut self, other: &BigUint) -> BigUint { |
31 | self &= other; |
32 | self |
33 | } |
34 | } |
35 | impl BitAndAssign<&BigUint> for BigUint { |
36 | #[inline ] |
37 | fn bitand_assign(&mut self, other: &BigUint) { |
38 | for (ai: &mut u64, &bi: u64) 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 | |
52 | fn bitor(mut self, other: &BigUint) -> BigUint { |
53 | self |= other; |
54 | self |
55 | } |
56 | } |
57 | impl BitOrAssign<&BigUint> for BigUint { |
58 | #[inline ] |
59 | fn bitor_assign(&mut self, other: &BigUint) { |
60 | for (ai: &mut u64, &bi: u64) in self.data.iter_mut().zip(other.data.iter()) { |
61 | *ai |= bi; |
62 | } |
63 | if other.data.len() > self.data.len() { |
64 | let extra: &[u64] = &other.data[self.data.len()..]; |
65 | self.data.extend(iter: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 | |
76 | fn bitxor(mut self, other: &BigUint) -> BigUint { |
77 | self ^= other; |
78 | self |
79 | } |
80 | } |
81 | impl BitXorAssign<&BigUint> for BigUint { |
82 | #[inline ] |
83 | fn bitxor_assign(&mut self, other: &BigUint) { |
84 | for (ai: &mut u64, &bi: u64) in self.data.iter_mut().zip(other.data.iter()) { |
85 | *ai ^= bi; |
86 | } |
87 | if other.data.len() > self.data.len() { |
88 | let extra: &[u64] = &other.data[self.data.len()..]; |
89 | self.data.extend(iter:extra.iter().cloned()); |
90 | } |
91 | self.normalize(); |
92 | } |
93 | } |
94 | |