use crate::is;
#[doc = crate::_tags!(iterator lifetime)]
#[doc = crate::_doc_location!("data/access/iter")]
#[rustfmt::skip]
pub trait IteratorLending {
type Item<'a> where Self: 'a;
fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
fn count(&mut self) -> usize {
let mut n = 0;
while self.next().is_some() { n += 1; }
n
}
fn advance_by(&mut self, mut n: usize) -> Result<(), usize> {
while n > 0 {
match self.next() {
Some(_) => n -= 1,
None => return Err(n),
}
}
Ok(())
}
fn nth<'a>(&'a mut self, mut n: usize) -> Option<Self::Item<'a>> {
while n > 0 {
is![self.next().is_none(), return None];
n -= 1;
}
self.next()
}
fn for_each<F>(&mut self, mut f: F)
where F: FnMut(Self::Item<'_>) {
while let Some(item) = self.next() { f(item); }
}
fn inspect<F>(&mut self, mut f: F)
where
F: FnMut(&Self::Item<'_>),
{
while let Some(item) = self.next() {
f(&item);
}
}
fn is_partitioned<P>(&mut self, mut pred: P) -> bool
where
P: FnMut(&Self::Item<'_>) -> bool,
{
let mut seen_false = false;
while let Some(item) = self.next() {
if pred(&item) {
if seen_false { return false; }
} else {
seen_false = true;
}
}
true
}
fn try_fold<B, E, F>(&mut self, mut acc: B, mut f: F) -> Result<B, E>
where
F: FnMut(B, Self::Item<'_>) -> Result<B, E>,
{
while let Some(item) = self.next() {
acc = f(acc, item)?;
}
Ok(acc)
}
fn try_for_each<F, E>(&mut self, mut f: F) -> Result<(), E>
where F: FnMut(Self::Item<'_>) -> Result<(), E> {
while let Some(item) = self.next() { f(item)?; }
Ok(())
}
fn all<P>(&mut self, mut pred: P) -> bool
where
P: FnMut(&Self::Item<'_>) -> bool,
{
while let Some(item) = self.next() { is![!pred(&item), return false]; }
true
}
fn any<P>(&mut self, mut pred: P) -> bool
where
P: FnMut(&Self::Item<'_>) -> bool,
{
while let Some(item) = self.next() { is![pred(&item), return true]; }
false
}
fn position<P>(&mut self, mut pred: P) -> Option<usize>
where
P: FnMut(&Self::Item<'_>) -> bool,
{
let mut index = 0;
while let Some(item) = self.next() {
is![pred(&item), return Some(index)];
index += 1;
}
None
}
}
#[doc = crate::_tags!(iterator lifetime)]
#[doc = crate::_doc_location!("data/access/iter")]
pub trait IteratorLendingDoubleEnded: IteratorLending {
fn next_back<'a>(&'a mut self) -> Option<Self::Item<'a>>;
fn nth_back<'a>(&'a mut self, mut n: usize) -> Option<Self::Item<'a>> {
while n > 0 {
is![self.next_back().is_none(), return None];
n -= 1;
}
self.next_back()
}
fn try_rfold<B, E, F>(&mut self, mut acc: B, mut f: F) -> Result<B, E>
where
F: FnMut(B, Self::Item<'_>) -> Result<B, E>,
{
while let Some(item) = self.next_back() {
acc = f(acc, item)?;
}
Ok(acc)
}
}
#[doc = crate::_tags!(iterator lifetime)]
#[doc = crate::_doc_location!("data/access/iter")]
pub trait IteratorLendingExactSize: IteratorLending {
fn len(&self) -> usize {
let (lower, upper) = self.size_hint();
debug_assert!(upper == Some(lower));
lower
}
fn is_empty(&self) -> bool {
self.len() == 0
}
}
#[doc = crate::_tags!(iterator lifetime)]
#[doc = crate::_doc_location!("data/access/iter")]
pub trait IteratorLendingPeek: IteratorLending {
fn peek<'a>(&'a mut self) -> Option<Self::Item<'a>>;
fn next_if<F>(&mut self, pred: F) -> Option<Self::Item<'_>>
where
for<'a> F: FnOnce(&Self::Item<'a>) -> bool,
{
is![self.peek().is_some_and(|i| pred(&i)), self.next(), None]
}
fn next_if_eq<Q>(&mut self, expected: &Q) -> Option<Self::Item<'_>>
where
for<'a> Self::Item<'a>: PartialEq<Q>,
Q: ?Sized,
{
self.next_if(|item| item == expected)
}
fn next_if_map<R, E, F>(&mut self, f: F) -> Result<Option<R>, E>
where
F: FnOnce(&Self::Item<'_>) -> Result<R, E>,
{
match self.peek().map(|item| f(&item)) {
None => Ok(None),
Some(Ok(r)) => {
self.next();
Ok(Some(r))
}
Some(Err(e)) => Err(e),
}
}
}
#[doc = crate::_tags!(iterator lifetime)]
#[doc = crate::_doc_location!("data/access/iter")]
pub trait IteratorLendingPeekDoubleEnded: IteratorLendingPeek + IteratorLendingDoubleEnded {
fn peek_back<'a>(&'a mut self) -> Option<Self::Item<'a>>;
fn next_back_if<F>(&mut self, pred: F) -> Option<Self::Item<'_>>
where
for<'a> F: FnOnce(&Self::Item<'a>) -> bool,
{
is![self.peek_back().is_some_and(|i| pred(&i)), self.next_back(), None]
}
fn next_back_if_eq<Q>(&mut self, expected: &Q) -> Option<Self::Item<'_>>
where
for<'a> Self::Item<'a>: PartialEq<Q>,
Q: ?Sized,
{
self.next_back_if(|item| item == expected)
}
fn next_back_if_map<R, E, F>(&mut self, f: F) -> Result<Option<R>, E>
where
F: FnOnce(&Self::Item<'_>) -> Result<R, E>,
{
match self.peek_back().map(|item| f(&item)) {
None => Ok(None),
Some(Ok(r)) => {
self.next_back();
Ok(Some(r))
}
Some(Err(e)) => Err(e),
}
}
}