num_bigint/biguint/
bits.rs

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