1 use super::plumbing::*;
2 use super::*;
3 
4 use std::fmt::{self, Debug};
5 
6 /// `MapWith` is an iterator that transforms the elements of an underlying iterator.
7 ///
8 /// This struct is created by the [`map_with()`] method on [`ParallelIterator`]
9 ///
10 /// [`map_with()`]: trait.ParallelIterator.html#method.map_with
11 /// [`ParallelIterator`]: trait.ParallelIterator.html
12 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13 #[derive(Clone)]
14 pub struct MapWith<I: ParallelIterator, T, F> {
15     base: I,
16     item: T,
17     map_op: F,
18 }
19 
20 impl<I: ParallelIterator + Debug, T: Debug, F> Debug for MapWith<I, T, F> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result21     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22         f.debug_struct("MapWith")
23             .field("base", &self.base)
24             .field("item", &self.item)
25             .finish()
26     }
27 }
28 
29 impl<I, T, F> MapWith<I, T, F>
30 where
31     I: ParallelIterator,
32 {
33     /// Creates a new `MapWith` iterator.
new(base: I, item: T, map_op: F) -> Self34     pub(super) fn new(base: I, item: T, map_op: F) -> Self {
35         MapWith { base, item, map_op }
36     }
37 }
38 
39 impl<I, T, F, R> ParallelIterator for MapWith<I, T, F>
40 where
41     I: ParallelIterator,
42     T: Send + Clone,
43     F: Fn(&mut T, I::Item) -> R + Sync + Send,
44     R: Send,
45 {
46     type Item = R;
47 
drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,48     fn drive_unindexed<C>(self, consumer: C) -> C::Result
49     where
50         C: UnindexedConsumer<Self::Item>,
51     {
52         let consumer1 = MapWithConsumer::new(consumer, self.item, &self.map_op);
53         self.base.drive_unindexed(consumer1)
54     }
55 
opt_len(&self) -> Option<usize>56     fn opt_len(&self) -> Option<usize> {
57         self.base.opt_len()
58     }
59 }
60 
61 impl<I, T, F, R> IndexedParallelIterator for MapWith<I, T, F>
62 where
63     I: IndexedParallelIterator,
64     T: Send + Clone,
65     F: Fn(&mut T, I::Item) -> R + Sync + Send,
66     R: Send,
67 {
drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,68     fn drive<C>(self, consumer: C) -> C::Result
69     where
70         C: Consumer<Self::Item>,
71     {
72         let consumer1 = MapWithConsumer::new(consumer, self.item, &self.map_op);
73         self.base.drive(consumer1)
74     }
75 
len(&self) -> usize76     fn len(&self) -> usize {
77         self.base.len()
78     }
79 
with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,80     fn with_producer<CB>(self, callback: CB) -> CB::Output
81     where
82         CB: ProducerCallback<Self::Item>,
83     {
84         return self.base.with_producer(Callback {
85             callback,
86             item: self.item,
87             map_op: self.map_op,
88         });
89 
90         struct Callback<CB, U, F> {
91             callback: CB,
92             item: U,
93             map_op: F,
94         }
95 
96         impl<T, U, F, R, CB> ProducerCallback<T> for Callback<CB, U, F>
97         where
98             CB: ProducerCallback<R>,
99             U: Send + Clone,
100             F: Fn(&mut U, T) -> R + Sync,
101             R: Send,
102         {
103             type Output = CB::Output;
104 
105             fn callback<P>(self, base: P) -> CB::Output
106             where
107                 P: Producer<Item = T>,
108             {
109                 let producer = MapWithProducer {
110                     base,
111                     item: self.item,
112                     map_op: &self.map_op,
113                 };
114                 self.callback.callback(producer)
115             }
116         }
117     }
118 }
119 
120 /// ////////////////////////////////////////////////////////////////////////
121 
122 struct MapWithProducer<'f, P, U, F> {
123     base: P,
124     item: U,
125     map_op: &'f F,
126 }
127 
128 impl<'f, P, U, F, R> Producer for MapWithProducer<'f, P, U, F>
129 where
130     P: Producer,
131     U: Send + Clone,
132     F: Fn(&mut U, P::Item) -> R + Sync,
133     R: Send,
134 {
135     type Item = R;
136     type IntoIter = MapWithIter<'f, P::IntoIter, U, F>;
137 
into_iter(self) -> Self::IntoIter138     fn into_iter(self) -> Self::IntoIter {
139         MapWithIter {
140             base: self.base.into_iter(),
141             item: self.item,
142             map_op: self.map_op,
143         }
144     }
145 
min_len(&self) -> usize146     fn min_len(&self) -> usize {
147         self.base.min_len()
148     }
max_len(&self) -> usize149     fn max_len(&self) -> usize {
150         self.base.max_len()
151     }
152 
split_at(self, index: usize) -> (Self, Self)153     fn split_at(self, index: usize) -> (Self, Self) {
154         let (left, right) = self.base.split_at(index);
155         (
156             MapWithProducer {
157                 base: left,
158                 item: self.item.clone(),
159                 map_op: self.map_op,
160             },
161             MapWithProducer {
162                 base: right,
163                 item: self.item,
164                 map_op: self.map_op,
165             },
166         )
167     }
168 
fold_with<G>(self, folder: G) -> G where G: Folder<Self::Item>,169     fn fold_with<G>(self, folder: G) -> G
170     where
171         G: Folder<Self::Item>,
172     {
173         let folder1 = MapWithFolder {
174             base: folder,
175             item: self.item,
176             map_op: self.map_op,
177         };
178         self.base.fold_with(folder1).base
179     }
180 }
181 
182 struct MapWithIter<'f, I, U, F> {
183     base: I,
184     item: U,
185     map_op: &'f F,
186 }
187 
188 impl<'f, I, U, F, R> Iterator for MapWithIter<'f, I, U, F>
189 where
190     I: Iterator,
191     F: Fn(&mut U, I::Item) -> R + Sync,
192     R: Send,
193 {
194     type Item = R;
195 
next(&mut self) -> Option<R>196     fn next(&mut self) -> Option<R> {
197         let item = self.base.next()?;
198         Some((self.map_op)(&mut self.item, item))
199     }
200 
size_hint(&self) -> (usize, Option<usize>)201     fn size_hint(&self) -> (usize, Option<usize>) {
202         self.base.size_hint()
203     }
204 }
205 
206 impl<'f, I, U, F, R> DoubleEndedIterator for MapWithIter<'f, I, U, F>
207 where
208     I: DoubleEndedIterator,
209     F: Fn(&mut U, I::Item) -> R + Sync,
210     R: Send,
211 {
next_back(&mut self) -> Option<R>212     fn next_back(&mut self) -> Option<R> {
213         let item = self.base.next_back()?;
214         Some((self.map_op)(&mut self.item, item))
215     }
216 }
217 
218 impl<'f, I, U, F, R> ExactSizeIterator for MapWithIter<'f, I, U, F>
219 where
220     I: ExactSizeIterator,
221     F: Fn(&mut U, I::Item) -> R + Sync,
222     R: Send,
223 {
224 }
225 
226 /// ////////////////////////////////////////////////////////////////////////
227 /// Consumer implementation
228 
229 struct MapWithConsumer<'f, C, U, F> {
230     base: C,
231     item: U,
232     map_op: &'f F,
233 }
234 
235 impl<'f, C, U, F> MapWithConsumer<'f, C, U, F> {
new(base: C, item: U, map_op: &'f F) -> Self236     fn new(base: C, item: U, map_op: &'f F) -> Self {
237         MapWithConsumer { base, item, map_op }
238     }
239 }
240 
241 impl<'f, T, U, R, C, F> Consumer<T> for MapWithConsumer<'f, C, U, F>
242 where
243     C: Consumer<R>,
244     U: Send + Clone,
245     F: Fn(&mut U, T) -> R + Sync,
246     R: Send,
247 {
248     type Folder = MapWithFolder<'f, C::Folder, U, F>;
249     type Reducer = C::Reducer;
250     type Result = C::Result;
251 
split_at(self, index: usize) -> (Self, Self, Self::Reducer)252     fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
253         let (left, right, reducer) = self.base.split_at(index);
254         (
255             MapWithConsumer::new(left, self.item.clone(), self.map_op),
256             MapWithConsumer::new(right, self.item, self.map_op),
257             reducer,
258         )
259     }
260 
into_folder(self) -> Self::Folder261     fn into_folder(self) -> Self::Folder {
262         MapWithFolder {
263             base: self.base.into_folder(),
264             item: self.item,
265             map_op: self.map_op,
266         }
267     }
268 
full(&self) -> bool269     fn full(&self) -> bool {
270         self.base.full()
271     }
272 }
273 
274 impl<'f, T, U, R, C, F> UnindexedConsumer<T> for MapWithConsumer<'f, C, U, F>
275 where
276     C: UnindexedConsumer<R>,
277     U: Send + Clone,
278     F: Fn(&mut U, T) -> R + Sync,
279     R: Send,
280 {
split_off_left(&self) -> Self281     fn split_off_left(&self) -> Self {
282         MapWithConsumer::new(self.base.split_off_left(), self.item.clone(), self.map_op)
283     }
284 
to_reducer(&self) -> Self::Reducer285     fn to_reducer(&self) -> Self::Reducer {
286         self.base.to_reducer()
287     }
288 }
289 
290 struct MapWithFolder<'f, C, U, F> {
291     base: C,
292     item: U,
293     map_op: &'f F,
294 }
295 
296 impl<'f, T, U, R, C, F> Folder<T> for MapWithFolder<'f, C, U, F>
297 where
298     C: Folder<R>,
299     F: Fn(&mut U, T) -> R,
300 {
301     type Result = C::Result;
302 
consume(mut self, item: T) -> Self303     fn consume(mut self, item: T) -> Self {
304         let mapped_item = (self.map_op)(&mut self.item, item);
305         self.base = self.base.consume(mapped_item);
306         self
307     }
308 
consume_iter<I>(mut self, iter: I) -> Self where I: IntoIterator<Item = T>,309     fn consume_iter<I>(mut self, iter: I) -> Self
310     where
311         I: IntoIterator<Item = T>,
312     {
313         fn with<'f, T, U, R>(
314             item: &'f mut U,
315             map_op: impl Fn(&mut U, T) -> R + 'f,
316         ) -> impl FnMut(T) -> R + 'f {
317             move |x| map_op(item, x)
318         }
319 
320         {
321             let mapped_iter = iter.into_iter().map(with(&mut self.item, self.map_op));
322             self.base = self.base.consume_iter(mapped_iter);
323         }
324         self
325     }
326 
complete(self) -> C::Result327     fn complete(self) -> C::Result {
328         self.base.complete()
329     }
330 
full(&self) -> bool331     fn full(&self) -> bool {
332         self.base.full()
333     }
334 }
335 
336 // ------------------------------------------------------------------------------------------------
337 
338 /// `MapInit` is an iterator that transforms the elements of an underlying iterator.
339 ///
340 /// This struct is created by the [`map_init()`] method on [`ParallelIterator`]
341 ///
342 /// [`map_init()`]: trait.ParallelIterator.html#method.map_init
343 /// [`ParallelIterator`]: trait.ParallelIterator.html
344 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
345 #[derive(Clone)]
346 pub struct MapInit<I: ParallelIterator, INIT, F> {
347     base: I,
348     init: INIT,
349     map_op: F,
350 }
351 
352 impl<I: ParallelIterator + Debug, INIT, F> Debug for MapInit<I, INIT, F> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result353     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354         f.debug_struct("MapInit").field("base", &self.base).finish()
355     }
356 }
357 
358 impl<I, INIT, F> MapInit<I, INIT, F>
359 where
360     I: ParallelIterator,
361 {
362     /// Creates a new `MapInit` iterator.
new(base: I, init: INIT, map_op: F) -> Self363     pub(super) fn new(base: I, init: INIT, map_op: F) -> Self {
364         MapInit { base, init, map_op }
365     }
366 }
367 
368 impl<I, INIT, T, F, R> ParallelIterator for MapInit<I, INIT, F>
369 where
370     I: ParallelIterator,
371     INIT: Fn() -> T + Sync + Send,
372     F: Fn(&mut T, I::Item) -> R + Sync + Send,
373     R: Send,
374 {
375     type Item = R;
376 
drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,377     fn drive_unindexed<C>(self, consumer: C) -> C::Result
378     where
379         C: UnindexedConsumer<Self::Item>,
380     {
381         let consumer1 = MapInitConsumer::new(consumer, &self.init, &self.map_op);
382         self.base.drive_unindexed(consumer1)
383     }
384 
opt_len(&self) -> Option<usize>385     fn opt_len(&self) -> Option<usize> {
386         self.base.opt_len()
387     }
388 }
389 
390 impl<I, INIT, T, F, R> IndexedParallelIterator for MapInit<I, INIT, F>
391 where
392     I: IndexedParallelIterator,
393     INIT: Fn() -> T + Sync + Send,
394     F: Fn(&mut T, I::Item) -> R + Sync + Send,
395     R: Send,
396 {
drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,397     fn drive<C>(self, consumer: C) -> C::Result
398     where
399         C: Consumer<Self::Item>,
400     {
401         let consumer1 = MapInitConsumer::new(consumer, &self.init, &self.map_op);
402         self.base.drive(consumer1)
403     }
404 
len(&self) -> usize405     fn len(&self) -> usize {
406         self.base.len()
407     }
408 
with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,409     fn with_producer<CB>(self, callback: CB) -> CB::Output
410     where
411         CB: ProducerCallback<Self::Item>,
412     {
413         return self.base.with_producer(Callback {
414             callback,
415             init: self.init,
416             map_op: self.map_op,
417         });
418 
419         struct Callback<CB, INIT, F> {
420             callback: CB,
421             init: INIT,
422             map_op: F,
423         }
424 
425         impl<T, INIT, U, F, R, CB> ProducerCallback<T> for Callback<CB, INIT, F>
426         where
427             CB: ProducerCallback<R>,
428             INIT: Fn() -> U + Sync,
429             F: Fn(&mut U, T) -> R + Sync,
430             R: Send,
431         {
432             type Output = CB::Output;
433 
434             fn callback<P>(self, base: P) -> CB::Output
435             where
436                 P: Producer<Item = T>,
437             {
438                 let producer = MapInitProducer {
439                     base,
440                     init: &self.init,
441                     map_op: &self.map_op,
442                 };
443                 self.callback.callback(producer)
444             }
445         }
446     }
447 }
448 
449 /// ////////////////////////////////////////////////////////////////////////
450 
451 struct MapInitProducer<'f, P, INIT, F> {
452     base: P,
453     init: &'f INIT,
454     map_op: &'f F,
455 }
456 
457 impl<'f, P, INIT, U, F, R> Producer for MapInitProducer<'f, P, INIT, F>
458 where
459     P: Producer,
460     INIT: Fn() -> U + Sync,
461     F: Fn(&mut U, P::Item) -> R + Sync,
462     R: Send,
463 {
464     type Item = R;
465     type IntoIter = MapWithIter<'f, P::IntoIter, U, F>;
466 
into_iter(self) -> Self::IntoIter467     fn into_iter(self) -> Self::IntoIter {
468         MapWithIter {
469             base: self.base.into_iter(),
470             item: (self.init)(),
471             map_op: self.map_op,
472         }
473     }
474 
min_len(&self) -> usize475     fn min_len(&self) -> usize {
476         self.base.min_len()
477     }
max_len(&self) -> usize478     fn max_len(&self) -> usize {
479         self.base.max_len()
480     }
481 
split_at(self, index: usize) -> (Self, Self)482     fn split_at(self, index: usize) -> (Self, Self) {
483         let (left, right) = self.base.split_at(index);
484         (
485             MapInitProducer {
486                 base: left,
487                 init: self.init,
488                 map_op: self.map_op,
489             },
490             MapInitProducer {
491                 base: right,
492                 init: self.init,
493                 map_op: self.map_op,
494             },
495         )
496     }
497 
fold_with<G>(self, folder: G) -> G where G: Folder<Self::Item>,498     fn fold_with<G>(self, folder: G) -> G
499     where
500         G: Folder<Self::Item>,
501     {
502         let folder1 = MapWithFolder {
503             base: folder,
504             item: (self.init)(),
505             map_op: self.map_op,
506         };
507         self.base.fold_with(folder1).base
508     }
509 }
510 
511 /// ////////////////////////////////////////////////////////////////////////
512 /// Consumer implementation
513 
514 struct MapInitConsumer<'f, C, INIT, F> {
515     base: C,
516     init: &'f INIT,
517     map_op: &'f F,
518 }
519 
520 impl<'f, C, INIT, F> MapInitConsumer<'f, C, INIT, F> {
new(base: C, init: &'f INIT, map_op: &'f F) -> Self521     fn new(base: C, init: &'f INIT, map_op: &'f F) -> Self {
522         MapInitConsumer { base, init, map_op }
523     }
524 }
525 
526 impl<'f, T, INIT, U, R, C, F> Consumer<T> for MapInitConsumer<'f, C, INIT, F>
527 where
528     C: Consumer<R>,
529     INIT: Fn() -> U + Sync,
530     F: Fn(&mut U, T) -> R + Sync,
531     R: Send,
532 {
533     type Folder = MapWithFolder<'f, C::Folder, U, F>;
534     type Reducer = C::Reducer;
535     type Result = C::Result;
536 
split_at(self, index: usize) -> (Self, Self, Self::Reducer)537     fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
538         let (left, right, reducer) = self.base.split_at(index);
539         (
540             MapInitConsumer::new(left, self.init, self.map_op),
541             MapInitConsumer::new(right, self.init, self.map_op),
542             reducer,
543         )
544     }
545 
into_folder(self) -> Self::Folder546     fn into_folder(self) -> Self::Folder {
547         MapWithFolder {
548             base: self.base.into_folder(),
549             item: (self.init)(),
550             map_op: self.map_op,
551         }
552     }
553 
full(&self) -> bool554     fn full(&self) -> bool {
555         self.base.full()
556     }
557 }
558 
559 impl<'f, T, INIT, U, R, C, F> UnindexedConsumer<T> for MapInitConsumer<'f, C, INIT, F>
560 where
561     C: UnindexedConsumer<R>,
562     INIT: Fn() -> U + Sync,
563     F: Fn(&mut U, T) -> R + Sync,
564     R: Send,
565 {
split_off_left(&self) -> Self566     fn split_off_left(&self) -> Self {
567         MapInitConsumer::new(self.base.split_off_left(), self.init, self.map_op)
568     }
569 
to_reducer(&self) -> Self::Reducer570     fn to_reducer(&self) -> Self::Reducer {
571         self.base.to_reducer()
572     }
573 }
574