crate::ix!();
#[macro_export]
macro_rules! define_baseuint_bitor {
($uint_type:ident, $bits:expr, $limbs:expr) => {
impl core::ops::BitOrAssign<&$uint_type> for $uint_type {
#[inline]
fn bitor_assign(&mut self, b: &$uint_type) {
for i in 0..$limbs {
self.pn[i] |= b.pn[i];
}
}
}
impl core::ops::BitOrAssign<u64> for $uint_type {
#[inline]
fn bitor_assign(&mut self, b: u64) {
self.pn[0] |= (b & 0xffff_ffff) as u32;
if $limbs > 1 {
self.pn[1] |= ((b >> 32) & 0xffff_ffff) as u32;
}
}
}
impl core::ops::BitOr<&$uint_type> for $uint_type {
type Output = $uint_type;
fn bitor(self, other: &$uint_type) -> Self::Output {
let mut ret = self.clone();
ret |= other;
ret
}
}
}
}
#[cfg(test)]
mod base_uint_bitor_exhaustive_tests {
use super::*;
#[traced_test]
fn test_bitor_32_bits_edge_cases() {
info!("Testing bitwise OR (`|=`) for 32-bit BaseUInt edge cases.");
type U32 = BaseUInt32;
let mut x = U32::default();
let y = U32::default();
x |= &y;
debug!("(0 | 0) => 0x{:08X}", x.pn[0]);
assert_eq!(x.pn[0], 0);
let mut a = U32::default();
a |= 0x1234_5678_9ABC_DEF0u64; assert_eq!(a.pn[0], 0x9ABC_DEF0);
let mut b = U32::default();
b.pn[0] = 0xFFFF_FFFF;
let c = U32::default(); b |= &c; assert_eq!(b.pn[0], 0xFFFF_FFFF);
let mut d = U32::default();
d.pn[0] = 0x1234_0000;
let mut e = U32::default();
e.pn[0] = 0x0000_9999;
d |= &e;
debug!("(0x12340000 | 0x00009999) => 0x{:08X}", d.pn[0]);
assert_eq!(d.pn[0], 0x1234_9999);
info!("32-bit OR edge-case tests passed.");
}
#[traced_test]
fn test_bitor_64_bits_edge_cases() {
info!("Testing bitwise OR for 64-bit BaseUInt edge cases.");
type U64B = BaseUInt64;
let mut x = U64B::default();
let y = U64B::default();
x |= &y;
assert_eq!(x.pn, [0, 0]);
let mut a = U64B::default();
a |= 0x1122_3344_5566_7788u64;
debug!("a |= 0x1122334455667788 => pn[0]={:08X}, pn[1]={:08X}", a.pn[0], a.pn[1]);
assert_eq!(a.pn[0], 0x5566_7788);
assert_eq!(a.pn[1], 0x1122_3344);
let mut b = U64B::default();
b.pn[0] = 0xFFFF_0000;
let mut c = U64B::default();
c.pn[0] = 0x0000_FFFF;
b |= &c;
debug!("(0xFFFF0000 | 0x0000FFFF) => pn[0]=0x{:08X}, pn[1]=0x{:08X}", b.pn[0], b.pn[1]);
assert_eq!(b.pn[0], 0xFFFF_FFFF);
assert_eq!(b.pn[1], 0);
let mut d = U64B::default();
d.pn[0] = 0x1234_0000;
d.pn[1] = 0x0000_0001;
let mut e = U64B::default();
e.pn[0] = 0x0000_5678;
e.pn[1] = 0x0000_0002;
d |= &e;
debug!("d OR e => d={:?}", d);
assert_eq!(d.pn[0], 0x1234_5678);
assert_eq!(d.pn[1], 0x0000_0003);
info!("64-bit OR edge-case tests passed.");
}
#[traced_test]
fn test_bitor_256_bits_edge_cases() {
info!("Testing bitwise OR for 256-bit BaseUInt edge cases.");
type U256 = BaseUInt256;
let mut x = U256::default();
let y = U256::default();
x |= &y;
assert!(x.pn.iter().all(|&limb| limb == 0), "All limbs zero after 0|0");
let mut a = U256::default();
a.pn[0] = 0xAAAA_AAAA;
a.pn[1] = 0x0000_FFFF;
a.pn[2] = 0;
a.pn[3] = 0x1234_0000;
a.pn[7] = 0xFFFF_0000;
let mut b = U256::default();
b.pn[0] = 0x5555_5555;
b.pn[1] = 0xFFFF_0000;
b.pn[2] = 0xFFFF_FFFF;
b.pn[3] = 0x0000_5678;
a |= &b;
assert_eq!(a.pn[0], 0xFFFF_FFFF); assert_eq!(a.pn[1], 0xFFFF_FFFF); assert_eq!(a.pn[2], 0xFFFF_FFFF);
assert_eq!(a.pn[3], 0x1234_5678);
assert_eq!(a.pn[7], 0xFFFF_0000);
let mut c = U256::default();
c.pn[4] = 0xAAAA_BBBB; c |= 0x1122_3344_5566_7788u64;
assert_eq!(c.pn[0], 0x5566_7788);
assert_eq!(c.pn[1], 0x1122_3344);
assert_eq!(c.pn[4], 0xAAAA_BBBB);
info!("256-bit OR edge-case tests passed.");
}
#[traced_test]
fn test_bitor_random_64_and_256() {
info!("Testing bitwise OR with random data in 64-bit & 256-bit BaseUInt.");
let mut rng = SimpleLCG::new(0x1122_3344_5566_7788);
for _ in 0..50 {
let a_val = rng.next_u64();
let b_val = rng.next_u64();
let expected64 = a_val | b_val;
let mut a_bu = BaseUInt64::default();
a_bu.pn[0] = (a_val & 0xFFFF_FFFF) as u32;
a_bu.pn[1] = ((a_val >> 32) & 0xFFFF_FFFF) as u32;
a_bu |= b_val;
let got64 = ((a_bu.pn[1] as u64) << 32) | (a_bu.pn[0] as u64);
assert_eq!(got64, expected64, "64-bit random OR mismatch");
}
for _ in 0..50 {
let a0 = rng.next_u64();
let a1 = rng.next_u64();
let a2 = rng.next_u64();
let a3 = rng.next_u64();
let b0 = rng.next_u64();
let b1 = rng.next_u64();
let b2 = rng.next_u64();
let b3 = rng.next_u64();
let r0 = a0 | b0;
let r1 = a1 | b1;
let r2 = a2 | b2;
let r3 = a3 | b3;
let mut a_bu = BaseUInt256::default();
a_bu.pn[0] = (a0 & 0xFFFF_FFFF) as u32;
a_bu.pn[1] = ((a0 >> 32) & 0xFFFF_FFFF) as u32;
a_bu.pn[2] = (a1 & 0xFFFF_FFFF) as u32;
a_bu.pn[3] = ((a1 >> 32) & 0xFFFF_FFFF) as u32;
a_bu.pn[4] = (a2 & 0xFFFF_FFFF) as u32;
a_bu.pn[5] = ((a2 >> 32) & 0xFFFF_FFFF) as u32;
a_bu.pn[6] = (a3 & 0xFFFF_FFFF) as u32;
a_bu.pn[7] = ((a3 >> 32) & 0xFFFF_FFFF) as u32;
let mut b_bu = BaseUInt256::default();
b_bu.pn[0] = (b0 & 0xFFFF_FFFF) as u32;
b_bu.pn[1] = ((b0 >> 32) & 0xFFFF_FFFF) as u32;
b_bu.pn[2] = (b1 & 0xFFFF_FFFF) as u32;
b_bu.pn[3] = ((b1 >> 32) & 0xFFFF_FFFF) as u32;
b_bu.pn[4] = (b2 & 0xFFFF_FFFF) as u32;
b_bu.pn[5] = ((b2 >> 32) & 0xFFFF_FFFF) as u32;
b_bu.pn[6] = (b3 & 0xFFFF_FFFF) as u32;
b_bu.pn[7] = ((b3 >> 32) & 0xFFFF_FFFF) as u32;
a_bu |= &b_bu;
let rr0 = ((a_bu.pn[1] as u64) << 32) | (a_bu.pn[0] as u64);
let rr1 = ((a_bu.pn[3] as u64) << 32) | (a_bu.pn[2] as u64);
let rr2 = ((a_bu.pn[5] as u64) << 32) | (a_bu.pn[4] as u64);
let rr3 = ((a_bu.pn[7] as u64) << 32) | (a_bu.pn[6] as u64);
assert_eq!(rr0, r0, "256-bit random OR mismatch in limb0");
assert_eq!(rr1, r1, "256-bit random OR mismatch in limb1");
assert_eq!(rr2, r2, "256-bit random OR mismatch in limb2");
assert_eq!(rr3, r3, "256-bit random OR mismatch in limb3");
}
info!("Random OR tests for 64-bit & 256-bit completed successfully.");
}
#[traced_test]
fn test_bitor_operator_new() {
info!("Testing `self | &other => new BaseUInt` with a few small examples.");
let x = {
let mut tmp = BaseUInt64::default();
tmp.pn[0] = 0xFFFF_0000;
tmp
};
let y = {
let mut tmp = BaseUInt64::default();
tmp.pn[0] = 0x1234_5678;
tmp
};
let z = x | &y;
assert_eq!(z.pn[0], 0xFFFF_5678);
assert_eq!(z.pn[1], 0);
{
let mut x32 = BaseUInt32::default();
x32.pn[0] = 0xA5A5_A5A5;
let mut y32 = BaseUInt32::default();
y32.pn[0] = 0x0F0F_0F0F;
let z32 = x32 | &y32;
assert_eq!(z32.pn[0], 0xAFAF_AFAF);
}
info!("`BitOr` operator returning a new BaseUInt tested OK.");
}
}