use std::iter::Peekable;
use crate::BitRead;
pub struct BitSetUnion<'a, A: BitRead, B: BitRead> {
a: &'a A,
b: &'a B,
}
impl<'a, A: BitRead, B: BitRead> BitSetUnion<'a, A, B> {
pub fn new(a: &'a A, b: &'a B) -> Self {
Self { a, b }
}
}
impl<'a, A: BitRead, B: BitRead> BitRead for BitSetUnion<'a, A, B> {
type Iter<'b>
= BitSetUnionIter<'b, A, B>
where
Self: 'b;
fn len(&self) -> usize {
self.a.len()
}
fn test(&self, idx: usize) -> bool {
self.a.test(idx) || self.b.test(idx)
}
fn iter(&self) -> Self::Iter<'_> {
BitSetUnionIter {
a: self.a.iter().peekable(),
b: self.b.iter().peekable(),
}
}
}
pub struct BitSetUnionIter<'a, A: BitRead + 'a, B: BitRead + 'a> {
a: Peekable<<A as BitRead>::Iter<'a>>,
b: Peekable<<B as BitRead>::Iter<'a>>,
}
impl<'a, A: BitRead, B: BitRead> Iterator for BitSetUnionIter<'a, A, B> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
match (self.a.peek(), self.b.peek()) {
(None, None) => None,
(None, Some(_)) => self.b.next(),
(Some(_), None) => self.a.next(),
(Some(a), Some(b)) => {
if a < b {
self.a.next()
} else if a > b {
self.b.next()
} else {
let result = self.a.next();
let _ = self.b.next();
result
}
}
}
}
}
pub struct BitSetIntersection<'a, A: BitRead, B: BitRead> {
a: &'a A,
b: &'a B,
}
impl<'a, A: BitRead, B: BitRead> BitSetIntersection<'a, A, B> {
pub fn new(a: &'a A, b: &'a B) -> Self {
Self { a, b }
}
}
impl<'a, A: BitRead, B: BitRead> BitRead for BitSetIntersection<'a, A, B> {
type Iter<'b>
= BitSetIntersectionIter<'b, A, B>
where
Self: 'b;
fn len(&self) -> usize {
self.a.len()
}
fn test(&self, idx: usize) -> bool {
self.a.test(idx) && self.b.test(idx)
}
fn iter(&self) -> Self::Iter<'_> {
BitSetIntersectionIter {
a: self.a.iter().peekable(),
b: self.b.iter().peekable(),
}
}
}
pub struct BitSetIntersectionIter<'a, A: BitRead + 'a, B: BitRead + 'a> {
a: Peekable<<A as BitRead>::Iter<'a>>,
b: Peekable<<B as BitRead>::Iter<'a>>,
}
impl<'a, A: BitRead, B: BitRead> Iterator for BitSetIntersectionIter<'a, A, B> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
loop {
match (self.a.peek(), self.b.peek()) {
(Some(a), Some(b)) => {
if a < b {
let _ = self.a.next();
} else if a > b {
let _ = self.b.next();
} else {
let result = self.a.next();
let _ = self.b.next();
return result;
}
}
_ => return None,
}
}
}
}
pub struct BitSetSymmetricDifference<'a, A: BitRead, B: BitRead> {
a: &'a A,
b: &'a B,
}
impl<'a, A: BitRead, B: BitRead> BitSetSymmetricDifference<'a, A, B> {
pub fn new(a: &'a A, b: &'a B) -> Self {
Self { a, b }
}
}
impl<'a, A: BitRead, B: BitRead> BitRead for BitSetSymmetricDifference<'a, A, B> {
type Iter<'b>
= BitSetSymmetricDifferenceIter<'b, A, B>
where
Self: 'b;
fn len(&self) -> usize {
self.a.len()
}
fn test(&self, idx: usize) -> bool {
self.a.test(idx) != self.b.test(idx)
}
fn iter(&self) -> Self::Iter<'_> {
BitSetSymmetricDifferenceIter {
a: self.a.iter().peekable(),
b: self.b.iter().peekable(),
}
}
}
pub struct BitSetSymmetricDifferenceIter<'a, A: BitRead + 'a, B: BitRead + 'a> {
a: Peekable<<A as BitRead>::Iter<'a>>,
b: Peekable<<B as BitRead>::Iter<'a>>,
}
impl<'a, A: BitRead, B: BitRead> Iterator for BitSetSymmetricDifferenceIter<'a, A, B> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
loop {
match (self.a.peek(), self.b.peek()) {
(None, None) => return None,
(None, Some(_)) => return self.b.next(),
(Some(_), None) => return self.a.next(),
(Some(a), Some(b)) => {
if a < b {
return self.a.next();
} else if a > b {
return self.b.next();
} else {
let _ = self.a.next();
let _ = self.b.next();
}
}
}
}
}
}
pub struct BitSetDifference<'a, A: BitRead, B: BitRead> {
a: &'a A,
b: &'a B,
}
impl<'a, A: BitRead, B: BitRead> BitSetDifference<'a, A, B> {
pub fn new(a: &'a A, b: &'a B) -> Self {
Self { a, b }
}
}
impl<'a, A: BitRead, B: BitRead> BitRead for BitSetDifference<'a, A, B> {
type Iter<'c>
= BitSetDifferenceIter<'c, A, B>
where
Self: 'c;
fn len(&self) -> usize {
self.a.len()
}
fn test(&self, idx: usize) -> bool {
self.a.test(idx) && !self.b.test(idx)
}
fn iter(&self) -> Self::Iter<'_> {
BitSetDifferenceIter {
a: self.a.iter().peekable(),
b: self.b.iter().peekable(),
}
}
}
pub struct BitSetDifferenceIter<'a, A: BitRead + 'a, B: BitRead + 'a> {
a: Peekable<<A as BitRead>::Iter<'a>>,
b: Peekable<<B as BitRead>::Iter<'a>>,
}
impl<'a, A: BitRead, B: BitRead> Iterator for BitSetDifferenceIter<'a, A, B> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
loop {
match (self.a.peek(), self.b.peek()) {
(None, _) => return None, (Some(_), None) => return self.a.next(), (Some(a), Some(b)) => {
if a < b {
return self.a.next();
} else if a > b {
let _ = self.b.next();
} else {
let _ = self.a.next();
let _ = self.b.next();
}
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{BitVec, BitWrite};
#[test]
fn test_bitset_union() {
let mut bv1 = BitVec::<u32>::new(64);
let mut bv2 = BitVec::<u32>::new(64);
for i in 0..64 {
if i % 2 == 0 {
bv1.set(i);
}
}
for i in 0..64 {
if i % 3 == 0 {
bv2.set(i);
}
}
let union = BitSetUnion::new(&bv1, &bv2);
assert!(union.test(0)); assert!(union.test(2)); assert!(union.test(3)); assert!(union.test(6)); assert!(!union.test(1));
let union_bits: Vec<usize> = union.iter().collect();
let mut expected_bits = Vec::new();
for i in 0..64 {
if i % 2 == 0 || i % 3 == 0 {
expected_bits.push(i);
}
}
assert_eq!(union_bits, expected_bits);
}
#[test]
fn test_bitset_intersection() {
let mut bv1 = BitVec::<u32>::new(64);
let mut bv2 = BitVec::<u32>::new(64);
for i in 0..64 {
if i % 2 == 0 {
bv1.set(i);
}
}
for i in 0..64 {
if i % 3 == 0 {
bv2.set(i);
}
}
let intersection = BitSetIntersection::new(&bv1, &bv2);
assert!(intersection.test(0)); assert!(!intersection.test(2)); assert!(!intersection.test(3)); assert!(intersection.test(6)); assert!(!intersection.test(1));
let intersection_bits: Vec<usize> = intersection.iter().collect();
let mut expected_bits = Vec::new();
for i in 0..64 {
if i % 2 == 0 && i % 3 == 0 {
expected_bits.push(i);
}
}
assert_eq!(intersection_bits, expected_bits);
}
#[test]
fn test_bitset_symmetric_difference() {
let mut bv1 = BitVec::<u32>::new(64);
let mut bv2 = BitVec::<u32>::new(64);
for i in 0..64 {
if i % 2 == 0 {
bv1.set(i);
}
}
for i in 0..64 {
if i % 3 == 0 {
bv2.set(i);
}
}
let sym_diff = BitSetSymmetricDifference::new(&bv1, &bv2);
assert!(!sym_diff.test(0)); assert!(sym_diff.test(2)); assert!(sym_diff.test(3)); assert!(!sym_diff.test(6)); assert!(!sym_diff.test(1));
let sym_diff_bits: Vec<usize> = sym_diff.iter().collect();
let mut expected_bits = Vec::new();
for i in 0..64 {
if (i % 2 == 0) != (i % 3 == 0) {
expected_bits.push(i);
}
}
assert_eq!(sym_diff_bits, expected_bits);
}
#[test]
fn test_bitset_difference() {
let mut bv1 = BitVec::<u32>::new(64);
let mut bv2 = BitVec::<u32>::new(64);
for i in 0..64 {
if i % 2 == 0 {
bv1.set(i);
}
}
for i in 0..64 {
if i % 3 == 0 {
bv2.set(i);
}
}
let difference = BitSetDifference::new(&bv1, &bv2);
assert!(!difference.test(0)); assert!(difference.test(2)); assert!(!difference.test(3)); assert!(!difference.test(6)); assert!(!difference.test(1));
let difference_bits: Vec<usize> = difference.iter().collect();
let mut expected_bits = Vec::new();
for i in 0..64 {
if i % 2 == 0 && i % 3 != 0 {
expected_bits.push(i);
}
}
assert_eq!(difference_bits, expected_bits);
}
#[test]
fn test_empty_sets() {
let empty1 = BitVec::<u32>::new(64);
let empty2 = BitVec::<u32>::new(64);
let union = BitSetUnion::new(&empty1, &empty2);
let intersection = BitSetIntersection::new(&empty1, &empty2);
let sym_diff = BitSetSymmetricDifference::new(&empty1, &empty2);
let difference = BitSetDifference::new(&empty1, &empty2);
assert_eq!(union.iter().count(), 0);
assert_eq!(intersection.iter().count(), 0);
assert_eq!(sym_diff.iter().count(), 0);
assert_eq!(difference.iter().count(), 0);
}
#[test]
fn test_with_single_bit() {
let mut bv1 = BitVec::<u32>::new(64);
let mut bv2 = BitVec::<u32>::new(64);
bv1.set(10);
bv2.set(20);
let union = BitSetUnion::new(&bv1, &bv2);
let union_bits: Vec<usize> = union.iter().collect();
assert_eq!(union_bits, vec![10, 20]);
let intersection = BitSetIntersection::new(&bv1, &bv2);
assert_eq!(intersection.iter().count(), 0);
let sym_diff = BitSetSymmetricDifference::new(&bv1, &bv2);
let sym_diff_bits: Vec<usize> = sym_diff.iter().collect();
assert_eq!(sym_diff_bits, vec![10, 20]);
let difference = BitSetDifference::new(&bv1, &bv2);
let difference_bits: Vec<usize> = difference.iter().collect();
assert_eq!(difference_bits, vec![10]);
let reverse_difference = BitSetDifference::new(&bv2, &bv1);
let reverse_difference_bits: Vec<usize> = reverse_difference.iter().collect();
assert_eq!(reverse_difference_bits, vec![20]);
}
}