use crate::types::IndexType;
#[derive(Clone, Debug)]
pub(crate) struct IndexList<I> {
pos_start: Vec<I>,
index_list: Vec<I>,
}
impl<I> IndexList<I>
where I: IndexType {
pub(crate) const UNSET: I = <I as IndexType>::MAX;
pub(crate) fn new() -> Self {
Self {
pos_start: Vec::<I>::new(),
index_list: Vec::<I>::new(),
}
}
pub(crate) fn with_capacity(cap: usize) -> Self {
Self {
pos_start: Vec::<I>::with_capacity(cap),
index_list: Vec::<I>::with_capacity(cap),
}
}
pub(crate) fn n_entries(&self) -> usize {
self.index_list.len()
}
pub(crate) fn n_rows(&self) -> usize {
self.pos_start.len()
}
pub(crate) fn push(&mut self, row: usize) -> usize {
if row >= self.pos_start.len() {
self.pos_start.resize(row + 1, Self::UNSET);
}
let index = I::as_indextype(self.n_entries());
assert_ne!(index, Self::UNSET);
self.index_list.push(Self::UNSET);
if self.pos_start[row] == Self::UNSET {
self.pos_start[row] = index;
} else {
let mut iter = self.pos_start[row].as_usize();
while self.index_list[iter] != Self::UNSET {
iter = self.index_list[iter].as_usize();
}
self.index_list[iter] = index;
}
index.as_usize()
}
pub(crate) fn iter_row(&self, row: usize) -> IterRow<I> {
IterRow::<I> {
list: self,
pos: self.pos_start[row],
}
}
}
pub(crate) struct IterRow<'a, I> {
list: &'a IndexList<I>,
pos: I,
}
impl<'a, I> Iterator for IterRow<'a, I>
where I: IndexType {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.pos != IndexList::<I>::UNSET {
let index = self.pos.as_usize();
self.pos = self.list.index_list[index];
Some(index)
} else {
None
}
}
}