Skip to main content

crypto_bigint/uint/
bit_or.rs

1//! [`Uint`] bitwise OR operations.
2
3use super::Uint;
4use crate::{BitOr, BitOrAssign, CtOption, Limb};
5
6impl<const LIMBS: usize> Uint<LIMBS> {
7    /// Computes bitwise `a | b`.
8    #[inline(always)]
9    #[must_use]
10    pub const fn bitor(&self, rhs: &Self) -> Self {
11        let mut limbs = [Limb::ZERO; LIMBS];
12        let mut i = 0;
13
14        while i < LIMBS {
15            limbs[i] = self.limbs[i].bitor(rhs.limbs[i]);
16            i += 1;
17        }
18
19        Self { limbs }
20    }
21
22    /// Perform wrapping bitwise `OR`.
23    ///
24    /// There's no way wrapping could ever happen.
25    /// This function exists so that all operations are accounted for in the wrapping operations
26    #[must_use]
27    pub const fn wrapping_or(&self, rhs: &Self) -> Self {
28        self.bitor(rhs)
29    }
30
31    /// Perform checked bitwise `OR`, returning a [`CtOption`] which `is_some` always
32    #[must_use]
33    pub const fn checked_or(&self, rhs: &Self) -> CtOption<Self> {
34        CtOption::some(self.bitor(rhs))
35    }
36}
37
38impl<const LIMBS: usize> BitOr for Uint<LIMBS> {
39    type Output = Self;
40
41    fn bitor(self, rhs: Self) -> Uint<LIMBS> {
42        self.bitor(&rhs)
43    }
44}
45
46impl<const LIMBS: usize> BitOr<&Uint<LIMBS>> for Uint<LIMBS> {
47    type Output = Uint<LIMBS>;
48
49    #[allow(clippy::needless_borrow)]
50    fn bitor(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
51        (&self).bitor(rhs)
52    }
53}
54
55impl<const LIMBS: usize> BitOr<Uint<LIMBS>> for &Uint<LIMBS> {
56    type Output = Uint<LIMBS>;
57
58    fn bitor(self, rhs: Uint<LIMBS>) -> Uint<LIMBS> {
59        self.bitor(&rhs)
60    }
61}
62
63impl<const LIMBS: usize> BitOr<&Uint<LIMBS>> for &Uint<LIMBS> {
64    type Output = Uint<LIMBS>;
65
66    fn bitor(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
67        self.bitor(rhs)
68    }
69}
70
71impl<const LIMBS: usize> BitOrAssign for Uint<LIMBS> {
72    fn bitor_assign(&mut self, other: Self) {
73        *self = *self | other;
74    }
75}
76
77impl<const LIMBS: usize> BitOrAssign<&Uint<LIMBS>> for Uint<LIMBS> {
78    fn bitor_assign(&mut self, other: &Self) {
79        *self = *self | other;
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use crate::U128;
86
87    #[test]
88    fn checked_or_ok() {
89        let result = U128::ZERO.checked_or(&U128::ONE);
90        assert_eq!(result.unwrap(), U128::ONE);
91    }
92
93    #[test]
94    fn overlapping_or_ok() {
95        let result = U128::MAX.wrapping_or(&U128::ONE);
96        assert_eq!(result, U128::MAX);
97    }
98}