1 use super::plumbing
::*;
4 use std
::fmt
::{self, Debug}
;
6 /// `MapWith` is an iterator that transforms the elements of an underlying iterator.
8 /// This struct is created by the [`map_with()`] method on [`ParallelIterator`]
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"]
14 pub struct MapWith
<I
: ParallelIterator
, T
, F
> {
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
)
29 impl<I
, T
, F
> MapWith
<I
, T
, F
>
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 }
39 impl<I
, T
, F
, R
> ParallelIterator
for MapWith
<I
, T
, F
>
43 F
: Fn(&mut T
, I
::Item
) -> R
+ Sync
+ Send
,
48 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
50 C
: UnindexedConsumer
<Self::Item
>,
52 let consumer1
= MapWithConsumer
::new(consumer
, self.item
, &self.map_op
);
53 self.base
.drive_unindexed(consumer1
)
56 fn opt_len(&self) -> Option
<usize> {
61 impl<I
, T
, F
, R
> IndexedParallelIterator
for MapWith
<I
, T
, F
>
63 I
: IndexedParallelIterator
,
65 F
: Fn(&mut T
, I
::Item
) -> R
+ Sync
+ Send
,
68 fn drive
<C
>(self, consumer
: C
) -> C
::Result
70 C
: Consumer
<Self::Item
>,
72 let consumer1
= MapWithConsumer
::new(consumer
, self.item
, &self.map_op
);
73 self.base
.drive(consumer1
)
76 fn len(&self) -> usize {
80 fn with_producer
<CB
>(self, callback
: CB
) -> CB
::Output
82 CB
: ProducerCallback
<Self::Item
>,
84 return self.base
.with_producer(Callback
{
90 struct Callback
<CB
, U
, F
> {
96 impl<T
, U
, F
, R
, CB
> ProducerCallback
<T
> for Callback
<CB
, U
, F
>
98 CB
: ProducerCallback
<R
>,
100 F
: Fn(&mut U
, T
) -> R
+ Sync
,
103 type Output
= CB
::Output
;
105 fn callback
<P
>(self, base
: P
) -> CB
::Output
107 P
: Producer
<Item
= T
>,
109 let producer
= MapWithProducer
{
112 map_op
: &self.map_op
,
114 self.callback
.callback(producer
)
120 /// ////////////////////////////////////////////////////////////////////////
122 struct MapWithProducer
<'f
, P
, U
, F
: 'f
> {
128 impl<'f
, P
, U
, F
, R
> Producer
for MapWithProducer
<'f
, P
, U
, F
>
132 F
: Fn(&mut U
, P
::Item
) -> R
+ Sync
,
136 type IntoIter
= MapWithIter
<'f
, P
::IntoIter
, U
, F
>;
138 fn into_iter(self) -> Self::IntoIter
{
140 base
: self.base
.into_iter(),
146 fn min_len(&self) -> usize {
149 fn max_len(&self) -> usize {
153 fn split_at(self, index
: usize) -> (Self, Self) {
154 let (left
, right
) = self.base
.split_at(index
);
158 item
: self.item
.clone(),
169 fn fold_with
<G
>(self, folder
: G
) -> G
171 G
: Folder
<Self::Item
>,
173 let folder1
= MapWithFolder
{
178 self.base
.fold_with(folder1
).base
182 struct MapWithIter
<'f
, I
, U
, F
: 'f
> {
188 impl<'f
, I
, U
, F
, R
> Iterator
for MapWithIter
<'f
, I
, U
, F
>
191 F
: Fn(&mut U
, I
::Item
) -> R
+ Sync
,
196 fn next(&mut self) -> Option
<R
> {
197 let item
= self.base
.next()?
;
198 Some((self.map_op
)(&mut self.item
, item
))
201 fn size_hint(&self) -> (usize, Option
<usize>) {
202 self.base
.size_hint()
206 impl<'f
, I
, U
, F
, R
> DoubleEndedIterator
for MapWithIter
<'f
, I
, U
, F
>
208 I
: DoubleEndedIterator
,
209 F
: Fn(&mut U
, I
::Item
) -> R
+ Sync
,
212 fn next_back(&mut self) -> Option
<R
> {
213 let item
= self.base
.next_back()?
;
214 Some((self.map_op
)(&mut self.item
, item
))
218 impl<'f
, I
, U
, F
, R
> ExactSizeIterator
for MapWithIter
<'f
, I
, U
, F
>
220 I
: ExactSizeIterator
,
221 F
: Fn(&mut U
, I
::Item
) -> R
+ Sync
,
226 /// ////////////////////////////////////////////////////////////////////////
227 /// Consumer implementation
229 struct MapWithConsumer
<'f
, C
, U
, F
: 'f
> {
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 }
241 impl<'f
, T
, U
, R
, C
, F
> Consumer
<T
> for MapWithConsumer
<'f
, C
, U
, F
>
245 F
: Fn(&mut U
, T
) -> R
+ Sync
,
248 type Folder
= MapWithFolder
<'f
, C
::Folder
, U
, F
>;
249 type Reducer
= C
::Reducer
;
250 type Result
= C
::Result
;
252 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
253 let (left
, right
, reducer
) = self.base
.split_at(index
);
255 MapWithConsumer
::new(left
, self.item
.clone(), self.map_op
),
256 MapWithConsumer
::new(right
, self.item
, self.map_op
),
261 fn into_folder(self) -> Self::Folder
{
263 base
: self.base
.into_folder(),
269 fn full(&self) -> bool
{
274 impl<'f
, T
, U
, R
, C
, F
> UnindexedConsumer
<T
> for MapWithConsumer
<'f
, C
, U
, F
>
276 C
: UnindexedConsumer
<R
>,
278 F
: Fn(&mut U
, T
) -> R
+ Sync
,
281 fn split_off_left(&self) -> Self {
282 MapWithConsumer
::new(self.base
.split_off_left(), self.item
.clone(), self.map_op
)
285 fn to_reducer(&self) -> Self::Reducer
{
286 self.base
.to_reducer()
290 struct MapWithFolder
<'f
, C
, U
, F
: 'f
> {
296 impl<'f
, T
, U
, R
, C
, F
> Folder
<T
> for MapWithFolder
<'f
, C
, U
, F
>
299 F
: Fn(&mut U
, T
) -> R
,
301 type Result
= C
::Result
;
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
);
309 fn consume_iter
<I
>(mut self, iter
: I
) -> Self
311 I
: IntoIterator
<Item
= T
>,
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
);
322 fn complete(self) -> C
::Result
{
326 fn full(&self) -> bool
{
331 // ------------------------------------------------------------------------------------------------
333 /// `MapInit` is an iterator that transforms the elements of an underlying iterator.
335 /// This struct is created by the [`map_init()`] method on [`ParallelIterator`]
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"]
341 pub struct MapInit
<I
: ParallelIterator
, INIT
, F
> {
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()
353 impl<I
, INIT
, F
> MapInit
<I
, INIT
, F
>
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 }
363 impl<I
, INIT
, T
, F
, R
> ParallelIterator
for MapInit
<I
, INIT
, F
>
366 INIT
: Fn() -> T
+ Sync
+ Send
,
367 F
: Fn(&mut T
, I
::Item
) -> R
+ Sync
+ Send
,
372 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
374 C
: UnindexedConsumer
<Self::Item
>,
376 let consumer1
= MapInitConsumer
::new(consumer
, &self.init
, &self.map_op
);
377 self.base
.drive_unindexed(consumer1
)
380 fn opt_len(&self) -> Option
<usize> {
385 impl<I
, INIT
, T
, F
, R
> IndexedParallelIterator
for MapInit
<I
, INIT
, F
>
387 I
: IndexedParallelIterator
,
388 INIT
: Fn() -> T
+ Sync
+ Send
,
389 F
: Fn(&mut T
, I
::Item
) -> R
+ Sync
+ Send
,
392 fn drive
<C
>(self, consumer
: C
) -> C
::Result
394 C
: Consumer
<Self::Item
>,
396 let consumer1
= MapInitConsumer
::new(consumer
, &self.init
, &self.map_op
);
397 self.base
.drive(consumer1
)
400 fn len(&self) -> usize {
404 fn with_producer
<CB
>(self, callback
: CB
) -> CB
::Output
406 CB
: ProducerCallback
<Self::Item
>,
408 return self.base
.with_producer(Callback
{
414 struct Callback
<CB
, INIT
, F
> {
420 impl<T
, INIT
, U
, F
, R
, CB
> ProducerCallback
<T
> for Callback
<CB
, INIT
, F
>
422 CB
: ProducerCallback
<R
>,
423 INIT
: Fn() -> U
+ Sync
,
424 F
: Fn(&mut U
, T
) -> R
+ Sync
,
427 type Output
= CB
::Output
;
429 fn callback
<P
>(self, base
: P
) -> CB
::Output
431 P
: Producer
<Item
= T
>,
433 let producer
= MapInitProducer
{
436 map_op
: &self.map_op
,
438 self.callback
.callback(producer
)
444 /// ////////////////////////////////////////////////////////////////////////
446 struct MapInitProducer
<'f
, P
, INIT
: 'f
, F
: 'f
> {
452 impl<'f
, P
, INIT
, U
, F
, R
> Producer
for MapInitProducer
<'f
, P
, INIT
, F
>
455 INIT
: Fn() -> U
+ Sync
,
456 F
: Fn(&mut U
, P
::Item
) -> R
+ Sync
,
460 type IntoIter
= MapWithIter
<'f
, P
::IntoIter
, U
, F
>;
462 fn into_iter(self) -> Self::IntoIter
{
464 base
: self.base
.into_iter(),
470 fn min_len(&self) -> usize {
473 fn max_len(&self) -> usize {
477 fn split_at(self, index
: usize) -> (Self, Self) {
478 let (left
, right
) = self.base
.split_at(index
);
493 fn fold_with
<G
>(self, folder
: G
) -> G
495 G
: Folder
<Self::Item
>,
497 let folder1
= MapWithFolder
{
502 self.base
.fold_with(folder1
).base
506 /// ////////////////////////////////////////////////////////////////////////
507 /// Consumer implementation
509 struct MapInitConsumer
<'f
, C
, INIT
: 'f
, F
: 'f
> {
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 }
521 impl<'f
, T
, INIT
, U
, R
, C
, F
> Consumer
<T
> for MapInitConsumer
<'f
, C
, INIT
, F
>
524 INIT
: Fn() -> U
+ Sync
,
525 F
: Fn(&mut U
, T
) -> R
+ Sync
,
528 type Folder
= MapWithFolder
<'f
, C
::Folder
, U
, F
>;
529 type Reducer
= C
::Reducer
;
530 type Result
= C
::Result
;
532 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
533 let (left
, right
, reducer
) = self.base
.split_at(index
);
535 MapInitConsumer
::new(left
, self.init
, self.map_op
),
536 MapInitConsumer
::new(right
, self.init
, self.map_op
),
541 fn into_folder(self) -> Self::Folder
{
543 base
: self.base
.into_folder(),
549 fn full(&self) -> bool
{
554 impl<'f
, T
, INIT
, U
, R
, C
, F
> UnindexedConsumer
<T
> for MapInitConsumer
<'f
, C
, INIT
, F
>
556 C
: UnindexedConsumer
<R
>,
557 INIT
: Fn() -> U
+ Sync
,
558 F
: Fn(&mut U
, T
) -> R
+ Sync
,
561 fn split_off_left(&self) -> Self {
562 MapInitConsumer
::new(self.base
.split_off_left(), self.init
, self.map_op
)
565 fn to_reducer(&self) -> Self::Reducer
{
566 self.base
.to_reducer()