rayon/iter/
map.rs

1use super::plumbing::*;
2use super::*;
3
4use std::fmt::{self, Debug};
5use std::iter;
6
7/// `Map` is an iterator that transforms the elements of an underlying iterator.
8///
9/// This struct is created by the [`map()`] method on [`ParallelIterator`]
10///
11/// [`map()`]: ParallelIterator::map()
12#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13#[derive(Clone)]
14pub struct Map<I, F> {
15    base: I,
16    map_op: F,
17}
18
19impl<I: Debug, F> Debug for Map<I, F> {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        f.debug_struct("Map").field("base", &self.base).finish()
22    }
23}
24
25impl<I, F> Map<I, F> {
26    /// Creates a new `Map` iterator.
27    pub(super) fn new(base: I, map_op: F) -> Self {
28        Map { base, map_op }
29    }
30}
31
32impl<I, F, R> ParallelIterator for Map<I, F>
33where
34    I: ParallelIterator,
35    F: Fn(I::Item) -> R + Sync + Send,
36    R: Send,
37{
38    type Item = F::Output;
39
40    fn drive_unindexed<C>(self, consumer: C) -> C::Result
41    where
42        C: UnindexedConsumer<Self::Item>,
43    {
44        let consumer1 = MapConsumer::new(consumer, &self.map_op);
45        self.base.drive_unindexed(consumer1)
46    }
47
48    fn opt_len(&self) -> Option<usize> {
49        self.base.opt_len()
50    }
51}
52
53impl<I, F, R> IndexedParallelIterator for Map<I, F>
54where
55    I: IndexedParallelIterator,
56    F: Fn(I::Item) -> R + Sync + Send,
57    R: Send,
58{
59    fn drive<C>(self, consumer: C) -> C::Result
60    where
61        C: Consumer<Self::Item>,
62    {
63        let consumer1 = MapConsumer::new(consumer, &self.map_op);
64        self.base.drive(consumer1)
65    }
66
67    fn len(&self) -> usize {
68        self.base.len()
69    }
70
71    fn with_producer<CB>(self, callback: CB) -> CB::Output
72    where
73        CB: ProducerCallback<Self::Item>,
74    {
75        return self.base.with_producer(Callback {
76            callback,
77            map_op: self.map_op,
78        });
79
80        struct Callback<CB, F> {
81            callback: CB,
82            map_op: F,
83        }
84
85        impl<T, F, R, CB> ProducerCallback<T> for Callback<CB, F>
86        where
87            CB: ProducerCallback<R>,
88            F: Fn(T) -> R + Sync,
89            R: Send,
90        {
91            type Output = CB::Output;
92
93            fn callback<P>(self, base: P) -> CB::Output
94            where
95                P: Producer<Item = T>,
96            {
97                let producer = MapProducer {
98                    base,
99                    map_op: &self.map_op,
100                };
101                self.callback.callback(producer)
102            }
103        }
104    }
105}
106
107// ////////////////////////////////////////////////////////////////////////
108
109struct MapProducer<'f, P, F> {
110    base: P,
111    map_op: &'f F,
112}
113
114impl<'f, P, F, R> Producer for MapProducer<'f, P, F>
115where
116    P: Producer,
117    F: Fn(P::Item) -> R + Sync,
118    R: Send,
119{
120    type Item = F::Output;
121    type IntoIter = iter::Map<P::IntoIter, &'f F>;
122
123    fn into_iter(self) -> Self::IntoIter {
124        self.base.into_iter().map(self.map_op)
125    }
126
127    fn min_len(&self) -> usize {
128        self.base.min_len()
129    }
130    fn max_len(&self) -> usize {
131        self.base.max_len()
132    }
133
134    fn split_at(self, index: usize) -> (Self, Self) {
135        let (left, right) = self.base.split_at(index);
136        (
137            MapProducer {
138                base: left,
139                map_op: self.map_op,
140            },
141            MapProducer {
142                base: right,
143                map_op: self.map_op,
144            },
145        )
146    }
147
148    fn fold_with<G>(self, folder: G) -> G
149    where
150        G: Folder<Self::Item>,
151    {
152        let folder1 = MapFolder {
153            base: folder,
154            map_op: self.map_op,
155        };
156        self.base.fold_with(folder1).base
157    }
158}
159
160// ////////////////////////////////////////////////////////////////////////
161// Consumer implementation
162
163struct MapConsumer<'f, C, F> {
164    base: C,
165    map_op: &'f F,
166}
167
168impl<'f, C, F> MapConsumer<'f, C, F> {
169    fn new(base: C, map_op: &'f F) -> Self {
170        MapConsumer { base, map_op }
171    }
172}
173
174impl<'f, T, R, C, F> Consumer<T> for MapConsumer<'f, C, F>
175where
176    C: Consumer<F::Output>,
177    F: Fn(T) -> R + Sync,
178    R: Send,
179{
180    type Folder = MapFolder<'f, C::Folder, F>;
181    type Reducer = C::Reducer;
182    type Result = C::Result;
183
184    fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
185        let (left, right, reducer) = self.base.split_at(index);
186        (
187            MapConsumer::new(left, self.map_op),
188            MapConsumer::new(right, self.map_op),
189            reducer,
190        )
191    }
192
193    fn into_folder(self) -> Self::Folder {
194        MapFolder {
195            base: self.base.into_folder(),
196            map_op: self.map_op,
197        }
198    }
199
200    fn full(&self) -> bool {
201        self.base.full()
202    }
203}
204
205impl<'f, T, R, C, F> UnindexedConsumer<T> for MapConsumer<'f, C, F>
206where
207    C: UnindexedConsumer<F::Output>,
208    F: Fn(T) -> R + Sync,
209    R: Send,
210{
211    fn split_off_left(&self) -> Self {
212        MapConsumer::new(self.base.split_off_left(), self.map_op)
213    }
214
215    fn to_reducer(&self) -> Self::Reducer {
216        self.base.to_reducer()
217    }
218}
219
220struct MapFolder<'f, C, F> {
221    base: C,
222    map_op: &'f F,
223}
224
225impl<'f, T, R, C, F> Folder<T> for MapFolder<'f, C, F>
226where
227    C: Folder<F::Output>,
228    F: Fn(T) -> R,
229{
230    type Result = C::Result;
231
232    fn consume(self, item: T) -> Self {
233        let mapped_item = (self.map_op)(item);
234        MapFolder {
235            base: self.base.consume(mapped_item),
236            map_op: self.map_op,
237        }
238    }
239
240    fn consume_iter<I>(mut self, iter: I) -> Self
241    where
242        I: IntoIterator<Item = T>,
243    {
244        self.base = self.base.consume_iter(iter.into_iter().map(self.map_op));
245        self
246    }
247
248    fn complete(self) -> C::Result {
249        self.base.complete()
250    }
251
252    fn full(&self) -> bool {
253        self.base.full()
254    }
255}