par_iter/iter/
len.rs

1use super::{plumbing::*, *};
2
3/// `MinLen` is an iterator that imposes a minimum length on iterator splits.
4/// This struct is created by the [`with_min_len()`] method on
5/// [`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
76            fn callback<P>(self, base: P) -> CB::Output
77            where
78                P: Producer<Item = T>,
79            {
80                let producer = MinLenProducer {
81                    base,
82                    min: self.min,
83                };
84                self.callback.callback(producer)
85            }
86        }
87    }
88}
89
90/// ////////////////////////////////////////////////////////////////////////
91/// `MinLenProducer` implementation
92
93struct MinLenProducer<P> {
94    base: P,
95    min: usize,
96}
97
98impl<P> Producer for MinLenProducer<P>
99where
100    P: Producer,
101{
102    type IntoIter = P::IntoIter;
103    type Item = P::Item;
104
105    fn into_iter(self) -> Self::IntoIter {
106        self.base.into_iter()
107    }
108
109    fn min_len(&self) -> usize {
110        Ord::max(self.min, self.base.min_len())
111    }
112
113    fn max_len(&self) -> usize {
114        self.base.max_len()
115    }
116
117    fn split_at(self, index: usize) -> (Self, Self) {
118        let (left, right) = self.base.split_at(index);
119        (
120            MinLenProducer {
121                base: left,
122                min: self.min,
123            },
124            MinLenProducer {
125                base: right,
126                min: self.min,
127            },
128        )
129    }
130
131    fn fold_with<F>(self, folder: F) -> F
132    where
133        F: Folder<Self::Item>,
134    {
135        self.base.fold_with(folder)
136    }
137}
138
139/// `MaxLen` is an iterator that imposes a maximum length on iterator splits.
140/// This struct is created by the [`with_max_len()`] method on
141/// [`IndexedParallelIterator`]
142///
143/// [`with_max_len()`]: trait.IndexedParallelIterator.html#method.with_max_len
144/// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
145#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
146#[derive(Debug, Clone)]
147pub struct MaxLen<I: IndexedParallelIterator> {
148    base: I,
149    max: usize,
150}
151
152impl<I> MaxLen<I>
153where
154    I: IndexedParallelIterator,
155{
156    /// Creates a new `MaxLen` iterator.
157    pub(super) fn new(base: I, max: usize) -> Self {
158        MaxLen { base, max }
159    }
160}
161
162impl<I> ParallelIterator for MaxLen<I>
163where
164    I: IndexedParallelIterator,
165{
166    type Item = I::Item;
167
168    fn drive_unindexed<C>(self, consumer: C) -> C::Result
169    where
170        C: UnindexedConsumer<Self::Item>,
171    {
172        bridge(self, consumer)
173    }
174
175    fn opt_len(&self) -> Option<usize> {
176        Some(self.len())
177    }
178}
179
180impl<I> IndexedParallelIterator for MaxLen<I>
181where
182    I: IndexedParallelIterator,
183{
184    fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
185        bridge(self, consumer)
186    }
187
188    fn len(&self) -> usize {
189        self.base.len()
190    }
191
192    fn with_producer<CB>(self, callback: CB) -> CB::Output
193    where
194        CB: ProducerCallback<Self::Item>,
195    {
196        return self.base.with_producer(Callback {
197            callback,
198            max: self.max,
199        });
200
201        struct Callback<CB> {
202            callback: CB,
203            max: usize,
204        }
205
206        impl<T, CB> ProducerCallback<T> for Callback<CB>
207        where
208            CB: ProducerCallback<T>,
209        {
210            type Output = CB::Output;
211
212            fn callback<P>(self, base: P) -> CB::Output
213            where
214                P: Producer<Item = T>,
215            {
216                let producer = MaxLenProducer {
217                    base,
218                    max: self.max,
219                };
220                self.callback.callback(producer)
221            }
222        }
223    }
224}
225
226/// ////////////////////////////////////////////////////////////////////////
227/// `MaxLenProducer` implementation
228
229struct MaxLenProducer<P> {
230    base: P,
231    max: usize,
232}
233
234impl<P> Producer for MaxLenProducer<P>
235where
236    P: Producer,
237{
238    type IntoIter = P::IntoIter;
239    type Item = P::Item;
240
241    fn into_iter(self) -> Self::IntoIter {
242        self.base.into_iter()
243    }
244
245    fn min_len(&self) -> usize {
246        self.base.min_len()
247    }
248
249    fn max_len(&self) -> usize {
250        Ord::min(self.max, self.base.max_len())
251    }
252
253    fn split_at(self, index: usize) -> (Self, Self) {
254        let (left, right) = self.base.split_at(index);
255        (
256            MaxLenProducer {
257                base: left,
258                max: self.max,
259            },
260            MaxLenProducer {
261                base: right,
262                max: self.max,
263            },
264        )
265    }
266
267    fn fold_with<F>(self, folder: F) -> F
268    where
269        F: Folder<Self::Item>,
270    {
271        self.base.fold_with(folder)
272    }
273}