num_bigint/biguint/
bits.rs

1use super::{BigUint, IntDigits};
2
3use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
4
5forward_val_val_binop!(impl BitAnd for BigUint, bitand);
6forward_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
10impl<'a, 'b> BitAnd<&'b BigUint> for &'a 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
24forward_val_assign!(impl BitAndAssign for BigUint, bitand_assign);
25
26impl<'a> BitAnd<&'a 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}
35impl<'a> BitAndAssign<&'a BigUint> for BigUint {
36    #[inline]
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
46forward_all_binop_to_val_ref_commutative!(impl BitOr for BigUint, bitor);
47forward_val_assign!(impl BitOrAssign for BigUint, bitor_assign);
48
49impl<'a> BitOr<&'a BigUint> for BigUint {
50    type Output = BigUint;
51
52    fn bitor(mut self, other: &BigUint) -> BigUint {
53        self |= other;
54        self
55    }
56}
57impl<'a> BitOrAssign<&'a BigUint> for BigUint {
58    #[inline]
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
70forward_all_binop_to_val_ref_commutative!(impl BitXor for BigUint, bitxor);
71forward_val_assign!(impl BitXorAssign for BigUint, bitxor_assign);
72
73impl<'a> BitXor<&'a BigUint> for BigUint {
74    type Output = BigUint;
75
76    fn bitxor(mut self, other: &BigUint) -> BigUint {
77        self ^= other;
78        self
79    }
80}
81impl<'a> BitXorAssign<&'a BigUint> for BigUint {
82    #[inline]
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}