use core::iter::FusedIterator;
use crate::{CovariantLending, FusedLender, IntoLender, prelude::*};
#[inline]
pub fn from_iter<I: Iterator>(iter: I) -> FromIter<I> {
FromIter { iter }
}
#[derive(Clone, Debug)]
#[repr(transparent)]
#[must_use = "lenders are lazy and do nothing unless consumed"]
pub struct FromIter<I> {
iter: I,
}
impl<I: Iterator> Lending<'_> for FromIter<I> {
type Lend = I::Item;
}
impl<I: Iterator> Lender for FromIter<I> {
crate::check_covariance!();
#[inline(always)]
fn next(&mut self) -> Option<Lend<'_, Self>> {
self.iter.next()
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline(always)]
fn nth(&mut self, n: usize) -> Option<Lend<'_, Self>> {
self.iter.nth(n)
}
#[inline(always)]
fn count(self) -> usize
where
Self: Sized,
{
self.iter.count()
}
#[inline(always)]
fn fold<B, F>(self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Lend<'_, Self>) -> B,
{
self.iter.fold(init, f)
}
}
impl<I: DoubleEndedIterator> DoubleEndedLender for FromIter<I> {
#[inline(always)]
fn next_back(&mut self) -> Option<Lend<'_, Self>> {
self.iter.next_back()
}
#[inline(always)]
fn nth_back(&mut self, n: usize) -> Option<Lend<'_, Self>> {
self.iter.nth_back(n)
}
#[inline(always)]
fn rfold<B, F>(self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Lend<'_, Self>) -> B,
{
self.iter.rfold(init, f)
}
}
impl<I: ExactSizeIterator> ExactSizeLender for FromIter<I> {
#[inline(always)]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<I: FusedIterator> FusedLender for FromIter<I> {}
impl<I: Iterator> From<I> for FromIter<I> {
#[inline(always)]
fn from(iter: I) -> Self {
from_iter(iter)
}
}
#[inline]
pub fn from_into_iter<I: IntoIterator>(into_iter: I) -> FromIntoIter<I> {
FromIntoIter { into_iter }
}
#[repr(transparent)]
#[derive(Clone, Debug)]
pub struct FromIntoIter<I> {
into_iter: I,
}
impl<I: IntoIterator> IntoLender for FromIntoIter<I> {
type Lender = FromIter<I::IntoIter>;
#[inline(always)]
fn into_lender(self) -> <Self as IntoLender>::Lender {
self.into_iter.into_iter().into_lender()
}
}
impl<I: IntoIterator> From<I> for FromIntoIter<I> {
#[inline(always)]
fn from(into_iter: I) -> Self {
from_into_iter(into_iter)
}
}
#[inline]
pub fn lend_iter<'a, L, I>(iter: I) -> LendIter<'a, L, I>
where
L: ?Sized + CovariantLending + 'a,
I: Iterator<Item = Lend<'a, L>>,
{
let _ = L::__check_covariance(crate::CovariantProof::new());
LendIter {
iter,
_marker: core::marker::PhantomData,
}
}
#[derive(Clone, Debug)]
#[must_use = "lenders are lazy and do nothing unless consumed"]
pub struct LendIter<'a, L: ?Sized, I> {
iter: I,
_marker: core::marker::PhantomData<&'a L>,
}
impl<'a, 'lend, L, I> Lending<'lend> for LendIter<'a, L, I>
where
L: ?Sized + CovariantLending + 'a,
I: Iterator<Item = Lend<'a, L>>,
{
type Lend = Lend<'lend, L>;
}
impl<'a, L, I> Lender for LendIter<'a, L, I>
where
L: ?Sized + CovariantLending + 'a,
I: Iterator<Item = Lend<'a, L>>,
{
crate::unsafe_assume_covariance!();
#[inline]
fn next(&mut self) -> Option<Lend<'_, Self>> {
unsafe {
core::mem::transmute::<Option<Lend<'a, L>>, Option<Lend<'_, L>>>(self.iter.next())
}
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Lend<'_, Self>> {
unsafe {
core::mem::transmute::<Option<Lend<'a, L>>, Option<Lend<'_, L>>>(self.iter.nth(n))
}
}
#[inline(always)]
fn count(self) -> usize
where
Self: Sized,
{
self.iter.count()
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Lend<'_, Self>) -> B,
{
self.iter.fold(init, |acc, x| {
f(acc, unsafe {
core::mem::transmute::<Lend<'a, L>, Lend<'_, L>>(x)
})
})
}
}
impl<'a, L, I> DoubleEndedLender for LendIter<'a, L, I>
where
L: ?Sized + CovariantLending + 'a,
I: DoubleEndedIterator<Item = Lend<'a, L>>,
{
#[inline]
fn next_back(&mut self) -> Option<Lend<'_, Self>> {
unsafe {
core::mem::transmute::<Option<Lend<'a, L>>, Option<Lend<'_, L>>>(self.iter.next_back())
}
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Lend<'_, Self>> {
unsafe {
core::mem::transmute::<Option<Lend<'a, L>>, Option<Lend<'_, L>>>(self.iter.nth_back(n))
}
}
#[inline]
fn rfold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Lend<'_, Self>) -> B,
{
self.iter.rfold(init, |acc, x| {
f(acc, unsafe {
core::mem::transmute::<Lend<'a, L>, Lend<'_, L>>(x)
})
})
}
}
impl<'a, L, I> ExactSizeLender for LendIter<'a, L, I>
where
L: ?Sized + CovariantLending + 'a,
I: ExactSizeIterator<Item = Lend<'a, L>>,
{
#[inline(always)]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<'a, L, I> FusedLender for LendIter<'a, L, I>
where
L: ?Sized + CovariantLending + 'a,
I: FusedIterator<Item = Lend<'a, L>>,
{
}