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&mut DebugStruct<'_, '_>.debug_struct("MapWith")
23 .field("base", &self.base)
24 .field(name:"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<'_, C, T, …> = MapWithConsumer::new(base:consumer, self.item, &self.map_op);
53 self.base.drive_unindexed(consumer: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: ::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: ::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(name:"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<'_, C, INIT, …> = MapInitConsumer::new(base:consumer, &self.init, &self.map_op);
382 self.base.drive_unindexed(consumer: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}
574