#![doc = include_str!("../README.md")]
#![no_std]
#![allow(non_upper_case_globals, clippy::type_complexity)]
use core::{iter::FusedIterator, marker::PhantomData};
use traits::*;
pub mod traits;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct No<T>(PhantomData<T>);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct Meta<F, S, T>(F, PhantomData<(T, S)>);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct Flags<
const Finish: bool,
const Fused: bool,
const Exact: bool,
>;
#[derive(Debug, Clone)]
pub struct Iter<
S,
L,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
>
{
pub state: S,
next: Next,
nth: Nth,
size_hint: SizeHint,
next_back: NextBack,
nth_back: NthBack,
flags_phantom: PhantomData<L>,
}
impl<F, S, T> Iter<
S,
Flags<false, false, false>,
Meta<F, S, T>,
No<T>,
No<T>,
No<T>,
No<T>,
>
where F: FnMut(&mut S) -> Option<T>,
{
pub const fn new(state: S, f: F) -> Self {
Self {
state,
next: Meta(f, PhantomData),
nth: No(PhantomData),
size_hint: No(PhantomData),
next_back: No(PhantomData),
nth_back: No(PhantomData),
flags_phantom: PhantomData,
}
}
}
impl<F, T> Iter<
(),
Flags<false, false, false>,
Meta<F, (), T>,
No<T>,
No<T>,
No<T>,
No<T>,
>
where F: FnMut(&mut ()) -> Option<T>,
{
pub const fn new_unit(f: F) -> Self {
Self {
state: (),
next: Meta(f, PhantomData),
nth: No(PhantomData),
size_hint: No(PhantomData),
next_back: No(PhantomData),
nth_back: No(PhantomData),
flags_phantom: PhantomData,
}
}
}
impl<S, const Fused: bool, const Exact: bool, Next, Nth, SizeHint, NextBack, NthBack>
Iter<
S,
Flags<false, Fused, Exact>,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
>
where Next: IterNext<S>,
{
pub fn nth<F>(self, f: F) -> Iter<
S,
Flags<false, Fused, Exact>,
Next,
Meta<F, S, Next::T>,
SizeHint,
NextBack,
NthBack,
>
where F: FnMut(&mut S, usize) -> Option<Next::T>,
Nth: Unimplemented,
{
let Self {
state,
next,
nth: _,
size_hint,
next_back,
nth_back,
flags_phantom,
} = self;
let nth = Meta(f, PhantomData);
Iter { state, next, nth, size_hint, next_back, nth_back, flags_phantom }
}
pub fn size_hint<F>(self, f: F) -> Iter<
S,
Flags<false, Fused, Exact>,
Next,
Nth,
Meta<F, S, Next::T>,
NextBack,
NthBack,
>
where F: Fn(&S) -> (usize, Option<usize>),
SizeHint: Unimplemented,
{
let Self {
state,
next,
nth,
size_hint: _,
next_back,
nth_back,
flags_phantom,
} = self;
let size_hint = Meta(f, PhantomData);
Iter { state, next, nth, size_hint, next_back, nth_back, flags_phantom }
}
pub fn next_back<F>(self, f: F) -> Iter<
S,
Flags<false, Fused, Exact>,
Next,
Nth,
SizeHint,
Meta<F, S, Next::T>,
NthBack,
>
where F: FnMut(&mut S) -> Option<Next::T>,
NextBack: Unimplemented,
{
let Self {
state,
next,
nth,
size_hint,
next_back: _,
nth_back,
flags_phantom,
} = self;
let next_back = Meta(f, PhantomData);
Iter { state, next, nth, size_hint, next_back, nth_back, flags_phantom }
}
pub fn nth_back<F>(self, f: F) -> Iter<
S,
Flags<false, Fused, Exact>,
Next,
Nth,
SizeHint,
NextBack,
Meta<F, S, Next::T>,
>
where F: FnMut(&mut S, usize) -> Option<Next::T>,
NthBack: Unimplemented,
{
let Self {
state,
next,
nth,
size_hint,
next_back,
nth_back: _,
flags_phantom,
} = self;
let nth_back = Meta(f, PhantomData);
Iter { state, next, nth, size_hint, next_back, nth_back, flags_phantom }
}
pub fn exact(self) -> Iter<
S,
Flags<false, Fused, true>,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
>
where Predicate<Exact>: Unimplemented,
{
let Self {
state,
next,
nth,
size_hint,
next_back,
nth_back,
flags_phantom: _,
} = self;
Iter { state, next, nth, size_hint, next_back, nth_back, flags_phantom: PhantomData }
}
pub fn fused(self) -> Iter<
S,
Flags<false, true, Exact>,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
>
where Predicate<Fused>: Unimplemented,
{
let Self {
state,
next,
nth,
size_hint,
next_back,
nth_back,
flags_phantom: _,
} = self;
Iter { state, next, nth, size_hint, next_back, nth_back, flags_phantom: PhantomData }
}
pub fn finish(self) -> Iter<
S,
Flags<true, Fused, Exact>,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
> {
let Self {
state,
next,
nth,
size_hint,
next_back,
nth_back,
flags_phantom: _,
} = self;
Iter { state, next, nth, size_hint, next_back, nth_back, flags_phantom: PhantomData }
}
}
impl<S, const Fused: bool, const Exact: bool, Next, Nth, SizeHint, NextBack, NthBack>
Iterator
for Iter<
S,
Flags<true, Fused, Exact>,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
>
where Next: IterNext<S>,
Nth: IterNth<S, T = Next::T>,
SizeHint: IterSizeHint<S>
{
type Item = Next::T;
fn next(&mut self) -> Option<Self::Item> {
self.next.iter_next(&mut self.state)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.nth.iter_nth(&mut self.state, &mut self.next, n)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.size_hint.iter_size_hint(&self.state)
}
}
impl<S, const Fused: bool, const Exact: bool, Next, Nth, SizeHint, NextBack, NthBack>
DoubleEndedIterator
for Iter<
S,
Flags<true, Fused, Exact>,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
>
where Next: IterNext<S>,
Nth: IterNth<S, T = Next::T>,
SizeHint: IterSizeHint<S>,
NextBack: IterNextBack<S, T = Next::T>,
NthBack: IterNthBack<S, T = Next::T>,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.next_back.iter_next_back(&mut self.state)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.nth_back.iter_nth_back(&mut self.state, &mut self.next_back, n)
}
}
impl<S, const Exact: bool, Next, Nth, SizeHint, NextBack, NthBack>
FusedIterator
for Iter<
S,
Flags<true, true, Exact>,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
>
where Next: IterNext<S>,
Nth: IterNth<S, T = Next::T>,
SizeHint: IterSizeHint<S>,
{
}
impl<S, const Fused: bool, Next, Nth, SizeHint, NextBack, NthBack>
ExactSizeIterator
for Iter<
S,
Flags<true, Fused, true>,
Next,
Nth,
SizeHint,
NextBack,
NthBack,
>
where Next: IterNext<S>,
Nth: IterNth<S, T = Next::T>,
SizeHint: IterSizeHint<S> + Implemented,
{
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_next() {
let mut iter = Iter::new(0, |n| {
let i = *n;
(i < 3).then_some(())?;
*n += 1;
Some(i)
}).finish();
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
}
#[test]
fn test_nth() {
let mut iter = Iter::new(0, |n| {
let i = *n;
(i < 3).then_some(())?;
*n += 1;
Some(i)
}).nth(|_, n| Some(n)).finish();
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
assert_eq!(iter.nth(0), Some(0));
assert_eq!(iter.nth(9), Some(9));
}
#[test]
fn test_nth_dep() {
let mut iter = Iter::new(0, |n| {
let i = *n;
(i < 3).then_some(())?;
*n += 1;
Some(i)
}).finish();
assert_eq!(iter.nth(0), Some(0));
assert_eq!(iter.nth(1), Some(2));
assert_eq!(iter.nth(0), None);
}
#[test]
fn test_size_hint() {
let mut iter = Iter::new(0, |n| {
let i = *n;
(i < 3).then_some(())?;
*n += 1;
Some(i)
}).size_hint(|s| (3-s, Some(3-s))).finish();
assert_eq!(iter.size_hint(), (3, Some(3)));
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.size_hint(), (2, Some(2)));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
assert_eq!(iter.size_hint(), (0, Some(0)));
assert_eq!(iter.next(), None);
assert_eq!(iter.size_hint(), (0, Some(0)));
}
#[test]
fn test_exact() {
let mut iter = Iter::new(0, |n| {
let i = *n;
(i < 3).then_some(())?;
*n += 1;
Some(i)
}).size_hint(|s| (3-s, Some(3-s))).exact().finish();
assert_eq!(iter.len(), 3);
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.len(), 2);
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.len(), 0);
assert_eq!(iter.next(), None);
assert_eq!(iter.len(), 0);
}
#[test]
fn test_fused() {
let mut iter = Iter::new(0, |n| {
let i = *n;
(i < 3).then_some(())?;
*n += 1;
Some(i)
}).fused().finish();
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
}
#[test]
fn test_exact_fused() {
let mut iter = Iter::new(0, |n| {
let i = *n;
(i < 3).then_some(())?;
*n += 1;
Some(i)
}).exact().fused().finish();
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
}
#[test]
fn test_next_back() {
let mut iter = Iter::new((0, 3), |(a, b)| {
let i = *a;
(i < *b).then_some(())?;
*a += 1;
Some(i)
}).next_back(|(a, b)| {
(*a < *b).then_some(())?;
*b -= 1;
Some(*b)
}).finish();
let mut iter1 = iter.clone();
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
assert_eq!(iter1.next(), Some(0));
assert_eq!(iter1.next_back(), Some(2));
assert_eq!(iter1.next_back(), Some(1));
assert_eq!(iter1.next_back(), None);
assert_eq!(iter1.next(), None);
}
#[test]
fn size() {
let f = |_: &mut ()| Some(());
assert_eq!(size_of_val(&f), 0);
let iter = Iter::new((), f);
assert_eq!(size_of_val(&iter), 0);
let mut iter = iter.finish();
assert_eq!(size_of_val(&iter), 0);
assert_eq!(iter.next(), Some(()));
}
#[test]
fn size1() {
let f = |_: &mut ()| Some(());
assert_eq!(size_of_val(&f), 0);
let iter = Iter::new((), f).next_back(f);
assert_eq!(size_of_val(&iter), 0);
let mut iter = iter.finish();
assert_eq!(size_of_val(&iter), 0);
assert_eq!(iter.next(), Some(()));
assert_eq!(iter.next_back(), Some(()));
}
}