orx_parallel/infallible/
xap_iter.rs1use crate::infallible::Xap;
2use core::iter::Fuse;
3
4#[must_use = "iterators are lazy and do nothing unless consumed"]
9pub struct XapIter<I, X>
10where
11 I: Iterator,
12 X: Xap<I = I::Item>,
13{
14 iter: Fuse<I>,
15 xap: X,
16 values: Option<<X::Values as IntoIterator>::IntoIter>,
17}
18
19impl<I, X> XapIter<I, X>
20where
21 I: Iterator,
22 X: Xap<I = I::Item>,
23{
24 pub fn new(iter: I, xap: X) -> Self {
26 Self {
27 iter: iter.fuse(),
28 xap,
29 values: None,
30 }
31 }
32}
33
34impl<I, X> Iterator for XapIter<I, X>
35where
36 I: Iterator,
37 X: Xap<I = I::Item>,
38{
39 type Item = X::O;
40
41 #[inline]
42 fn next(&mut self) -> Option<Self::Item> {
43 loop {
44 if let Some(values) = &mut self.values
45 && let Some(value) = values.next()
46 {
47 return Some(value);
48 }
49
50 self.values = None;
51
52 let input = self.iter.next()?;
53 self.values = Some(self.xap.xap(input).into_iter());
54 }
55 }
56
57 #[inline]
58 fn size_hint(&self) -> (usize, Option<usize>) {
59 let (values_lower, values_upper) = self
60 .values
61 .as_ref()
62 .map_or((0, Some(0)), Iterator::size_hint);
63 let (iter_lower, iter_upper) = self.iter.size_hint();
64 let (transformed_lower, transformed_upper) =
65 <X::Size as crate::sizes::Size>::transformed_size_hint((iter_lower, iter_upper));
66
67 let lower = values_lower.saturating_add(transformed_lower);
68 let upper = values_upper.and_then(|values_upper| {
69 transformed_upper
70 .and_then(|transformed_upper| values_upper.checked_add(transformed_upper))
71 });
72 (lower, upper)
73 }
74
75 #[inline]
76 fn fold<B, F>(self, init: B, mut f: F) -> B
77 where
78 F: FnMut(B, Self::Item) -> B,
79 {
80 let mut result = init;
81 if let Some(values) = self.values {
82 result = values.fold(result, &mut f);
83 }
84 for input in self.iter {
85 result = self.xap.xap(input).into_iter().fold(result, &mut f);
86 }
87 result
88 }
89}