rayon/iter/
len.rs

1use super::plumbing::*;
2use super::*;
3
4/// `MinLen` is an iterator that imposes a minimum length on iterator splits.
5/// This struct is created by the [`with_min_len()`] method on [`IndexedParallelIterator`]
6///
7/// [`with_min_len()`]: IndexedParallelIterator::with_min_len()
8#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
9#[derive(Debug, Clone)]
10pub struct MinLen<I> {
11    base: I,
12    min: usize,
13}
14
15impl<I> MinLen<I> {
16    /// Creates a new `MinLen` iterator.
17    pub(super) fn new(base: I, min: usize) -> Self {
18        MinLen { base, min }
19    }
20}
21
22impl<I> ParallelIterator for MinLen<I>
23where
24    I: IndexedParallelIterator,
25{
26    type Item = I::Item;
27
28    fn drive_unindexed<C>(self, consumer: C) -> C::Result
29    where
30        C: UnindexedConsumer<Self::Item>,
31    {
32        bridge(self, consumer)
33    }
34
35    fn opt_len(&self) -> Option<usize> {
36        Some(self.len())
37    }
38}
39
40impl<I> IndexedParallelIterator for MinLen<I>
41where
42    I: IndexedParallelIterator,
43{
44    fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
45        bridge(self, consumer)
46    }
47
48    fn len(&self) -> usize {
49        self.base.len()
50    }
51
52    fn with_producer<CB>(self, callback: CB) -> CB::Output
53    where
54        CB: ProducerCallback<Self::Item>,
55    {
56        return self.base.with_producer(Callback {
57            callback,
58            min: self.min,
59        });
60
61        struct Callback<CB> {
62            callback: CB,
63            min: usize,
64        }
65
66        impl<T, CB> ProducerCallback<T> for Callback<CB>
67        where
68            CB: ProducerCallback<T>,
69        {
70            type Output = CB::Output;
71            fn callback<P>(self, base: P) -> CB::Output
72            where
73                P: Producer<Item = T>,
74            {
75                let producer = MinLenProducer {
76                    base,
77                    min: self.min,
78                };
79                self.callback.callback(producer)
80            }
81        }
82    }
83}
84
85// ////////////////////////////////////////////////////////////////////////
86// `MinLenProducer` implementation
87
88struct MinLenProducer<P> {
89    base: P,
90    min: usize,
91}
92
93impl<P> Producer for MinLenProducer<P>
94where
95    P: Producer,
96{
97    type Item = P::Item;
98    type IntoIter = P::IntoIter;
99
100    fn into_iter(self) -> Self::IntoIter {
101        self.base.into_iter()
102    }
103
104    fn min_len(&self) -> usize {
105        Ord::max(self.min, self.base.min_len())
106    }
107
108    fn max_len(&self) -> usize {
109        self.base.max_len()
110    }
111
112    fn split_at(self, index: usize) -> (Self, Self) {
113        let (left, right) = self.base.split_at(index);
114        (
115            MinLenProducer {
116                base: left,
117                min: self.min,
118            },
119            MinLenProducer {
120                base: right,
121                min: self.min,
122            },
123        )
124    }
125
126    fn fold_with<F>(self, folder: F) -> F
127    where
128        F: Folder<Self::Item>,
129    {
130        self.base.fold_with(folder)
131    }
132}
133
134/// `MaxLen` is an iterator that imposes a maximum length on iterator splits.
135/// This struct is created by the [`with_max_len()`] method on [`IndexedParallelIterator`]
136///
137/// [`with_max_len()`]: IndexedParallelIterator::with_max_len()
138#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
139#[derive(Debug, Clone)]
140pub struct MaxLen<I> {
141    base: I,
142    max: usize,
143}
144
145impl<I> MaxLen<I> {
146    /// Creates a new `MaxLen` iterator.
147    pub(super) fn new(base: I, max: usize) -> Self {
148        MaxLen { base, max }
149    }
150}
151
152impl<I> ParallelIterator for MaxLen<I>
153where
154    I: IndexedParallelIterator,
155{
156    type Item = I::Item;
157
158    fn drive_unindexed<C>(self, consumer: C) -> C::Result
159    where
160        C: UnindexedConsumer<Self::Item>,
161    {
162        bridge(self, consumer)
163    }
164
165    fn opt_len(&self) -> Option<usize> {
166        Some(self.len())
167    }
168}
169
170impl<I> IndexedParallelIterator for MaxLen<I>
171where
172    I: IndexedParallelIterator,
173{
174    fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
175        bridge(self, consumer)
176    }
177
178    fn len(&self) -> usize {
179        self.base.len()
180    }
181
182    fn with_producer<CB>(self, callback: CB) -> CB::Output
183    where
184        CB: ProducerCallback<Self::Item>,
185    {
186        return self.base.with_producer(Callback {
187            callback,
188            max: self.max,
189        });
190
191        struct Callback<CB> {
192            callback: CB,
193            max: usize,
194        }
195
196        impl<T, CB> ProducerCallback<T> for Callback<CB>
197        where
198            CB: ProducerCallback<T>,
199        {
200            type Output = CB::Output;
201            fn callback<P>(self, base: P) -> CB::Output
202            where
203                P: Producer<Item = T>,
204            {
205                let producer = MaxLenProducer {
206                    base,
207                    max: self.max,
208                };
209                self.callback.callback(producer)
210            }
211        }
212    }
213}
214
215// ////////////////////////////////////////////////////////////////////////
216// `MaxLenProducer` implementation
217
218struct MaxLenProducer<P> {
219    base: P,
220    max: usize,
221}
222
223impl<P> Producer for MaxLenProducer<P>
224where
225    P: Producer,
226{
227    type Item = P::Item;
228    type IntoIter = P::IntoIter;
229
230    fn into_iter(self) -> Self::IntoIter {
231        self.base.into_iter()
232    }
233
234    fn min_len(&self) -> usize {
235        self.base.min_len()
236    }
237
238    fn max_len(&self) -> usize {
239        Ord::min(self.max, self.base.max_len())
240    }
241
242    fn split_at(self, index: usize) -> (Self, Self) {
243        let (left, right) = self.base.split_at(index);
244        (
245            MaxLenProducer {
246                base: left,
247                max: self.max,
248            },
249            MaxLenProducer {
250                base: right,
251                max: self.max,
252            },
253        )
254    }
255
256    fn fold_with<F>(self, folder: F) -> F
257    where
258        F: Folder<Self::Item>,
259    {
260        self.base.fold_with(folder)
261    }
262}