use std::{iter::Cloned, slice::Iter, cmp::Ordering};
use fixedbitset::FixedBitSet;
type BitSet = FixedBitSet;
pub struct BitSetIter<'a> {
iter: Cloned<Iter<'a, u32>>,
word: Option<u32>,
base: usize,
offset: usize,
}
impl BitSetIter<'_> {
pub fn new(bs: &BitSet) -> BitSetIter {
let mut iter = bs.as_slice().iter().cloned();
let word = iter.next();
BitSetIter {iter, word, base: 0, offset: 0}
}
}
impl Iterator for BitSetIter<'_> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
while let Some(w) = self.word {
if w == 0 || self.offset >= 32 {
self.word = self.iter.next();
self.base += 32;
self.offset = 0;
} else {
let mut mask = 1_u32 << self.offset as u32;
while (w & mask) == 0 && self.offset < 32 {
mask <<= 1;
self.offset += 1;
}
if self.offset < 32 {
let ret = Some(self.base + self.offset);
self.offset += 1;
return ret;
}
}
}
None
}
}
#[derive(Debug)]
pub struct LexBitSet<'a>(pub &'a BitSet);
impl Ord for LexBitSet<'_> {
fn cmp(&self, other: &Self) -> Ordering {
let mut x = self.0.as_slice().iter().cloned();
let mut y = other.0.as_slice().iter().cloned();
let end = x.len().max(y.len());
for _ in 0..end {
let xi = x.next().unwrap_or(0);
let yi = y.next().unwrap_or(0);
if xi != yi {
let mut mask = 1_u32;
for _ in 0..32 {
let bit_x = xi & mask;
let bit_y = yi & mask;
if bit_x != bit_y {
return bit_x.cmp(&bit_y);
}
mask <<= 1;
}
}
}
Ordering::Equal
}
}
impl PartialOrd for LexBitSet<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for LexBitSet<'_> {}
impl PartialEq for LexBitSet<'_> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0 || self.cmp(other) == Ordering::Equal
}
}
#[cfg(test)]
mod tests_bitset_iter {
use crate::{BitSetIter, BitSet};
#[test]
fn bsiter_collect() {
let mut bit_set = BitSet::with_capacity(5);
bit_set.set(1, true);
bit_set.set(2, true);
bit_set.set(4, true);
let iter = BitSetIter::new(&bit_set);
let items = iter.collect::<Vec<usize>>();
assert_eq!(items, vec![1, 2, 4]);
}
#[test]
fn bsiter_next_normal_case() {
let mut bit_set = BitSet::with_capacity(5);
bit_set.set(1, true);
bit_set.set(2, true);
bit_set.set(4, true);
let mut iter = BitSetIter::new(&bit_set);
assert_eq!(Some(1), iter.next());
assert_eq!(Some(2), iter.next());
assert_eq!(Some(4), iter.next());
assert_eq!(None , iter.next());
}
#[test]
fn bsiter_no_items() {
let bit_set = BitSet::with_capacity(5);
let mut iter = BitSetIter::new(&bit_set);
assert_eq!(None, iter.next());
assert_eq!(None, iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn bsiter_mutiple_words() {
let mut bit_set = BitSet::with_capacity(128);
bit_set.set( 1, true);
bit_set.set( 50, true);
bit_set.set( 66, true);
bit_set.set(100, true);
let mut iter = BitSetIter::new(&bit_set);
assert_eq!(Some( 1), iter.next());
assert_eq!(Some( 50), iter.next());
assert_eq!(Some( 66), iter.next());
assert_eq!(Some(100), iter.next());
assert_eq!(None , iter.next());
}
}
#[cfg(test)]
mod tests_lexbitset {
use crate::{LexBitSet, BitSet};
#[test]
fn same_size_less_than() {
let mut a = BitSet::with_capacity(200);
let mut b = BitSet::with_capacity(200);
a.set(2, true); b.set(2, true);
a.set(3, false); b.set(3, true);
a.set(4, true); b.set(4, false);
a.set(150, true);
b.set(150, true);
assert!(LexBitSet(&a) <= LexBitSet(&b));
assert!(LexBitSet(&a) < LexBitSet(&b));
}
#[test]
fn same_size_greater_than() {
let mut a = BitSet::with_capacity(200);
let mut b = BitSet::with_capacity(200);
a.set(2, true); b.set(2, true);
a.set(3, false); b.set(3, true);
a.set(4, true); b.set(4, false);
a.set(150, true);
b.set(150, true);
assert!(LexBitSet(&b) >= LexBitSet(&a));
assert!(LexBitSet(&b) > LexBitSet(&a));
}
#[test]
fn same_size_equal() {
let mut a = BitSet::with_capacity(200);
let mut b = BitSet::with_capacity(200);
a.set(2, true); b.set(2, true);
a.set(150, true);
b.set(150, true);
assert!(LexBitSet(&a) >= LexBitSet(&b));
assert!(LexBitSet(&b) >= LexBitSet(&a));
assert_eq!(LexBitSet(&a), LexBitSet(&b));
assert_eq!(LexBitSet(&a), LexBitSet(&a));
assert_eq!(LexBitSet(&b), LexBitSet(&b));
}
#[test]
fn different_sizes_considered_padded_with_zeroes() {
let mut a = BitSet::with_capacity(20);
let mut b = BitSet::with_capacity(200);
a.set(2, true); b.set(2, true);
assert_eq!(LexBitSet(&a), LexBitSet(&b));
b.set(150, true);
assert!(LexBitSet(&a) <= LexBitSet(&b));
assert!(LexBitSet(&a) < LexBitSet(&b));
}
}