rayon/iter/
map_with.rs

1use super::plumbing::*;
2use super::*;
3
4use 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)]
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 Item = R;
136    type IntoIter = MapWithIter<'f, P::IntoIter, U, F>;
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    fn max_len(&self) -> usize {
150        self.base.max_len()
151    }
152
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
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
182struct MapWithIter<'f, I, U, F> {
183    base: I,
184    item: U,
185    map_op: &'f F,
186}
187
188impl<'f, I, U, F, R> Iterator for MapWithIter<'f, I, U, F>
189where
190    I: Iterator,
191    F: Fn(&mut U, I::Item) -> R + Sync,
192    R: Send,
193{
194    type Item = R;
195
196    fn next(&mut self) -> Option<R> {
197        let item = self.base.next()?;
198        Some((self.map_op)(&mut self.item, item))
199    }
200
201    fn size_hint(&self) -> (usize, Option<usize>) {
202        self.base.size_hint()
203    }
204}
205
206impl<'f, I, U, F, R> DoubleEndedIterator for MapWithIter<'f, I, U, F>
207where
208    I: DoubleEndedIterator,
209    F: Fn(&mut U, I::Item) -> R + Sync,
210    R: Send,
211{
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
218impl<'f, I, U, F, R> ExactSizeIterator for MapWithIter<'f, I, U, F>
219where
220    I: ExactSizeIterator,
221    F: Fn(&mut U, I::Item) -> R + Sync,
222    R: Send,
223{
224}
225
226/// ////////////////////////////////////////////////////////////////////////
227/// Consumer implementation
228
229struct MapWithConsumer<'f, C, U, F> {
230    base: C,
231    item: U,
232    map_op: &'f F,
233}
234
235impl<'f, C, U, F> MapWithConsumer<'f, C, U, F> {
236    fn new(base: C, item: U, map_op: &'f F) -> Self {
237        MapWithConsumer { base, item, map_op }
238    }
239}
240
241impl<'f, T, U, R, C, F> Consumer<T> for MapWithConsumer<'f, C, U, F>
242where
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
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
261    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
269    fn full(&self) -> bool {
270        self.base.full()
271    }
272}
273
274impl<'f, T, U, R, C, F> UnindexedConsumer<T> for MapWithConsumer<'f, C, U, F>
275where
276    C: UnindexedConsumer<R>,
277    U: Send + Clone,
278    F: Fn(&mut U, T) -> R + Sync,
279    R: Send,
280{
281    fn split_off_left(&self) -> Self {
282        MapWithConsumer::new(self.base.split_off_left(), self.item.clone(), self.map_op)
283    }
284
285    fn to_reducer(&self) -> Self::Reducer {
286        self.base.to_reducer()
287    }
288}
289
290struct MapWithFolder<'f, C, U, F> {
291    base: C,
292    item: U,
293    map_op: &'f F,
294}
295
296impl<'f, T, U, R, C, F> Folder<T> for MapWithFolder<'f, C, U, F>
297where
298    C: Folder<R>,
299    F: Fn(&mut U, T) -> R,
300{
301    type Result = C::Result;
302
303    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
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
327    fn complete(self) -> C::Result {
328        self.base.complete()
329    }
330
331    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)]
346pub struct MapInit<I: ParallelIterator, INIT, F> {
347    base: I,
348    init: INIT,
349    map_op: F,
350}
351
352impl<I: ParallelIterator + Debug, INIT, F> Debug for MapInit<I, INIT, F> {
353    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354        f.debug_struct("MapInit").field("base", &self.base).finish()
355    }
356}
357
358impl<I, INIT, F> MapInit<I, INIT, F>
359where
360    I: ParallelIterator,
361{
362    /// Creates a new `MapInit` iterator.
363    pub(super) fn new(base: I, init: INIT, map_op: F) -> Self {
364        MapInit { base, init, map_op }
365    }
366}
367
368impl<I, INIT, T, F, R> ParallelIterator for MapInit<I, INIT, F>
369where
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
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
385    fn opt_len(&self) -> Option<usize> {
386        self.base.opt_len()
387    }
388}
389
390impl<I, INIT, T, F, R> IndexedParallelIterator for MapInit<I, INIT, F>
391where
392    I: IndexedParallelIterator,
393    INIT: Fn() -> T + Sync + Send,
394    F: Fn(&mut T, I::Item) -> R + Sync + Send,
395    R: Send,
396{
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
405    fn len(&self) -> usize {
406        self.base.len()
407    }
408
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
451struct MapInitProducer<'f, P, INIT, F> {
452    base: P,
453    init: &'f INIT,
454    map_op: &'f F,
455}
456
457impl<'f, P, INIT, U, F, R> Producer for MapInitProducer<'f, P, INIT, F>
458where
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
467    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
475    fn min_len(&self) -> usize {
476        self.base.min_len()
477    }
478    fn max_len(&self) -> usize {
479        self.base.max_len()
480    }
481
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
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
514struct MapInitConsumer<'f, C, INIT, F> {
515    base: C,
516    init: &'f INIT,
517    map_op: &'f F,
518}
519
520impl<'f, C, INIT, F> MapInitConsumer<'f, C, INIT, F> {
521    fn new(base: C, init: &'f INIT, map_op: &'f F) -> Self {
522        MapInitConsumer { base, init, map_op }
523    }
524}
525
526impl<'f, T, INIT, U, R, C, F> Consumer<T> for MapInitConsumer<'f, C, INIT, F>
527where
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
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
546    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
554    fn full(&self) -> bool {
555        self.base.full()
556    }
557}
558
559impl<'f, T, INIT, U, R, C, F> UnindexedConsumer<T> for MapInitConsumer<'f, C, INIT, F>
560where
561    C: UnindexedConsumer<R>,
562    INIT: Fn() -> U + Sync,
563    F: Fn(&mut U, T) -> R + Sync,
564    R: Send,
565{
566    fn split_off_left(&self) -> Self {
567        MapInitConsumer::new(self.base.split_off_left(), self.init, self.map_op)
568    }
569
570    fn to_reducer(&self) -> Self::Reducer {
571        self.base.to_reducer()
572    }
573}