use crate::{OverflowVecReader, OverflowVecValue, VecIndex};
pub struct OverflowVecReaderCursor<I, T>
where
I: VecIndex,
T: OverflowVecValue,
{
reader: OverflowVecReader<I, T>,
position: usize,
}
impl<I, T> OverflowVecReaderCursor<I, T>
where
I: VecIndex,
T: OverflowVecValue,
{
#[inline(always)]
pub fn position(&self) -> usize {
self.position
}
#[inline(always)]
pub fn remaining(&self) -> usize {
self.reader.len().saturating_sub(self.position)
}
#[inline(always)]
pub fn advance(&mut self, count: usize) {
self.position = self.position.saturating_add(count).min(self.reader.len());
}
#[inline(always)]
pub fn get(&self, index: usize) -> Option<T> {
self.reader.try_get_at(index)
}
#[inline(always)]
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<T> {
let value = self.reader.try_get_at(self.position)?;
self.position += 1;
Some(value)
}
#[inline]
pub fn fold<B>(&mut self, count: usize, mut value: B, mut fold: impl FnMut(B, T) -> B) -> B {
let end = self.position.saturating_add(count).min(self.reader.len());
while self.position < end {
value = fold(value, self.reader.get_at(self.position));
self.position += 1;
}
value
}
#[inline]
pub fn for_each(&mut self, count: usize, mut f: impl FnMut(T)) {
self.fold(count, (), |(), value| f(value));
}
}
impl<I, T> OverflowVecReader<I, T>
where
I: VecIndex,
T: OverflowVecValue,
{
#[inline]
pub fn cursor(self) -> OverflowVecReaderCursor<I, T> {
OverflowVecReaderCursor {
reader: self,
position: 0,
}
}
}