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