]> git.proxmox.com Git - rustc.git/blob - vendor/rayon/src/iter/map_with.rs
New upstream version 1.38.0+dfsg1
[rustc.git] / vendor / rayon / src / iter / map_with.rs
1 use super::plumbing::*;
2 use super::*;
3
4 use 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)]
14 pub struct MapWith<I: ParallelIterator, T, F> {
15 base: I,
16 item: T,
17 map_op: F,
18 }
19
20 impl<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
29 impl<I, T, F> MapWith<I, T, F>
30 where
31 I: ParallelIterator,
32 {
33 /// Create 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
39 impl<I, T, F, R> ParallelIterator for MapWith<I, T, F>
40 where
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
61 impl<I, T, F, R> IndexedParallelIterator for MapWith<I, T, F>
62 where
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
122 struct MapWithProducer<'f, P, U, F: 'f> {
123 base: P,
124 item: U,
125 map_op: &'f F,
126 }
127
128 impl<'f, P, U, F, R> Producer for MapWithProducer<'f, P, U, F>
129 where
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
182 struct MapWithIter<'f, I, U, F: 'f> {
183 base: I,
184 item: U,
185 map_op: &'f F,
186 }
187
188 impl<'f, I, U, F, R> Iterator for MapWithIter<'f, I, U, F>
189 where
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
206 impl<'f, I, U, F, R> DoubleEndedIterator for MapWithIter<'f, I, U, F>
207 where
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
218 impl<'f, I, U, F, R> ExactSizeIterator for MapWithIter<'f, I, U, F>
219 where
220 I: ExactSizeIterator,
221 F: Fn(&mut U, I::Item) -> R + Sync,
222 R: Send,
223 {
224 }
225
226 /// ////////////////////////////////////////////////////////////////////////
227 /// Consumer implementation
228
229 struct MapWithConsumer<'f, C, U, F: 'f> {
230 base: C,
231 item: U,
232 map_op: &'f F,
233 }
234
235 impl<'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
241 impl<'f, T, U, R, C, F> Consumer<T> for MapWithConsumer<'f, C, U, F>
242 where
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
274 impl<'f, T, U, R, C, F> UnindexedConsumer<T> for MapWithConsumer<'f, C, U, F>
275 where
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
290 struct MapWithFolder<'f, C, U, F: 'f> {
291 base: C,
292 item: U,
293 map_op: &'f F,
294 }
295
296 impl<'f, T, U, R, C, F> Folder<T> for MapWithFolder<'f, C, U, F>
297 where
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 {
314 let map_op = self.map_op;
315 let item = &mut self.item;
316 let mapped_iter = iter.into_iter().map(|x| map_op(item, x));
317 self.base = self.base.consume_iter(mapped_iter);
318 }
319 self
320 }
321
322 fn complete(self) -> C::Result {
323 self.base.complete()
324 }
325
326 fn full(&self) -> bool {
327 self.base.full()
328 }
329 }
330
331 // ------------------------------------------------------------------------------------------------
332
333 /// `MapInit` is an iterator that transforms the elements of an underlying iterator.
334 ///
335 /// This struct is created by the [`map_init()`] method on [`ParallelIterator`]
336 ///
337 /// [`map_init()`]: trait.ParallelIterator.html#method.map_init
338 /// [`ParallelIterator`]: trait.ParallelIterator.html
339 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
340 #[derive(Clone)]
341 pub struct MapInit<I: ParallelIterator, INIT, F> {
342 base: I,
343 init: INIT,
344 map_op: F,
345 }
346
347 impl<I: ParallelIterator + Debug, INIT, F> Debug for MapInit<I, INIT, F> {
348 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349 f.debug_struct("MapInit").field("base", &self.base).finish()
350 }
351 }
352
353 impl<I, INIT, F> MapInit<I, INIT, F>
354 where
355 I: ParallelIterator,
356 {
357 /// Create a new `MapInit` iterator.
358 pub(super) fn new(base: I, init: INIT, map_op: F) -> Self {
359 MapInit { base, init, map_op }
360 }
361 }
362
363 impl<I, INIT, T, F, R> ParallelIterator for MapInit<I, INIT, F>
364 where
365 I: ParallelIterator,
366 INIT: Fn() -> T + Sync + Send,
367 F: Fn(&mut T, I::Item) -> R + Sync + Send,
368 R: Send,
369 {
370 type Item = R;
371
372 fn drive_unindexed<C>(self, consumer: C) -> C::Result
373 where
374 C: UnindexedConsumer<Self::Item>,
375 {
376 let consumer1 = MapInitConsumer::new(consumer, &self.init, &self.map_op);
377 self.base.drive_unindexed(consumer1)
378 }
379
380 fn opt_len(&self) -> Option<usize> {
381 self.base.opt_len()
382 }
383 }
384
385 impl<I, INIT, T, F, R> IndexedParallelIterator for MapInit<I, INIT, F>
386 where
387 I: IndexedParallelIterator,
388 INIT: Fn() -> T + Sync + Send,
389 F: Fn(&mut T, I::Item) -> R + Sync + Send,
390 R: Send,
391 {
392 fn drive<C>(self, consumer: C) -> C::Result
393 where
394 C: Consumer<Self::Item>,
395 {
396 let consumer1 = MapInitConsumer::new(consumer, &self.init, &self.map_op);
397 self.base.drive(consumer1)
398 }
399
400 fn len(&self) -> usize {
401 self.base.len()
402 }
403
404 fn with_producer<CB>(self, callback: CB) -> CB::Output
405 where
406 CB: ProducerCallback<Self::Item>,
407 {
408 return self.base.with_producer(Callback {
409 callback,
410 init: self.init,
411 map_op: self.map_op,
412 });
413
414 struct Callback<CB, INIT, F> {
415 callback: CB,
416 init: INIT,
417 map_op: F,
418 }
419
420 impl<T, INIT, U, F, R, CB> ProducerCallback<T> for Callback<CB, INIT, F>
421 where
422 CB: ProducerCallback<R>,
423 INIT: Fn() -> U + Sync,
424 F: Fn(&mut U, T) -> R + Sync,
425 R: Send,
426 {
427 type Output = CB::Output;
428
429 fn callback<P>(self, base: P) -> CB::Output
430 where
431 P: Producer<Item = T>,
432 {
433 let producer = MapInitProducer {
434 base,
435 init: &self.init,
436 map_op: &self.map_op,
437 };
438 self.callback.callback(producer)
439 }
440 }
441 }
442 }
443
444 /// ////////////////////////////////////////////////////////////////////////
445
446 struct MapInitProducer<'f, P, INIT: 'f, F: 'f> {
447 base: P,
448 init: &'f INIT,
449 map_op: &'f F,
450 }
451
452 impl<'f, P, INIT, U, F, R> Producer for MapInitProducer<'f, P, INIT, F>
453 where
454 P: Producer,
455 INIT: Fn() -> U + Sync,
456 F: Fn(&mut U, P::Item) -> R + Sync,
457 R: Send,
458 {
459 type Item = R;
460 type IntoIter = MapWithIter<'f, P::IntoIter, U, F>;
461
462 fn into_iter(self) -> Self::IntoIter {
463 MapWithIter {
464 base: self.base.into_iter(),
465 item: (self.init)(),
466 map_op: self.map_op,
467 }
468 }
469
470 fn min_len(&self) -> usize {
471 self.base.min_len()
472 }
473 fn max_len(&self) -> usize {
474 self.base.max_len()
475 }
476
477 fn split_at(self, index: usize) -> (Self, Self) {
478 let (left, right) = self.base.split_at(index);
479 (
480 MapInitProducer {
481 base: left,
482 init: self.init,
483 map_op: self.map_op,
484 },
485 MapInitProducer {
486 base: right,
487 init: self.init,
488 map_op: self.map_op,
489 },
490 )
491 }
492
493 fn fold_with<G>(self, folder: G) -> G
494 where
495 G: Folder<Self::Item>,
496 {
497 let folder1 = MapWithFolder {
498 base: folder,
499 item: (self.init)(),
500 map_op: self.map_op,
501 };
502 self.base.fold_with(folder1).base
503 }
504 }
505
506 /// ////////////////////////////////////////////////////////////////////////
507 /// Consumer implementation
508
509 struct MapInitConsumer<'f, C, INIT: 'f, F: 'f> {
510 base: C,
511 init: &'f INIT,
512 map_op: &'f F,
513 }
514
515 impl<'f, C, INIT, F> MapInitConsumer<'f, C, INIT, F> {
516 fn new(base: C, init: &'f INIT, map_op: &'f F) -> Self {
517 MapInitConsumer { base, init, map_op }
518 }
519 }
520
521 impl<'f, T, INIT, U, R, C, F> Consumer<T> for MapInitConsumer<'f, C, INIT, F>
522 where
523 C: Consumer<R>,
524 INIT: Fn() -> U + Sync,
525 F: Fn(&mut U, T) -> R + Sync,
526 R: Send,
527 {
528 type Folder = MapWithFolder<'f, C::Folder, U, F>;
529 type Reducer = C::Reducer;
530 type Result = C::Result;
531
532 fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
533 let (left, right, reducer) = self.base.split_at(index);
534 (
535 MapInitConsumer::new(left, self.init, self.map_op),
536 MapInitConsumer::new(right, self.init, self.map_op),
537 reducer,
538 )
539 }
540
541 fn into_folder(self) -> Self::Folder {
542 MapWithFolder {
543 base: self.base.into_folder(),
544 item: (self.init)(),
545 map_op: self.map_op,
546 }
547 }
548
549 fn full(&self) -> bool {
550 self.base.full()
551 }
552 }
553
554 impl<'f, T, INIT, U, R, C, F> UnindexedConsumer<T> for MapInitConsumer<'f, C, INIT, F>
555 where
556 C: UnindexedConsumer<R>,
557 INIT: Fn() -> U + Sync,
558 F: Fn(&mut U, T) -> R + Sync,
559 R: Send,
560 {
561 fn split_off_left(&self) -> Self {
562 MapInitConsumer::new(self.base.split_off_left(), self.init, self.map_op)
563 }
564
565 fn to_reducer(&self) -> Self::Reducer {
566 self.base.to_reducer()
567 }
568 }