use std::marker::PhantomData;
use crate::prelude::*;
pub trait TIter<T>: GetLen {
fn titer(&self) -> impl TIterator<Item = T> + '_;
#[inline]
fn map<'a, U, F>(&'a self, f: F) -> impl TIterator<Item = U>
where
F: FnMut(T) -> U,
T: 'a,
{
self.titer().map(f)
}
}
pub trait IntoTIter: IntoIterator
where
Self::IntoIter: TIterator,
{
fn into_titer(self) -> Self::IntoIter
where
Self: Sized;
}
impl<I: IntoIterator + GetLen> IntoTIter for I
where
Self::IntoIter: TIterator,
{
#[inline]
fn into_titer(self) -> Self::IntoIter {
self.into_iter()
}
}
pub struct OptIter<'a, V: Vec1View<T>, T> {
pub view: &'a V,
pub item: PhantomData<T>,
}
impl<V: Vec1View<T>, T> GetLen for OptIter<'_, V, T> {
#[inline]
fn len(&self) -> usize {
self.view.len()
}
}
impl<V: Vec1View<T>, T: IsNone> TIter<Option<<T as IsNone>::Inner>> for OptIter<'_, V, T> {
#[inline]
fn titer(&self) -> impl TIterator<Item = Option<<T as IsNone>::Inner>> {
self.view.titer().map(|v| v.to_opt())
}
}
impl<'a, T: IsNone + 'a, V: Vec1View<T>> Vec1View<Option<T::Inner>> for OptIter<'a, V, T>
where
for<'b> V::SliceOutput<'b>: TIter<T>,
{
type SliceOutput<'b>
= Vec<Option<T::Inner>>
where
Self: 'b;
#[inline]
fn slice<'b>(&'b self, start: usize, end: usize) -> TResult<Self::SliceOutput<'b>>
where
T: 'b,
{
Ok(self
.view
.slice(start, end)?
.titer()
.map(|v| v.to_opt())
.collect_trusted_to_vec())
}
#[inline]
fn get_backend_name(&self) -> &'static str {
self.view.get_backend_name()
}
#[inline]
unsafe fn uget(&self, index: usize) -> Option<T::Inner> {
unsafe { self.view.uget(index).to_opt() }
}
}
impl<'a, V: Vec1View<T>, T: IsNone> IntoIterator for &'a OptIter<'_, V, T> {
type Item = Option<T::Inner>;
type IntoIter = Box<dyn TrustedLen<Item = Option<T::Inner>> + 'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Box::new(self.titer())
}
}