#![forbid(unsafe_code)]
#![no_std]
#![no_builtins]
#![deny(missing_docs)]
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
extern crate core;
use core::{fmt, mem, iter::{Iterator, DoubleEndedIterator}};
#[repr(align(16))]
enum Peeked<T> {
Empty,
Once(((), Option<T>)),
Twice((Option<T>, Option<T>))
}
macro_rules! matched {
(
$peeked:expr => {
empty => $empty:expr,
once $ov:ident => $once:expr,
twice $fv:ident $sv:ident => $twice:expr $(,)?
}
) => {
match $peeked {
Peeked::Empty => $empty,
Peeked::Once((_, $ov)) => $once,
Peeked::Twice(($fv, $sv)) => $twice
}
}
}
macro_rules! on_left {
($peeked:expr => { $elem:ident => $do:expr, else => $else:expr $(,)? }) => {
match $peeked {
Peeked::Once((_, $elem)) | Peeked::Twice(($elem, _)) => $do,
_ => $else
}
}
}
macro_rules! is_some_and {
($opt:ident, $and:ident) => {
match &$opt {
Some(__inner) => $and(__inner),
None => false
}
}
}
enum MaybeTerm {
Size(usize),
Add(usize)
}
impl<T> Peeked<T> {
#[inline(always)]
#[must_use]
const fn once(elem: Option<T>) -> Self {
Self::Once(((), elem))
}
#[inline(always)]
#[must_use]
const fn twice(first: Option<T>, second: Option<T>) -> Self {
Self::Twice((first, second))
}
#[inline]
#[must_use]
const fn num_peeked(&self) -> u8 {
match self {
Self::Empty => 0,
Self::Once(_) => 1,
Self::Twice(_) => 2
}
}
#[inline]
#[must_use]
const fn is_term(&self) -> bool {
match self {
Self::Once((_, None)) | Self::Twice((None, _)) => true,
_ => false
}
}
#[inline]
#[must_use]
const fn maybe_term(&self) -> MaybeTerm {
match self {
Self::Once((_, None)) | Self::Twice((None, _)) => MaybeTerm::Size(0),
Self::Twice((Some(_), None)) => MaybeTerm::Size(1),
Self::Twice((Some(_), Some(_))) => MaybeTerm::Add(2),
Self::Once((_, Some(_))) => MaybeTerm::Add(1),
Self::Empty => MaybeTerm::Add(0)
}
}
#[inline]
#[must_use]
fn take(&mut self) -> Option<Option<T>> {
matched! { mem::replace(self, Self::Empty) => {
empty => None,
once p => Some(p),
twice f s => { *self = Self::once(s); Some(f) }
} }
}
#[inline(always)]
#[must_use]
fn drain(&mut self) -> Peeked<T> {
mem::replace(self, Self::Empty)
}
#[inline]
#[must_use]
const fn init_peek(&self) -> Option<&T> {
matched! { self => {
empty => None,
once elem => elem.as_ref(),
twice elem _ignore => elem.as_ref()
} }
}
#[inline]
#[must_use]
fn init_peek_mut(&mut self) -> Option<&mut T> {
matched! { self => {
empty => None,
once elem => elem.as_mut(),
twice elem _ignore => elem.as_mut()
} }
}
#[inline]
#[must_use]
fn has_first_and<P>(&self, and: P) -> bool where P: FnOnce(&Option<T>) -> bool {
on_left!(self => { elem => and(elem), else => false })
}
#[inline]
#[must_use]
const fn is_full(&self) -> bool {
matches!(self, Self::Twice(_))
}
#[inline]
#[must_use]
const fn non_empty(&self) -> bool {
!self.is_empty()
}
#[inline]
#[must_use]
const fn only_one(&self) -> bool {
matches!(self, Self::Once(_))
}
#[inline]
#[must_use]
const fn is_empty(&self) -> bool {
matches!(self, Self::Empty)
}
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
fn add_first_peek(&mut self, elem: Option<T>) {
debug_assert!(
self.is_empty(),
"Precondition violated: `add_first_peek` was called when state was not Empty."
);
*self = Self::once(elem);
}
}
#[must_use = "You must not ignore `drain_if` operation's result"]
pub enum DrainIf<'r, T: Iterator> {
Drained((Option<T::Item>, T::Item)),
Peek(Peek<'r, T>)
}
impl<'r, T: Iterator> DrainIf<'r, T> {
#[inline]
pub fn drained(self) -> Option<(Option<T::Item>, T::Item)> {
match self {
Self::Drained(res) => Some(res),
Self::Peek(_) => None
}
}
#[inline]
pub fn peek(self) -> Option<Peek<'r, T>> {
match self {
Self::Peek(peek) => Some(peek),
Self::Drained(_) => None
}
}
#[inline]
pub fn map_or_else<E, F, R>(self, e: E, map: F) -> R
where
E: FnOnce(Peek<'r, T>) -> R,
F: FnOnce((Option<T::Item>, T::Item)) -> R
{
match self {
Self::Drained(res) => map(res),
Self::Peek(peek) => e(peek)
}
}
}
#[repr(transparent)]
pub struct Peek<'r, T: Iterator> {
src: &'r mut Peekable<T>
}
impl<'r, T> PartialEq<Option<&T::Item>> for Peek<'r, T>
where
T: Iterator,
<T as Iterator>::Item: PartialEq
{
#[inline]
fn eq(&self, other: &Option<&T::Item>) -> bool { self.src.peeked.has_first_and(|data| data.as_ref().eq(other)) }
}
impl<'r, T> fmt::Debug for Peek<'r, T>
where
T: Iterator,
<T as Iterator>::Item: fmt::Debug
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Peek").field(&self.get()).finish()
}
}
impl<'r, T: Iterator> Peek<'r, T> {
#[inline]
#[must_use]
#[cfg_attr(debug_assertions, track_caller)]
fn new(src: &'r mut Peekable<T>) -> Self {
debug_assert!(
!src.peeked.is_empty(),
"Invariant violated on construction of Peek. Peeked state must not be Empty."
);
Self { src }
}
#[inline]
pub const fn get(&self) -> Option<&T::Item> {
self.src.peeked.init_peek()
}
#[inline]
pub fn get_mut(&mut self) -> Option<&mut T::Item> {
self.src.peeked.init_peek_mut()
}
#[must_use]
pub fn peek(&mut self) -> Option<&T::Item> {
self.src.transition_forward();
match &self.src.peeked {
Peeked::Twice((_, elem)) => elem.as_ref(),
_ => unreachable!()
}
}
#[must_use]
pub fn peek_mut(&mut self) -> Option<&mut T::Item> {
self.src.transition_forward();
match &mut self.src.peeked {
Peeked::Twice((_, elem)) => elem.as_mut(),
_ => unreachable!()
}
}
#[inline]
pub fn consume(self) -> Option<T::Item> {
self.src.peeked
.take()
.unwrap()
}
pub fn drain_if<F>(self, predicate: F) -> DrainIf<'r, T>
where F: FnOnce(&T::Item) -> bool
{
self.src.transition_forward();
match mem::replace(&mut self.src.peeked, Peeked::Empty) {
Peeked::Twice((first, second)) => match second {
Some(second) if predicate(&second) => DrainIf::Drained((first, second)),
_ => {
self.src.peeked = Peeked::twice(first, second);
DrainIf::Peek(self)
}
},
_ => unreachable!()
}
}
}
#[repr(transparent)]
#[must_use]
#[derive(Copy, Clone)]
pub struct PeekState<'r, T> {
peeked: &'r Peeked<T>
}
impl<'r, T> PeekState<'r, T> {
#[inline]
const fn new(peeked: &'r Peeked<T>) -> Self {
Self { peeked }
}
#[inline]
#[must_use]
pub const fn is_full(&self) -> bool {
self.peeked.is_full()
}
#[inline]
#[must_use]
pub const fn non_empty(&self) -> bool {
self.peeked.non_empty()
}
#[inline]
#[must_use]
pub const fn only_one(&self) -> bool {
self.peeked.only_one()
}
#[inline]
#[must_use]
pub const fn is_empty(&self) -> bool {
self.peeked.is_empty()
}
#[inline]
#[must_use]
pub const fn num_peeked(&self) -> u8 {
self.peeked.num_peeked()
}
}
pub struct Peekable<T: Iterator> {
iter: T,
peeked: Peeked<T::Item>
}
impl<T: Iterator> Peekable<T> {
pub const fn new(iter: T) -> Self {
Self { iter, peeked: Peeked::Empty }
}
#[inline]
pub const fn peek_state(&self) -> PeekState<'_, T::Item> {
PeekState::new(&self.peeked)
}
#[inline]
fn transition_forward(&mut self) {
self.peeked = match mem::replace(&mut self.peeked, Peeked::Empty) {
twice @ Peeked::Twice(_) => twice,
Peeked::Once((_, elem)) => Peeked::Twice((elem, self.iter.next())),
Peeked::Empty => unreachable!()
};
}
fn fill(&mut self) {
self.peeked = match mem::replace(&mut self.peeked, Peeked::Empty) {
twice @ Peeked::Twice(_) => twice,
Peeked::Once((_, elem)) => Peeked::twice(elem, self.iter.next()),
Peeked::Empty => {
let first = self.iter.next();
let second = self.iter.next();
Peeked::twice(first, second)
}
};
}
#[inline]
#[must_use]
pub fn peek(&mut self) -> Peek<'_, T> {
if self.peeked.is_empty() {
self.peeked.add_first_peek(self.iter.next());
}
Peek::new(self)
}
#[inline]
#[must_use]
pub fn peek_2(&mut self) -> Option<&T::Item> {
self.fill();
match &self.peeked {
Peeked::Twice((_, second)) => second.as_ref(),
_ => unreachable!()
}
}
#[inline]
#[must_use]
pub fn peek_2_mut(&mut self) -> Option<&mut T::Item> {
self.fill();
match &mut self.peeked {
Peeked::Twice((_, second)) => second.as_mut(),
_ => unreachable!()
}
}
#[inline]
pub fn next_if(&mut self, func: impl FnOnce(&T::Item) -> bool) -> Option<T::Item> {
match mem::replace(&mut self.peeked, Peeked::Empty) {
Peeked::Empty => {
let next = self.iter.next();
if is_some_and!(next, func) {
next
} else {
self.peeked = Peeked::once(next);
None
}
},
Peeked::Once((_, elem)) => if is_some_and!(elem, func) {
elem
} else {
self.peeked = Peeked::once(elem);
None
},
Peeked::Twice((elem, later)) => if is_some_and!(elem, func) {
self.peeked = Peeked::once(later);
elem
} else {
self.peeked = Peeked::twice(elem, later);
None
}
}
}
#[inline]
pub fn next_if_eq<E>(&mut self, expected: &E) -> Option<T::Item>
where
E: ?Sized,
<T as Iterator>::Item: PartialEq<E>,
{
self.next_if(|next| next.eq(expected))
}
}
impl<T: Iterator> Iterator for Peekable<T> {
type Item = T::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self.peeked.take() {
Some(v) => v,
None => self.iter.next(),
}
}
#[inline]
fn count(self) -> usize {
let amount = match self.peeked {
Peeked::Empty => 0,
Peeked::Once ((_, Some(_))) => 1,
Peeked::Twice((Some(_), next)) => match next {
Some(_) => 2,
None => 1
},
_ => return 0
};
amount + self.iter.count()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<T::Item> {
if n == 0 {
self.peeked.take().unwrap_or_else(|| self.iter.next())
} else {
match self.peeked.drain() {
Peeked::Twice((_, elem)) => if n == 1 {
elem
} else {
self.iter.nth(n - 2)
},
Peeked::Once(_) => self.iter.nth(n - 1),
Peeked::Empty => self.iter.nth(n)
}
}
}
#[inline]
fn last(mut self) -> Option<T::Item> {
match self.peeked.drain() {
Peeked::Empty => self.iter.last(),
Peeked::Once((_, None)) | Peeked::Twice((None, _)) => None,
Peeked::Twice((elem @ Some(_), None)) => elem,
Peeked::Once((_, elem @ Some(_)))
| Peeked::Twice((Some(_), elem @ Some(_))) => self.iter.last().or(elem)
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let peek_len = match self.peeked.maybe_term() {
MaybeTerm::Size(known_size) => return (known_size, Some(known_size)),
MaybeTerm::Add(amnt) => amnt
};
let (lo, hi) = self.iter.size_hint();
let lo = lo.saturating_add(peek_len);
let hi = hi.and_then(|l| l.checked_add(peek_len));
(lo, hi)
}
#[inline]
fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
let acc = match self.peeked.drain() {
Peeked::Once((_, None)) | Peeked::Twice((None, _)) => return init,
Peeked::Twice((Some(first), None)) => return fold(init, first),
Peeked::Twice((Some(first), Some(second))) => {
let acc = fold(init, first);
fold(acc, second)
},
Peeked::Once((_, Some(first))) => fold(init, first),
Peeked::Empty => init
};
self.iter.fold(acc, fold)
}
#[inline]
fn all<F>(&mut self, mut f: F) -> bool
where
Self: Sized,
F: FnMut(Self::Item) -> bool,
{
let peek_res = match self.peeked.drain() {
Peeked::Once((_, Some(elem))) => f(elem),
Peeked::Twice((Some(first), Some(second))) => f(first) && f(second),
Peeked::Empty => true,
Peeked::Once((_, None)) | Peeked::Twice((None, _)) => return true, Peeked::Twice((Some(elem), None)) => return f(elem), };
peek_res && self.iter.all(f)
}
#[inline]
fn any<F>(&mut self, mut f: F) -> bool
where
Self: Sized,
F: FnMut(Self::Item) -> bool,
{
let peek_res = match self.peeked.drain() {
Peeked::Once((_, Some(elem))) => f(elem),
Peeked::Twice((Some(first), Some(second))) => f(first) || f(second),
Peeked::Empty => false,
Peeked::Once((_, None)) | Peeked::Twice((None, _)) => return false, Peeked::Twice((Some(elem), None)) => return f(elem), };
peek_res || self.iter.any(f)
}
#[inline]
fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
where
Self: Sized,
P: FnMut(&Self::Item) -> bool,
{
match self.peeked.drain() {
Peeked::Once((_, Some(elem))) => if predicate(&elem) { return Some(elem) } else {},
Peeked::Twice((Some(elem), Some(n_elem))) => if predicate(&elem) {
self.peeked = Peeked::once(Some(n_elem));
return Some(elem)
} else if predicate(&n_elem) {
return Some(n_elem)
} else {
},
Peeked::Once((_, None)) | Peeked::Twice((None, _)) => return None,
Peeked::Twice((Some(elem), None)) => return predicate(&elem).then_some(elem),
Peeked::Empty => {}
}
self.iter.find(predicate)
}
#[inline]
fn find_map<B, F>(&mut self, mut f: F) -> Option<B>
where
Self: Sized,
F: FnMut(Self::Item) -> Option<B>
{
match self.peeked.drain() {
Peeked::Once((_, Some(elem))) => if let Some(out) = f(elem) { return Some(out) } else {},
Peeked::Twice((Some(elem), Some(n_elem))) => if let Some(out) = f(elem) {
self.peeked = Peeked::once(Some(n_elem));
return Some(out)
} else if let Some(n_out) = f(n_elem) {
return Some(n_out)
} else {
},
Peeked::Once((_, None)) | Peeked::Twice((None, _)) => return None,
Peeked::Twice((Some(elem), None)) => return f(elem),
Peeked::Empty => {}
}
self.iter.find_map(f)
}
#[inline]
fn position<P>(&mut self, mut predicate: P) -> Option<usize>
where
Self: Sized,
P: FnMut(Self::Item) -> bool,
{
let offset = match self.peeked.drain() {
Peeked::Once((_, Some(elem))) => if predicate(elem) { return Some(0) } else { 1},
Peeked::Twice((Some(elem), Some(n_elem))) => if predicate(elem) {
self.peeked = Peeked::once(Some(n_elem));
return Some(0)
} else if predicate(n_elem) {
return Some(1)
} else {
2
},
Peeked::Once((_, None)) | Peeked::Twice((None, _)) => return None,
Peeked::Twice((Some(elem), None)) => return predicate(elem).then_some(0),
Peeked::Empty => 0
};
self.iter.position(predicate).map(|out| out + offset)
}
}
impl<T: DoubleEndedIterator> DoubleEndedIterator for Peekable<T> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.peeked.is_term() { return None; }
match self.iter.next_back() {
res @ Some(_) => res,
None => match self.peeked.drain() {
Peeked::Empty => None,
Peeked::Once((_, elem)) => elem,
Peeked::Twice((first, second @ Some(_))) => {
self.peeked = Peeked::once(first);
second
},
Peeked::Twice((first, None)) => first
}
}
}
#[inline]
fn rfold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
where Fold: FnMut(Acc, Self::Item) -> Acc
{
match self.peeked.drain() {
Peeked::Once((_, None)) | Peeked::Twice((None, _)) => init,
Peeked::Empty => self.iter.rfold(init, fold),
Peeked::Once((_, Some(last))) => {
let acc = self.iter.rfold(init, &mut fold);
fold(acc, last)
},
Peeked::Twice((Some(last), Some(s_last))) => {
let acc = self.iter.rfold(init, &mut fold);
let acc = fold(acc, s_last);
fold(acc, last)
},
Peeked::Twice((Some(last), None)) => fold(init, last)
}
}
#[inline]
fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
where
Self: Sized,
P: FnMut(&Self::Item) -> bool,
{
if let found @ Some(_) = self.iter.rfind(&mut predicate) {
return found;
}
match self.peeked.drain() {
Peeked::Empty | Peeked::Once((_, None)) | Peeked::Twice((None, _)) => None,
Peeked::Once((_, Some(elem))) => predicate(&elem).then_some(elem),
Peeked::Twice((Some(last), Some(s_last))) => if predicate(&s_last) {
self.peeked = Peeked::once(Some(last));
Some(s_last)
} else {
predicate(&last).then_some(last)
},
Peeked::Twice((Some(last), None)) => predicate(&last).then_some(last)
}
}
}
#[cfg(test)]
mod tests {
extern crate alloc;
use super::*;
use alloc::{format, vec::Vec};
use proptest::prelude::*;
#[test]
fn find_map_peek_2_drain() {
let collection = [1, 2, 3, 4, 5];
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek_2();
assert_eq!(
iter.find_map(|elem| u8::try_from(*elem).ok()).unwrap(),
iter_spec.find_map(|elem| u8::try_from(*elem).ok()).unwrap()
);
assert_eq!(
iter.find_map(|elem| u8::try_from(*elem).ok()).unwrap(),
iter_spec.find_map(|elem| u8::try_from(*elem).ok()).unwrap()
);
assert_eq!(
iter.find_map(|elem| u8::try_from(*elem).ok()).unwrap(),
iter_spec.find_map(|elem| u8::try_from(*elem).ok()).unwrap()
);
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(50_000))]
#[test]
fn iter_find(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
match Peekable::new(collection.iter()).find(|elem| *elem == &to_find) {
Some(elem) => prop_assert_eq!(*elem, to_find),
None => prop_assert!(collection.into_iter().find(|elem| elem == &to_find).is_none())
}
}
#[test]
fn iter_find_with_peeked(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek();
match iter.find(|elem| *elem == &to_find) {
Some(elem) => prop_assert_eq!(*elem, to_find),
None => prop_assert!(collection.into_iter().find(|elem| elem == &to_find).is_none())
}
}
#[test]
fn iter_find_with_peeked_2(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek_2();
match iter.find(|elem| *elem == &to_find) {
Some(elem) => prop_assert_eq!(*elem, to_find),
None => prop_assert!(collection.into_iter().find(|elem| elem == &to_find).is_none())
}
}
#[test]
fn iter_find_many(collection in any::<Vec<u8>>(), to_find in any::<u8>(), times in 0..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
for _ in 0..times {
match iter.find(|elem| *elem == &to_find) {
Some(elem) => prop_assert_eq!(elem, iter_spec.find(|elem| *elem == &to_find).unwrap()),
None => prop_assert!(iter_spec.find(|elem| *elem == &to_find).is_none())
}
}
}
#[test]
fn iter_find_many_peeked(collection in any::<Vec<u8>>(), to_find in any::<u8>(), times in 0..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek();
for _ in 0..times {
match iter.find(|elem| *elem == &to_find) {
Some(elem) => prop_assert_eq!(elem, iter_spec.find(|elem| *elem == &to_find).unwrap()),
None => prop_assert!(iter_spec.find(|elem| *elem == &to_find).is_none())
}
}
}
#[test]
fn iter_find_many_peeked_2(collection in any::<Vec<u8>>(), to_find in any::<u8>(), times in 0..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek_2();
for _ in 0..times {
match iter.find(|elem| *elem == &to_find) {
Some(elem) => prop_assert_eq!(elem, iter_spec.find(|elem| *elem == &to_find).unwrap()),
None => prop_assert!(iter_spec.find(|elem| *elem == &to_find).is_none())
}
}
}
#[test]
fn iter_position(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
match Peekable::new(collection.iter()).position(|elem| elem == &to_find) {
Some(pos) => prop_assert_eq!(pos, collection.into_iter().position(|elem| elem == to_find).unwrap()),
None => prop_assert!(collection.into_iter().position(|elem| elem == to_find).is_none())
}
}
#[test]
fn iter_position_peeked(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek();
match iter.position(|elem| elem == &to_find) {
Some(pos) => prop_assert_eq!(pos, collection.into_iter().position(|elem| elem == to_find).unwrap()),
None => prop_assert!(collection.into_iter().position(|elem| elem == to_find).is_none())
}
}
#[test]
fn iter_position_peeked_2(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek_2();
match iter.position(|elem| elem == &to_find) {
Some(pos) => prop_assert_eq!(pos, collection.into_iter().position(|elem| elem == to_find).unwrap()),
None => prop_assert!(collection.into_iter().position(|elem| elem == to_find).is_none())
}
}
#[test]
fn iter_any(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
if Peekable::new(collection.iter()).any(|elem| elem == &to_find) {
prop_assert!(collection.into_iter().any(|elem| elem == to_find))
} else {
prop_assert!(!collection.into_iter().any(|elem| elem == to_find))
}
}
#[test]
fn iter_any_peeked(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek();
if iter.any(|elem| elem == &to_find) {
prop_assert!(collection.into_iter().any(|elem| elem == to_find))
} else {
prop_assert!(!collection.into_iter().any(|elem| elem == to_find))
}
}
#[test]
fn iter_any_peeked_2(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek_2();
if iter.any(|elem| elem == &to_find) {
prop_assert!(collection.into_iter().any(|elem| elem == to_find))
} else {
prop_assert!(!collection.into_iter().any(|elem| elem == to_find))
}
}
#[test]
fn iter_all(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
if Peekable::new(collection.iter()).all(|elem| elem == &to_find) {
prop_assert!(collection.into_iter().all(|elem| elem == to_find))
} else {
prop_assert!(!collection.into_iter().all(|elem| elem == to_find))
}
}
#[test]
fn iter_all_peeked(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek();
if iter.all(|elem| elem == &to_find) {
prop_assert!(collection.into_iter().all(|elem| elem == to_find))
} else {
prop_assert!(!collection.into_iter().all(|elem| elem == to_find))
}
}
#[test]
fn iter_all_peeked_2(collection in any::<Vec<u8>>(), to_find in any::<u8>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek_2();
if iter.all(|elem| elem == &to_find) {
prop_assert!(collection.into_iter().all(|elem| elem == to_find))
} else {
prop_assert!(!collection.into_iter().all(|elem| elem == to_find))
}
}
#[test]
fn iter_nth(amnt in 0..16usize) {
let mut collection = 0..=16;
let res = Peekable::new(collection.clone()).nth(amnt);
prop_assert_eq!(res, collection.nth(amnt));
}
#[test]
fn iter_nth_peeked(amnt in 0..16usize) {
let mut collection = 0..=16;
let mut iter = Peekable::new(collection.clone());
let _ = iter.peek();
let res = iter.nth(amnt);
prop_assert_eq!(res, collection.nth(amnt));
}
#[test]
fn iter_nth_peeked_2(amnt in 0..16usize) {
let mut collection = 0..=16;
let mut iter = Peekable::new(collection.clone());
let _ = iter.peek_2();
let res = iter.nth(amnt);
prop_assert_eq!(res, collection.nth(amnt));
}
#[test]
fn iter_find_map(collection in any::<Vec<usize>>()) {
match Peekable::new(collection.iter()).find_map(|elem| u8::try_from(*elem).ok()) {
Some(m) => prop_assert_eq!(m, collection.into_iter().find_map(|elem| u8::try_from(elem).ok()).unwrap()),
None => prop_assert!(collection.into_iter().find_map(|elem| u8::try_from(elem).ok()).is_none())
}
}
#[test]
fn iter_find_map_peeked(collection in any::<Vec<usize>>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek();
match iter.find_map(|elem| u8::try_from(*elem).ok()) {
Some(m) => prop_assert_eq!(m, collection.into_iter().find_map(|elem| u8::try_from(elem).ok()).unwrap()),
None => prop_assert!(collection.into_iter().find_map(|elem| u8::try_from(elem).ok()).is_none())
}
}
#[test]
fn iter_find_map_peeked_2(collection in any::<Vec<usize>>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek_2();
match iter.find_map(|elem| u8::try_from(*elem).ok()) {
Some(m) => prop_assert_eq!(m, collection.into_iter().find_map(|elem| u8::try_from(elem).ok()).unwrap()),
None => prop_assert!(collection.into_iter().find_map(|elem| u8::try_from(elem).ok()).is_none())
}
}
#[test]
fn iter_find_map_many(collection in any::<Vec<usize>>(), times in 1..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
for _ in 0..times {
prop_assert_eq!(
iter.find_map(|elem| u8::try_from(*elem).ok()),
iter_spec.find_map(|elem| u8::try_from(*elem).ok())
);
}
}
#[test]
fn iter_find_map_many_peeked(collection in any::<Vec<usize>>(), times in 1..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek();
for _ in 0..times {
prop_assert_eq!(
iter.find_map(|elem| u8::try_from(*elem).ok()),
iter_spec.find_map(|elem| u8::try_from(*elem).ok())
);
}
}
#[test]
fn iter_find_map_many_peeked_2(collection in any::<Vec<usize>>(), times in 1..16usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek_2();
for _ in 0..times {
prop_assert_eq!(
iter.find_map(|elem| u16::try_from(*elem).ok()),
iter_spec.find_map(|elem| u16::try_from(*elem).ok())
);
}
}
#[test]
fn iter_last(collection in any::<Vec<usize>>()) {
match Peekable::new(collection.iter()).last() {
Some(m) => prop_assert_eq!(m, collection.iter().last().unwrap()),
None => prop_assert!(collection.last().is_none())
}
}
#[test]
fn iter_last_peeked(collection in any::<Vec<usize>>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek();
match iter.last() {
Some(m) => prop_assert_eq!(m, collection.iter().last().unwrap()),
None => prop_assert!(collection.last().is_none())
}
}
#[test]
fn iter_last_peeked_2(collection in any::<Vec<usize>>()) {
let mut iter = Peekable::new(collection.iter());
let _ = iter.peek_2();
match iter.last() {
Some(m) => prop_assert_eq!(m, collection.iter().last().unwrap()),
None => prop_assert!(collection.last().is_none())
}
}
#[test]
fn iter_next_back(collection in any::<Vec<usize>>(), extra_iters in 1..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
loop {
let res = iter.next_back();
let s_res = iter_spec.next_back();
prop_assert_eq!(res, s_res);
if res.is_none() { break; }
}
for _ in 0..extra_iters {
prop_assert_eq!(iter.next_back(), iter_spec.next_back());
}
}
#[test]
fn iter_next_back_peeked(collection in any::<Vec<usize>>(), extra_iters in 1..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek();
loop {
let res = iter.next_back();
let s_res = iter_spec.next_back();
prop_assert_eq!(res, s_res);
if res.is_none() { break; }
}
for _ in 0..extra_iters {
prop_assert_eq!(iter.next_back(), iter_spec.next_back(), "Extra iters failure.");
}
}
#[test]
fn iter_next_back_peeked_2(collection in any::<Vec<usize>>(), extra_iters in 1..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek_2();
loop {
let res = iter.next_back();
let s_res = iter_spec.next_back();
prop_assert_eq!(res, s_res);
if res.is_none() { break; }
}
for _ in 0..extra_iters {
prop_assert_eq!(iter.next_back(), iter_spec.next_back(), "Extra iters failure.");
}
}
#[test]
fn iter_rfind(collection in any::<Vec<usize>>(), extra_iters in 1..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
loop {
let res = iter.rfind(|x| *x == &0);
let s_res = iter_spec.rfind(|x| *x == &0);
prop_assert_eq!(res, s_res);
if res.is_none() { break; }
}
for _ in 0..extra_iters {
prop_assert_eq!(iter.rfind(|x| *x == &0), iter_spec.rfind(|x| *x == &0), "Extra iters failure.");
}
}
#[test]
fn iter_rfind_peeked(collection in any::<Vec<usize>>(), extra_iters in 1..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek();
loop {
let res = iter.rfind(|x| *x == &0);
let s_res = iter_spec.rfind(|x| *x == &0);
prop_assert_eq!(res, s_res);
if res.is_none() { break; }
}
for _ in 0..extra_iters {
prop_assert_eq!(iter.rfind(|x| *x == &0), iter_spec.rfind(|x| *x == &0), "Extra iters failure.");
}
}
#[test]
fn iter_rfind_peeked_2(collection in any::<Vec<usize>>(), extra_iters in 1..7usize) {
let mut iter = Peekable::new(collection.iter());
let mut iter_spec = collection.iter();
let _ = iter.peek_2();
loop {
let res = iter.rfind(|x| *x == &0);
let s_res = iter_spec.rfind(|x| *x == &0);
prop_assert_eq!(res, s_res);
if res.is_none() { break; }
}
for _ in 0..extra_iters {
prop_assert_eq!(iter.rfind(|x| *x == &0), iter_spec.rfind(|x| *x == &0), "Extra iters failure.");
}
}
}
}