• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::plumbing::*;
2 use 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)]
11 pub struct MinLen<I: IndexedParallelIterator> {
12     base: I,
13     min: usize,
14 }
15 
16 impl<I> MinLen<I>
17 where
18     I: IndexedParallelIterator,
19 {
20     /// Creates a new `MinLen` iterator.
new(base: I, min: usize) -> Self21     pub(super) fn new(base: I, min: usize) -> Self {
22         MinLen { base, min }
23     }
24 }
25 
26 impl<I> ParallelIterator for MinLen<I>
27 where
28     I: IndexedParallelIterator,
29 {
30     type Item = I::Item;
31 
drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,32     fn drive_unindexed<C>(self, consumer: C) -> C::Result
33     where
34         C: UnindexedConsumer<Self::Item>,
35     {
36         bridge(self, consumer)
37     }
38 
opt_len(&self) -> Option<usize>39     fn opt_len(&self) -> Option<usize> {
40         Some(self.len())
41     }
42 }
43 
44 impl<I> IndexedParallelIterator for MinLen<I>
45 where
46     I: IndexedParallelIterator,
47 {
drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result48     fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
49         bridge(self, consumer)
50     }
51 
len(&self) -> usize52     fn len(&self) -> usize {
53         self.base.len()
54     }
55 
with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,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 
92 struct MinLenProducer<P> {
93     base: P,
94     min: usize,
95 }
96 
97 impl<P> Producer for MinLenProducer<P>
98 where
99     P: Producer,
100 {
101     type Item = P::Item;
102     type IntoIter = P::IntoIter;
103 
into_iter(self) -> Self::IntoIter104     fn into_iter(self) -> Self::IntoIter {
105         self.base.into_iter()
106     }
107 
min_len(&self) -> usize108     fn min_len(&self) -> usize {
109         Ord::max(self.min, self.base.min_len())
110     }
111 
max_len(&self) -> usize112     fn max_len(&self) -> usize {
113         self.base.max_len()
114     }
115 
split_at(self, index: usize) -> (Self, Self)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 
fold_with<F>(self, folder: F) -> F where F: Folder<Self::Item>,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)]
145 pub struct MaxLen<I: IndexedParallelIterator> {
146     base: I,
147     max: usize,
148 }
149 
150 impl<I> MaxLen<I>
151 where
152     I: IndexedParallelIterator,
153 {
154     /// Creates a new `MaxLen` iterator.
new(base: I, max: usize) -> Self155     pub(super) fn new(base: I, max: usize) -> Self {
156         MaxLen { base, max }
157     }
158 }
159 
160 impl<I> ParallelIterator for MaxLen<I>
161 where
162     I: IndexedParallelIterator,
163 {
164     type Item = I::Item;
165 
drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,166     fn drive_unindexed<C>(self, consumer: C) -> C::Result
167     where
168         C: UnindexedConsumer<Self::Item>,
169     {
170         bridge(self, consumer)
171     }
172 
opt_len(&self) -> Option<usize>173     fn opt_len(&self) -> Option<usize> {
174         Some(self.len())
175     }
176 }
177 
178 impl<I> IndexedParallelIterator for MaxLen<I>
179 where
180     I: IndexedParallelIterator,
181 {
drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result182     fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
183         bridge(self, consumer)
184     }
185 
len(&self) -> usize186     fn len(&self) -> usize {
187         self.base.len()
188     }
189 
with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,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 
226 struct MaxLenProducer<P> {
227     base: P,
228     max: usize,
229 }
230 
231 impl<P> Producer for MaxLenProducer<P>
232 where
233     P: Producer,
234 {
235     type Item = P::Item;
236     type IntoIter = P::IntoIter;
237 
into_iter(self) -> Self::IntoIter238     fn into_iter(self) -> Self::IntoIter {
239         self.base.into_iter()
240     }
241 
min_len(&self) -> usize242     fn min_len(&self) -> usize {
243         self.base.min_len()
244     }
245 
max_len(&self) -> usize246     fn max_len(&self) -> usize {
247         Ord::min(self.max, self.base.max_len())
248     }
249 
split_at(self, index: usize) -> (Self, Self)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 
fold_with<F>(self, folder: F) -> F where F: Folder<Self::Item>,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 }
271