use crate::{Meta, No};
pub trait IterBase<S> {
type T;
}
pub trait IterNext<S>: IterBase<S> {
fn iter_next(&mut self, state: &mut S) -> Option<Self::T>;
}
pub trait IterNth<S>: IterBase<S> {
fn iter_nth(
&mut self,
state: &mut S,
next: &mut impl IterNext<S, T = Self::T>,
n: usize,
) -> Option<Self::T>;
}
pub trait IterSizeHint<S>: IterBase<S> {
fn iter_size_hint(&self, state: &S) -> (usize, Option<usize>);
}
pub trait IterNextBack<S>: IterBase<S> {
fn iter_next_back(&mut self, state: &mut S) -> Option<Self::T>;
}
pub trait IterNthBack<S>: IterBase<S> {
fn iter_nth_back(
&mut self,
state: &mut S,
next_back: &mut impl IterNextBack<S, T = Self::T>,
n: usize,
) -> Option<Self::T>;
}
pub struct Predicate<const C: bool>;
pub trait Implemented {}
pub trait Unimplemented {}
impl<F, S, T> Implemented for Meta<F, S, T> { }
impl<T> Unimplemented for No<T> { }
impl Implemented for Predicate<true> { }
impl Unimplemented for Predicate<false> { }
impl<T, S> IterBase<S> for No<T> {
type T = T;
}
impl<T, S> IterNext<S> for No<T> {
#[inline]
fn iter_next(&mut self, _state: &mut S) -> Option<Self::T> {
None
}
}
impl<T, S> IterNth<S> for No<T> {
#[inline]
fn iter_nth(
&mut self,
state: &mut S,
next: &mut impl IterNext<S, T = Self::T>,
n: usize,
) -> Option<Self::T> {
for _ in 0..n {
next.iter_next(state)?;
}
next.iter_next(state)
}
}
impl<T, S> IterSizeHint<S> for No<T> {
#[inline]
fn iter_size_hint(&self, _state: &S) -> (usize, Option<usize>) {
(0, None)
}
}
impl<T, S> IterNthBack<S> for No<T> {
#[inline]
fn iter_nth_back(
&mut self,
state: &mut S,
next_back: &mut impl IterNextBack<S, T = Self::T>,
n: usize,
) -> Option<Self::T> {
for _ in 0..n {
next_back.iter_next_back(state)?;
}
next_back.iter_next_back(state)
}
}
impl<F, S, T> IterBase<S> for Meta<F, S, T> {
type T = T;
}
impl<F: FnMut(&mut S) -> Option<T>, S, T> IterNext<S> for Meta<F, S, T> {
#[inline]
fn iter_next(&mut self, state: &mut S) -> Option<Self::T> {
(self.0)(state)
}
}
impl<F: FnMut(&mut S, usize) -> Option<T>, S, T> IterNth<S> for Meta<F, S, T> {
#[inline]
fn iter_nth(
&mut self,
state: &mut S,
_next: &mut impl IterNext<S, T = Self::T>,
n: usize,
) -> Option<Self::T> {
(self.0)(state, n)
}
}
impl<F: Fn(&S) -> (usize, Option<usize>), S, T> IterSizeHint<S> for Meta<F, S, T> {
#[inline]
fn iter_size_hint(&self, state: &S) -> (usize, Option<usize>) {
(self.0)(state)
}
}
impl<F: FnMut(&mut S) -> Option<T>, S, T> IterNextBack<S> for Meta<F, S, T> {
#[inline]
fn iter_next_back(&mut self, state: &mut S) -> Option<Self::T> {
(self.0)(state)
}
}
impl<F: FnMut(&mut S, usize) -> Option<T>, S, T> IterNthBack<S> for Meta<F, S, T> {
#[inline]
fn iter_nth_back(
&mut self,
state: &mut S,
_next_back: &mut impl IterNextBack<S, T = Self::T>,
n: usize,
) -> Option<Self::T> {
(self.0)(state, n)
}
}