crypto_bigint/int/
bit_or.rs

1//! [`Int`] bitwise OR operations.
2
3use core::ops::{BitOr, BitOrAssign};
4
5use crate::{ConstCtOption, Uint, Wrapping};
6
7use super::Int;
8
9impl<const LIMBS: usize> Int<LIMBS> {
10    /// Computes bitwise `a & b`.
11    #[inline(always)]
12    pub const fn bitor(&self, rhs: &Self) -> Self {
13        Self(Uint::bitor(&self.0, &rhs.0))
14    }
15
16    /// Perform wrapping bitwise `OR`.
17    ///
18    /// There's no way wrapping could ever happen.
19    /// This function exists so that all operations are accounted for in the wrapping operations
20    pub const fn wrapping_or(&self, rhs: &Self) -> Self {
21        self.bitor(rhs)
22    }
23
24    /// Perform checked bitwise `OR`, returning a [`ConstCtOption`] which `is_some` always
25    pub const fn checked_or(&self, rhs: &Self) -> ConstCtOption<Self> {
26        ConstCtOption::some(self.bitor(rhs))
27    }
28}
29
30impl<const LIMBS: usize> BitOr for Int<LIMBS> {
31    type Output = Self;
32
33    fn bitor(self, rhs: Self) -> Int<LIMBS> {
34        self.bitor(&rhs)
35    }
36}
37
38impl<const LIMBS: usize> BitOr<&Int<LIMBS>> for Int<LIMBS> {
39    type Output = Int<LIMBS>;
40
41    #[allow(clippy::needless_borrow)]
42    fn bitor(self, rhs: &Int<LIMBS>) -> Int<LIMBS> {
43        (&self).bitor(rhs)
44    }
45}
46
47impl<const LIMBS: usize> BitOr<Int<LIMBS>> for &Int<LIMBS> {
48    type Output = Int<LIMBS>;
49
50    fn bitor(self, rhs: Int<LIMBS>) -> Int<LIMBS> {
51        self.bitor(&rhs)
52    }
53}
54
55impl<const LIMBS: usize> BitOr<&Int<LIMBS>> for &Int<LIMBS> {
56    type Output = Int<LIMBS>;
57
58    fn bitor(self, rhs: &Int<LIMBS>) -> Int<LIMBS> {
59        self.bitor(rhs)
60    }
61}
62
63impl<const LIMBS: usize> BitOrAssign for Int<LIMBS> {
64    fn bitor_assign(&mut self, other: Self) {
65        *self = *self | other;
66    }
67}
68
69impl<const LIMBS: usize> BitOrAssign<&Int<LIMBS>> for Int<LIMBS> {
70    fn bitor_assign(&mut self, other: &Self) {
71        *self = *self | other;
72    }
73}
74
75impl<const LIMBS: usize> BitOr for Wrapping<Int<LIMBS>> {
76    type Output = Self;
77
78    fn bitor(self, rhs: Self) -> Wrapping<Int<LIMBS>> {
79        Wrapping(self.0.bitor(&rhs.0))
80    }
81}
82
83impl<const LIMBS: usize> BitOr<&Wrapping<Int<LIMBS>>> for Wrapping<Int<LIMBS>> {
84    type Output = Wrapping<Int<LIMBS>>;
85
86    fn bitor(self, rhs: &Wrapping<Int<LIMBS>>) -> Wrapping<Int<LIMBS>> {
87        Wrapping(self.0.bitor(&rhs.0))
88    }
89}
90
91impl<const LIMBS: usize> BitOr<Wrapping<Int<LIMBS>>> for &Wrapping<Int<LIMBS>> {
92    type Output = Wrapping<Int<LIMBS>>;
93
94    fn bitor(self, rhs: Wrapping<Int<LIMBS>>) -> Wrapping<Int<LIMBS>> {
95        Wrapping(self.0.bitor(&rhs.0))
96    }
97}
98
99impl<const LIMBS: usize> BitOr<&Wrapping<Int<LIMBS>>> for &Wrapping<Int<LIMBS>> {
100    type Output = Wrapping<Int<LIMBS>>;
101
102    fn bitor(self, rhs: &Wrapping<Int<LIMBS>>) -> Wrapping<Int<LIMBS>> {
103        Wrapping(self.0.bitor(&rhs.0))
104    }
105}
106
107impl<const LIMBS: usize> BitOrAssign for Wrapping<Int<LIMBS>> {
108    fn bitor_assign(&mut self, other: Self) {
109        *self = *self | other;
110    }
111}
112
113impl<const LIMBS: usize> BitOrAssign<&Wrapping<Int<LIMBS>>> for Wrapping<Int<LIMBS>> {
114    fn bitor_assign(&mut self, other: &Self) {
115        *self = *self | other;
116    }
117}
118
119#[cfg(test)]
120mod tests {
121    use crate::I128;
122
123    #[test]
124    fn checked_or_ok() {
125        assert_eq!(I128::ZERO.checked_or(&I128::ONE).unwrap(), I128::ONE);
126        assert_eq!(I128::ONE.checked_or(&I128::ONE).unwrap(), I128::ONE);
127        assert_eq!(I128::MAX.checked_or(&I128::ONE).unwrap(), I128::MAX);
128    }
129
130    #[test]
131    fn wrapping_or_ok() {
132        assert_eq!(I128::ZERO.wrapping_or(&I128::ONE), I128::ONE);
133        assert_eq!(I128::ONE.wrapping_or(&I128::ONE), I128::ONE);
134        assert_eq!(I128::MAX.wrapping_or(&I128::ONE), I128::MAX);
135    }
136}