par_iter/iter/
map_with.rs

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