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