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