use std::{marker::PhantomData, ptr::NonNull};
use crate::traits::BitWord;
pub struct Iter<'a, W: BitWord> {
ptr: NonNull<W>,
len: usize,
word_offset: usize,
curr: W,
_marker: PhantomData<&'a W>,
}
impl<'a, W: BitWord> Iter<'a, W> {
pub(crate) fn new(ptr: NonNull<W>, len: usize) -> Self {
let curr = if len == 0 {
W::from(0)
} else {
unsafe { ptr.read() }
};
Self {
ptr,
len,
word_offset: 0,
curr,
_marker: PhantomData,
}
}
pub(crate) fn from_raw_parts(ptr: *const W, len: usize) -> Self {
let curr = if len == 0 {
W::from(0)
} else {
unsafe { *ptr }
};
Self {
ptr: NonNull::new(ptr as *mut _).unwrap_or(NonNull::dangling()),
len,
word_offset: 0,
curr,
_marker: PhantomData,
}
}
}
impl<'a, W: BitWord> Iterator for Iter<'a, W> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
while self.word_offset < self.len {
if self.curr == W::from(0) {
self.word_offset += W::BITS;
if self.word_offset >= self.len {
break;
}
self.curr = unsafe { self.ptr.add(self.word_offset / W::BITS).read() };
continue;
}
let tz = self.curr.trailing_zeros();
if self.word_offset + tz < self.len {
self.curr &= !(W::from(1) << tz);
return Some(self.word_offset + tz);
} else {
break;
}
}
None
}
}
#[cfg(test)]
mod tests {
use crate::{BitRead, BitVec, traits::BitWrite};
#[test]
fn test_iterator_empty() {
let bv: BitVec<u32> = BitVec::new(0);
let mut iter = bv.iter();
assert_eq!(iter.next(), None);
}
#[test]
fn test_iterator_single_bit() {
let mut bv: BitVec<u64> = BitVec::new(1);
assert_eq!(bv.iter().collect::<Vec<_>>(), vec![]);
bv.set(0);
assert_eq!(bv.iter().collect::<Vec<_>>(), vec![0]);
}
#[test]
fn test_iterator_multiple_bits() {
let mut bv: BitVec<u8> = BitVec::new(10);
bv.set(2);
bv.set(5);
bv.set(9);
let bits: Vec<_> = bv.iter().collect();
assert_eq!(bits, vec![2, 5, 9]);
}
#[test]
fn test_iterator_all_bits_set() {
let mut bv: BitVec<u16> = BitVec::new(8);
bv.fill();
let bits: Vec<_> = bv.iter().collect();
assert_eq!(bits, (0..8).collect::<Vec<_>>());
}
#[test]
fn test_iterator_after_clear_and_set() {
let mut bv: BitVec<u32> = BitVec::new(16);
bv.fill();
bv.clear();
assert_eq!(bv.iter().collect::<Vec<_>>(), vec![]);
bv.set(7);
bv.set(15);
assert!(bv.test(7));
assert!(bv.test(15));
assert_eq!(bv.iter().collect::<Vec<_>>(), vec![7, 15]);
}
#[test]
fn test_iterator_sparse_bits() {
let mut bv: BitVec<u64> = BitVec::new(64);
bv.set(0);
bv.set(31);
bv.set(32);
bv.set(63);
let bits: Vec<_> = bv.iter().collect();
assert_eq!(bits, vec![0, 31, 32, 63]);
}
#[test]
fn test_iterator_large_bitvec() {
let mut bv: BitVec<usize> = BitVec::new(130);
for i in (0..130).step_by(13) {
bv.set(i);
}
let expected: Vec<_> = (0..130).step_by(13).collect();
let actual: Vec<_> = bv.iter().collect();
assert_eq!(actual, expected);
}
#[test]
fn test_iterator_partial_last_word() {
let mut bv: BitVec<u8> = BitVec::new(70); bv.set(0);
bv.set(63);
bv.set(64);
bv.set(69);
let bits: Vec<_> = bv.iter().collect();
assert_eq!(bits, vec![0, 63, 64, 69]);
}
}