use core::iter::FusedIterator;
use unconst::unconst;
use crate::context::Context;
use crate::repr::Repr;
use crate::traits::Integral;
#[unconst]
#[derive_const(Clone, PartialEq)]
#[derive(Debug, Eq)]
pub struct Partition<'c, I: ~const Integral> {
context: &'c Context<I>,
repr: Repr<I>,
last_end: usize,
last_match: Option<usize>,
}
#[unconst]
impl<'c, I: ~const Integral> Partition<'c, I> {
pub const fn new(context: &Context<I>, repr: Repr<I>) -> Self {
Partition { context, repr, last_end: 0, last_match: None }
}
pub const fn context(&self) -> &'c Context<I> {
self.context
}
pub const fn repr(&self) -> &Repr<I> {
&self.repr
}
}
#[unconst]
impl<'c, I: ~const Integral> Iterator for Partition<'c, I> {
type Item = (usize, usize);
fn next(&mut self) -> Option<(usize, usize)> {
if self.last_end > self.context.len() {
return None;
}
let (start, end) = match self.repr.find_at(self.context, self.last_end) {
None => return None,
Some((start, end)) => (start, end),
};
if start == end {
self.last_end = end + 1;
if Some(end) == self.last_match {
return self.next();
}
} else {
self.last_end = end;
}
self.last_match = Some(end);
Some((start, end))
}
}
#[unconst]
impl<'c, I: ~const Integral> FusedIterator for Partition<'c, I> {}
#[unconst]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Match<'c, I: ~const Integral> {
context: &'c Context<I>,
start: usize,
end: usize,
}
#[unconst]
impl<'c, I: ~const Integral> Match<'c, I> {
#[inline]
pub const fn new(context: &'c Context<I>, start: usize, end: usize) -> Self
{
Match { context, start, end }
}
#[inline]
pub const fn as_slice(&self) -> &'c [I] {
&self.context[self.start..self.end]
}
}