#[derive(Debug, Clone)]
pub struct MaskedIter<I> {
parent: Box<I>,
blocks: Vec<usize>,
block_idx: usize,
size: usize,
}
impl<I: Iterator<Item = usize>> ExactSizeIterator for MaskedIter<I> {
#[inline(always)]
fn len(&self) -> usize {
self.size
}
}
impl<I: Iterator<Item = usize> + ExactSizeIterator> MaskedIter<I> {
pub fn new(parent: I, mut blocks: Vec<usize>) -> Self {
let mut size: usize = 0;
let mut cumsum_blocks: usize = 0;
for (i, x) in blocks.iter().enumerate() {
size += if i % 2 == 0 { *x } else { 0 };
cumsum_blocks += x;
}
let remainder = parent.len() - cumsum_blocks;
if remainder != 0 && blocks.len() % 2 == 0 {
size += remainder;
blocks.push(remainder);
}
Self {
parent: Box::new(parent),
blocks,
block_idx: 0,
size,
}
}
}
impl<I: Iterator<Item = usize>> Iterator for MaskedIter<I> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
debug_assert!(self.block_idx <= self.blocks.len());
let mut current_block = self.blocks[self.block_idx];
if current_block == 0 {
self.block_idx += 1;
if self.block_idx >= self.blocks.len() {
return None;
}
debug_assert!(self.blocks[self.block_idx] > 0);
for _ in 0..self.blocks[self.block_idx] {
let node = self.parent.next();
debug_assert!(node.is_some());
}
self.block_idx += 1;
current_block = self.blocks[self.block_idx];
debug_assert_ne!(current_block, 0);
}
let result = self.parent.next();
self.blocks[self.block_idx] -= 1;
result
}
#[inline(always)]
fn count(self) -> usize {
self.len()
}
}