1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
use std::iter::IntoIterator;
use tea_dtype::IsNone;
use super::trusted::TrustedLen;
/// A trait combining `Iterator`, `DoubleEndedIterator`, and `TrustedLen` capabilities.
pub trait TIterator: Iterator + DoubleEndedIterator + TrustedLen {}
impl<I: Iterator + DoubleEndedIterator + TrustedLen> TIterator for I {}
/// A trait providing additional iterator methods for types that can be converted into an iterator.
pub trait IterBasic: IntoIterator + Sized {
/// Folds the elements of the iterator, skipping `None` values.
///
/// # Arguments
/// * `init` - The initial value for the fold operation.
/// * `f` - A closure that takes the accumulator and a non-None item, returning a new accumulator.
///
/// # Returns
/// The final accumulated value.
#[inline]
fn vfold<U, F>(self, init: U, mut f: F) -> U
where
F: FnMut(U, Self::Item) -> U,
Self::Item: IsNone,
{
self.into_iter()
.fold(init, |acc, v| if v.not_none() { f(acc, v) } else { acc })
}
/// Folds two iterators together, skipping `None` values from either iterator.
///
/// # Arguments
/// * `other` - The second iterator to fold with.
/// * `init` - The initial value for the fold operation.
/// * `f` - A closure that takes the accumulator and non-None items from both iterators, returning a new accumulator.
///
/// # Returns
/// The final accumulated value.
#[inline]
fn vfold2<U, I2, F>(self, other: I2, init: U, mut f: F) -> U
where
I2: IntoIterator,
I2::Item: IsNone,
F: FnMut(U, Self::Item, I2::Item) -> U,
Self::Item: IsNone,
{
self.into_iter().zip(other).fold(init, |acc, (va, vb)| {
if va.not_none() && vb.not_none() {
f(acc, va, vb)
} else {
acc
}
})
}
/// Folds the elements of the iterator, skipping `None` values and counting non-None elements.
///
/// # Arguments
/// * `init` - The initial value for the fold operation.
/// * `f` - A closure that takes the accumulator and the inner value of a non-None item, returning a new accumulator.
///
/// # Returns
/// A tuple containing the count of non-None elements and the final accumulated value.
#[inline]
fn vfold_n<U, F>(self, init: U, mut f: F) -> (usize, U)
where
F: FnMut(U, <Self::Item as IsNone>::Inner) -> U,
Self::Item: IsNone,
{
let mut n = 0;
let acc = self.into_iter().fold(init, |acc, v| {
if v.not_none() {
n += 1;
f(acc, v.unwrap())
} else {
acc
}
});
(n, acc)
}
/// Applies a function to each non-None element of the iterator.
///
/// # Arguments
/// * `f` - A closure that takes the inner value of a non-None item and performs some operation.
#[inline]
fn vapply<F>(self, mut f: F)
where
F: FnMut(<Self::Item as IsNone>::Inner),
Self::Item: IsNone,
{
self.into_iter().fold((), |(), v| {
if v.not_none() {
f(v.unwrap())
}
})
}
/// Applies a function to each non-None element of the iterator and counts the number of applications.
///
/// # Arguments
/// * `f` - A closure that takes the inner value of a non-None item and performs some operation.
///
/// # Returns
/// The number of non-None elements processed.
#[inline]
fn vapply_n<F>(self, mut f: F) -> usize
where
F: FnMut(<Self::Item as IsNone>::Inner),
Self::Item: IsNone,
{
let mut n = 0;
self.into_iter().fold((), |(), v| {
if v.not_none() {
n += 1;
f(v.unwrap())
}
});
n
}
}
impl<I: IntoIterator + Sized> IterBasic for I {}