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