use std::marker::PhantomData;
use std::mem;
use std::mem::{ManuallyDrop, MaybeUninit};
use std::ops::ControlFlow;
use crate::bit_block::BitBlock;
use crate::bit_queue::BitQueue;
use crate::bitset_interface::{BitSetBase, LevelMasksIterExt};
use crate::level_indices;
use crate::config::Config;
use crate::data_block::{data_block_start_index, DataBlock, DataBlockIter};
use crate::iter::{BlockCursor, IndexCursor};
pub struct BlockIter<T>
where
T: LevelMasksIterExt,
{
virtual_set: T,
level0_iter: <<T::Conf as Config>::Level0BitBlock as BitBlock>::BitsIter,
level1_iter: <<T::Conf as Config>::Level1BitBlock as BitBlock>::BitsIter,
level0_index: usize,
state: ManuallyDrop<T::IterState>,
level1_block_data: MaybeUninit<T::Level1BlockData>,
}
impl<T> Clone for BlockIter<T>
where
T: LevelMasksIterExt + Clone
{
#[inline]
fn clone(&self) -> Self {
let state = self.virtual_set.make_iter_state();
let mut this = Self {
virtual_set : self.virtual_set.clone(),
level0_iter : self.level0_iter.clone(),
level1_iter : self.level1_iter.clone(),
level0_index: self.level0_index,
state: ManuallyDrop::new(state),
level1_block_data: MaybeUninit::uninit()
};
let have_state = mem::size_of::<T::IterState>() > 0;
if !have_state {
this.level1_block_data = unsafe{ std::ptr::read(&self.level1_block_data) };
} else {
if this.level0_index < <T::Conf as Config>::Level0BitBlock::size()
{
unsafe {
this.virtual_set.init_level1_block_data(
&mut this.state,
&mut this.level1_block_data,
this.level0_index
);
}
}
}
this
}
}
impl<T> BlockIter<T>
where
T: LevelMasksIterExt,
{
#[inline]
pub(crate) fn new(virtual_set: T) -> Self {
let level0_iter = virtual_set.level0_mask().into_bits_iter();
let state = virtual_set.make_iter_state();
Self{
virtual_set,
level0_iter,
level1_iter: BitQueue::empty(),
level0_index: usize::MAX,
state: ManuallyDrop::new(state),
level1_block_data: MaybeUninit::new(Default::default())
}
}
#[inline]
pub fn cursor(&self) -> BlockCursor<T::Conf> {
if self.level0_index == usize::MAX {
return BlockCursor::default();
}
BlockCursor {
level0_index : self.level0_index as u16,
level1_next_index: self.level1_iter.current() as u16,
phantom: PhantomData
}
}
#[inline]
pub fn into_indices(mut self) -> IndexIter<T> {
let data_block_iter =
if let Some(data_block) = self.next(){
data_block.into_iter()
} else {
DataBlockIter {
start_index : usize::MAX,
bit_block_iter: BitQueue::empty()
}
};
IndexIter {
block_iter: self,
data_block_iter
}
}
#[must_use]
#[inline]
pub fn move_to(mut self, cursor: BlockCursor<T::Conf>) -> Self{
if self.level0_index != usize::MAX{
self.level0_iter = self.virtual_set.level0_mask().into_bits_iter();
}
let cursor_level0_index = cursor.level0_index as usize;
self.level0_iter.zero_first_n(cursor_level0_index);
if let Some(level0_index) = self.level0_iter.next(){
self.level0_index = level0_index;
let level1_mask = unsafe {
self.level1_block_data.assume_init_drop();
let (level1_mask, _) = self.virtual_set.init_level1_block_data(
&mut self.state,
&mut self.level1_block_data,
level0_index
);
level1_mask
};
self.level1_iter = level1_mask.into_bits_iter();
if level0_index == cursor_level0_index{
self.level1_iter.zero_first_n(cursor.level1_next_index as usize);
}
} else {
self.level1_iter = BitQueue::empty();
self.level0_index = <T::Conf as Config>::DataBitBlock::size();
}
self
}
#[inline]
pub fn traverse<F, B>(mut self, mut f: F) -> ControlFlow<B>
where
F: FnMut(DataBlock<<T::Conf as Config>::DataBitBlock>) -> ControlFlow<B>
{
if self.level0_index != usize::MAX{
let level0_index = self.level0_index;
let level1_iter = unsafe{ std::ptr::read(&self.level1_iter) };
let ctrl = level1_iter.traverse(
|level1_index| level1_mask_traverse_fn::<T, _, _>(
level0_index, level1_index, &self.level1_block_data, |b| f(b)
)
);
if let Some(e) = ctrl.break_value() {
return ControlFlow::Break(e);
}
}
let level0_iter = unsafe{ std::ptr::read(&self.level0_iter) };
level0_iter.traverse(
|level0_index| level0_mask_traverse_fn(
&self.virtual_set,
level0_index,
&mut self.state,
&mut self.level1_block_data,
|b| f(b)
)
)
}
}
impl<T> Iterator for BlockIter<T>
where
T: LevelMasksIterExt,
{
type Item = DataBlock<<T::Conf as Config>::DataBitBlock>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let level1_index = loop {
if let Some(index) = self.level1_iter.next() {
break index;
} else {
if let Some(index) = self.level0_iter.next() {
self.level0_index = index;
let level1_mask = unsafe {
self.level1_block_data.assume_init_drop();
let (level1_mask, _) =
self.virtual_set.init_level1_block_data(
&mut self.state,
&mut self.level1_block_data,
index
);
level1_mask
};
self.level1_iter = level1_mask.into_bits_iter();
} else {
return None;
}
}
};
let data_mask = unsafe {
T::data_mask_from_block_data(
self.level1_block_data.assume_init_ref(), level1_index
)
};
let block_start_index =
data_block_start_index::<<T as BitSetBase>::Conf>(
self.level0_index, level1_index,
);
Some(DataBlock { start_index: block_start_index, bit_block: data_mask })
}
#[inline]
fn for_each<F>(self, mut f: F)
where
F: FnMut(Self::Item)
{
let _ = self.traverse(|block| -> ControlFlow<()> {
f(block);
ControlFlow::Continue(())
});
}
}
impl<T> Drop for BlockIter<T>
where
T: LevelMasksIterExt
{
#[inline]
fn drop(&mut self) {
unsafe{
self.level1_block_data.assume_init_drop();
self.virtual_set.drop_iter_state(&mut self.state);
}
}
}
pub struct IndexIter<T>
where
T: LevelMasksIterExt,
{
block_iter: BlockIter<T>,
data_block_iter: DataBlockIter<<T::Conf as Config>::DataBitBlock>,
}
impl<T> Clone for IndexIter<T>
where
T: LevelMasksIterExt + Clone
{
#[inline]
fn clone(&self) -> Self {
Self{
block_iter: self.block_iter.clone(),
data_block_iter: self.data_block_iter.clone(),
}
}
}
impl<T> IndexIter<T>
where
T: LevelMasksIterExt,
{
#[inline]
pub(crate) fn new(virtual_set: T) -> Self {
Self{
block_iter: BlockIter::new(virtual_set),
data_block_iter: DataBlockIter{
start_index: 0,
bit_block_iter: BitQueue::empty(),
}
}
}
#[must_use]
#[inline]
pub fn move_to(mut self, cursor: IndexCursor<T::Conf>) -> Self {
self.block_iter = self.block_iter.move_to(cursor.block_cursor);
self.data_block_iter =
if let Some(data_block) = self.block_iter.next(){
let mut data_block_iter = data_block.into_iter();
let cursor_block_start_index = data_block_start_index::<T::Conf>(
cursor.block_cursor.level0_index as usize,
cursor.block_cursor.level1_next_index as usize,
);
if data_block_iter.start_index == cursor_block_start_index{
data_block_iter.bit_block_iter.zero_first_n(cursor.data_next_index as usize);
}
data_block_iter
} else {
DataBlockIter{
start_index: usize::MAX,
bit_block_iter: BitQueue::empty(),
}
};
self
}
#[inline]
pub fn cursor(&self) -> IndexCursor<T::Conf> {
if self.block_iter.level0_index == usize::MAX{
return IndexCursor::default();
}
let (level0_index, level1_index, _) = level_indices::<T::Conf>(self.data_block_iter.start_index);
IndexCursor {
block_cursor: BlockCursor {
level0_index: level0_index as u16,
level1_next_index: level1_index as u16,
phantom: PhantomData
},
data_next_index: self.data_block_iter.bit_block_iter.current() as u32,
}
}
#[inline]
pub fn traverse<F, B>(mut self, mut f: F) -> ControlFlow<B>
where
F: FnMut(usize) -> ControlFlow<B>
{
if self.block_iter.level0_index != usize::MAX{
let level0_index = self.block_iter.level0_index;
let ctrl = self.data_block_iter.traverse(|i| f(i));
if let Some(e) = ctrl.break_value() {
return ControlFlow::Break(e);
}
let level1_iter = unsafe{ std::ptr::read(&self.block_iter.level1_iter) };
let ctrl = level1_iter.traverse(
|level1_index| level1_mask_traverse_fn::<T, _, _>(
level0_index, level1_index, &self.block_iter.level1_block_data,
|b| b.traverse(|i| f(i))
)
);
if let Some(e) = ctrl.break_value() {
return ControlFlow::Break(e);
}
}
let level0_iter = unsafe{ std::ptr::read(&self.block_iter.level0_iter) };
level0_iter.traverse(
|level0_index| level0_mask_traverse_fn(
&self.block_iter.virtual_set,
level0_index,
&mut self.block_iter.state,
&mut self.block_iter.level1_block_data,
|b| b.traverse(|i| f(i))
)
)
}
}
impl<T> Iterator for IndexIter<T>
where
T: LevelMasksIterExt,
{
type Item = usize;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
loop{
if let Some(index) = self.data_block_iter.next(){
return Some(index);
}
if let Some(data_block) = self.block_iter.next(){
self.data_block_iter = data_block.into_iter();
} else {
return None;
}
}
}
#[inline]
fn for_each<F>(self, mut f: F)
where
F: FnMut(Self::Item)
{
let _ = self.traverse(|index| -> ControlFlow<()> {
f(index);
ControlFlow::Continue(())
});
}
}
#[inline]
fn level1_mask_traverse_fn<S, F, B>(
level0_index: usize,
level1_index: usize,
level1_block_data: &MaybeUninit<S::Level1BlockData>,
mut f: F
) -> ControlFlow<B>
where
S: LevelMasksIterExt,
F: FnMut(DataBlock<<S::Conf as Config>::DataBitBlock>) -> ControlFlow<B>
{
let data_mask = unsafe {
S::data_mask_from_block_data(level1_block_data.assume_init_ref(), level1_index)
};
let block_start_index =
data_block_start_index::<<S as BitSetBase>::Conf>(
level0_index, level1_index
);
f(DataBlock{ start_index: block_start_index, bit_block: data_mask })
}
#[inline]
fn level0_mask_traverse_fn<S, F, B>(
set: &S,
level0_index: usize,
state: &mut S::IterState,
level1_blocks: &mut MaybeUninit<S::Level1BlockData>,
mut f: F
) -> ControlFlow<B>
where
S: LevelMasksIterExt,
F: FnMut(DataBlock<<S::Conf as Config>::DataBitBlock>) -> ControlFlow<B>
{
let level1_mask = unsafe{
level1_blocks.assume_init_drop();
let (level1_mask, _) =
set.init_level1_block_data(state, level1_blocks, level0_index);
level1_mask
};
level1_mask.traverse_bits(|level1_index|{
level1_mask_traverse_fn::<S, _, B>(level0_index, level1_index, level1_blocks, |b| f(b))
})
}