1use std::fmt::{self, Debug};
2
3use super::{plumbing::*, *};
4
5#[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.debug_struct("MapWith")
23 .field("base", &self.base)
24 .field("item", &self.item)
25 .finish()
26 }
27}
28
29impl<I, T, F> MapWith<I, T, F>
30where
31 I: ParallelIterator,
32{
33 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::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
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
120struct 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 IntoIter = MapWithIter<'f, P::IntoIter, U, F>;
136 type Item = R;
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
150 fn max_len(&self) -> usize {
151 self.base.max_len()
152 }
153
154 fn split_at(self, index: usize) -> (Self, Self) {
155 let (left, right) = self.base.split_at(index);
156 (
157 MapWithProducer {
158 base: left,
159 item: self.item.clone(),
160 map_op: self.map_op,
161 },
162 MapWithProducer {
163 base: right,
164 item: self.item,
165 map_op: self.map_op,
166 },
167 )
168 }
169
170 fn fold_with<G>(self, folder: G) -> G
171 where
172 G: Folder<Self::Item>,
173 {
174 let folder1 = MapWithFolder {
175 base: folder,
176 item: self.item,
177 map_op: self.map_op,
178 };
179 self.base.fold_with(folder1).base
180 }
181}
182
183struct MapWithIter<'f, I, U, F> {
184 base: I,
185 item: U,
186 map_op: &'f F,
187}
188
189impl<'f, I, U, F, R> Iterator for MapWithIter<'f, I, U, F>
190where
191 I: Iterator,
192 F: Fn(&mut U, I::Item) -> R + Sync,
193 R: Send,
194{
195 type Item = R;
196
197 fn next(&mut self) -> Option<R> {
198 let item = self.base.next()?;
199 Some((self.map_op)(&mut self.item, item))
200 }
201
202 fn size_hint(&self) -> (usize, Option<usize>) {
203 self.base.size_hint()
204 }
205}
206
207impl<'f, I, U, F, R> DoubleEndedIterator for MapWithIter<'f, I, U, F>
208where
209 I: DoubleEndedIterator,
210 F: Fn(&mut U, I::Item) -> R + Sync,
211 R: Send,
212{
213 fn next_back(&mut self) -> Option<R> {
214 let item = self.base.next_back()?;
215 Some((self.map_op)(&mut self.item, item))
216 }
217}
218
219impl<'f, I, U, F, R> ExactSizeIterator for MapWithIter<'f, I, U, F>
220where
221 I: ExactSizeIterator,
222 F: Fn(&mut U, I::Item) -> R + Sync,
223 R: Send,
224{
225}
226
227struct MapWithConsumer<'f, C, U, F> {
231 base: C,
232 item: U,
233 map_op: &'f F,
234}
235
236impl<'f, C, U, F> MapWithConsumer<'f, C, U, F> {
237 fn new(base: C, item: U, map_op: &'f F) -> Self {
238 MapWithConsumer { base, item, map_op }
239 }
240}
241
242impl<'f, T, U, R, C, F> Consumer<T> for MapWithConsumer<'f, C, U, F>
243where
244 C: Consumer<R>,
245 U: Send + Clone,
246 F: Fn(&mut U, T) -> R + Sync,
247 R: Send,
248{
249 type Folder = MapWithFolder<'f, C::Folder, U, F>;
250 type Reducer = C::Reducer;
251 type Result = C::Result;
252
253 fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
254 let (left, right, reducer) = self.base.split_at(index);
255 (
256 MapWithConsumer::new(left, self.item.clone(), self.map_op),
257 MapWithConsumer::new(right, self.item, self.map_op),
258 reducer,
259 )
260 }
261
262 fn into_folder(self) -> Self::Folder {
263 MapWithFolder {
264 base: self.base.into_folder(),
265 item: self.item,
266 map_op: self.map_op,
267 }
268 }
269
270 fn full(&self) -> bool {
271 self.base.full()
272 }
273}
274
275impl<'f, T, U, R, C, F> UnindexedConsumer<T> for MapWithConsumer<'f, C, U, F>
276where
277 C: UnindexedConsumer<R>,
278 U: Send + Clone,
279 F: Fn(&mut U, T) -> R + Sync,
280 R: Send,
281{
282 fn split_off_left(&self) -> Self {
283 MapWithConsumer::new(self.base.split_off_left(), self.item.clone(), self.map_op)
284 }
285
286 fn to_reducer(&self) -> Self::Reducer {
287 self.base.to_reducer()
288 }
289}
290
291struct MapWithFolder<'f, C, U, F> {
292 base: C,
293 item: U,
294 map_op: &'f F,
295}
296
297impl<'f, T, U, R, C, F> Folder<T> for MapWithFolder<'f, C, U, F>
298where
299 C: Folder<R>,
300 F: Fn(&mut U, T) -> R,
301{
302 type Result = C::Result;
303
304 fn consume(mut self, item: T) -> Self {
305 let mapped_item = (self.map_op)(&mut self.item, item);
306 self.base = self.base.consume(mapped_item);
307 self
308 }
309
310 fn consume_iter<I>(mut self, iter: I) -> Self
311 where
312 I: IntoIterator<Item = T>,
313 {
314 fn with<'f, T, U, R>(
315 item: &'f mut U,
316 map_op: impl Fn(&mut U, T) -> R + 'f,
317 ) -> impl FnMut(T) -> R + 'f {
318 move |x| map_op(item, x)
319 }
320
321 {
322 let mapped_iter = iter.into_iter().map(with(&mut self.item, self.map_op));
323 self.base = self.base.consume_iter(mapped_iter);
324 }
325 self
326 }
327
328 fn complete(self) -> C::Result {
329 self.base.complete()
330 }
331
332 fn full(&self) -> bool {
333 self.base.full()
334 }
335}
336
337#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
347#[derive(Clone)]
348pub struct MapInit<I: ParallelIterator, INIT, F> {
349 base: I,
350 init: INIT,
351 map_op: F,
352}
353
354impl<I: ParallelIterator + Debug, INIT, F> Debug for MapInit<I, INIT, F> {
355 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356 f.debug_struct("MapInit").field("base", &self.base).finish()
357 }
358}
359
360impl<I, INIT, F> MapInit<I, INIT, F>
361where
362 I: ParallelIterator,
363{
364 pub(super) fn new(base: I, init: INIT, map_op: F) -> Self {
366 MapInit { base, init, map_op }
367 }
368}
369
370impl<I, INIT, T, F, R> ParallelIterator for MapInit<I, INIT, F>
371where
372 I: ParallelIterator,
373 INIT: Fn() -> T + Sync + Send,
374 F: Fn(&mut T, I::Item) -> R + Sync + Send,
375 R: Send,
376{
377 type Item = R;
378
379 fn drive_unindexed<C>(self, consumer: C) -> C::Result
380 where
381 C: UnindexedConsumer<Self::Item>,
382 {
383 let consumer1 = MapInitConsumer::new(consumer, &self.init, &self.map_op);
384 self.base.drive_unindexed(consumer1)
385 }
386
387 fn opt_len(&self) -> Option<usize> {
388 self.base.opt_len()
389 }
390}
391
392impl<I, INIT, T, F, R> IndexedParallelIterator for MapInit<I, INIT, F>
393where
394 I: IndexedParallelIterator,
395 INIT: Fn() -> T + Sync + Send,
396 F: Fn(&mut T, I::Item) -> R + Sync + Send,
397 R: Send,
398{
399 fn drive<C>(self, consumer: C) -> C::Result
400 where
401 C: Consumer<Self::Item>,
402 {
403 let consumer1 = MapInitConsumer::new(consumer, &self.init, &self.map_op);
404 self.base.drive(consumer1)
405 }
406
407 fn len(&self) -> usize {
408 self.base.len()
409 }
410
411 fn with_producer<CB>(self, callback: CB) -> CB::Output
412 where
413 CB: ProducerCallback<Self::Item>,
414 {
415 return self.base.with_producer(Callback {
416 callback,
417 init: self.init,
418 map_op: self.map_op,
419 });
420
421 struct Callback<CB, INIT, F> {
422 callback: CB,
423 init: INIT,
424 map_op: F,
425 }
426
427 impl<T, INIT, U, F, R, CB> ProducerCallback<T> for Callback<CB, INIT, F>
428 where
429 CB: ProducerCallback<R>,
430 INIT: Fn() -> U + Sync,
431 F: Fn(&mut U, T) -> R + Sync,
432 R: Send,
433 {
434 type Output = CB::Output;
435
436 fn callback<P>(self, base: P) -> CB::Output
437 where
438 P: Producer<Item = T>,
439 {
440 let producer = MapInitProducer {
441 base,
442 init: &self.init,
443 map_op: &self.map_op,
444 };
445 self.callback.callback(producer)
446 }
447 }
448 }
449}
450
451struct MapInitProducer<'f, P, INIT, F> {
454 base: P,
455 init: &'f INIT,
456 map_op: &'f F,
457}
458
459impl<'f, P, INIT, U, F, R> Producer for MapInitProducer<'f, P, INIT, F>
460where
461 P: Producer,
462 INIT: Fn() -> U + Sync,
463 F: Fn(&mut U, P::Item) -> R + Sync,
464 R: Send,
465{
466 type IntoIter = MapWithIter<'f, P::IntoIter, U, F>;
467 type Item = R;
468
469 fn into_iter(self) -> Self::IntoIter {
470 MapWithIter {
471 base: self.base.into_iter(),
472 item: (self.init)(),
473 map_op: self.map_op,
474 }
475 }
476
477 fn min_len(&self) -> usize {
478 self.base.min_len()
479 }
480
481 fn max_len(&self) -> usize {
482 self.base.max_len()
483 }
484
485 fn split_at(self, index: usize) -> (Self, Self) {
486 let (left, right) = self.base.split_at(index);
487 (
488 MapInitProducer {
489 base: left,
490 init: self.init,
491 map_op: self.map_op,
492 },
493 MapInitProducer {
494 base: right,
495 init: self.init,
496 map_op: self.map_op,
497 },
498 )
499 }
500
501 fn fold_with<G>(self, folder: G) -> G
502 where
503 G: Folder<Self::Item>,
504 {
505 let folder1 = MapWithFolder {
506 base: folder,
507 item: (self.init)(),
508 map_op: self.map_op,
509 };
510 self.base.fold_with(folder1).base
511 }
512}
513
514struct MapInitConsumer<'f, C, INIT, F> {
518 base: C,
519 init: &'f INIT,
520 map_op: &'f F,
521}
522
523impl<'f, C, INIT, F> MapInitConsumer<'f, C, INIT, F> {
524 fn new(base: C, init: &'f INIT, map_op: &'f F) -> Self {
525 MapInitConsumer { base, init, map_op }
526 }
527}
528
529impl<'f, T, INIT, U, R, C, F> Consumer<T> for MapInitConsumer<'f, C, INIT, F>
530where
531 C: Consumer<R>,
532 INIT: Fn() -> U + Sync,
533 F: Fn(&mut U, T) -> R + Sync,
534 R: Send,
535{
536 type Folder = MapWithFolder<'f, C::Folder, U, F>;
537 type Reducer = C::Reducer;
538 type Result = C::Result;
539
540 fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) {
541 let (left, right, reducer) = self.base.split_at(index);
542 (
543 MapInitConsumer::new(left, self.init, self.map_op),
544 MapInitConsumer::new(right, self.init, self.map_op),
545 reducer,
546 )
547 }
548
549 fn into_folder(self) -> Self::Folder {
550 MapWithFolder {
551 base: self.base.into_folder(),
552 item: (self.init)(),
553 map_op: self.map_op,
554 }
555 }
556
557 fn full(&self) -> bool {
558 self.base.full()
559 }
560}
561
562impl<'f, T, INIT, U, R, C, F> UnindexedConsumer<T> for MapInitConsumer<'f, C, INIT, F>
563where
564 C: UnindexedConsumer<R>,
565 INIT: Fn() -> U + Sync,
566 F: Fn(&mut U, T) -> R + Sync,
567 R: Send,
568{
569 fn split_off_left(&self) -> Self {
570 MapInitConsumer::new(self.base.split_off_left(), self.init, self.map_op)
571 }
572
573 fn to_reducer(&self) -> Self::Reducer {
574 self.base.to_reducer()
575 }
576}