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
>,
313 fn with
<'f
, T
, U
, R
>(
315 map_op
: impl Fn(&mut U
, T
) -> R
+ 'f
,
316 ) -> impl FnMut(T
) -> R
+ 'f
{
317 move |x
| map_op(item
, x
)
321 let mapped_iter
= iter
.into_iter().map(with(&mut self.item
, self.map_op
));
322 self.base
= self.base
.consume_iter(mapped_iter
);
327 fn complete(self) -> C
::Result
{
331 fn full(&self) -> bool
{
336 // ------------------------------------------------------------------------------------------------
338 /// `MapInit` is an iterator that transforms the elements of an underlying iterator.
340 /// This struct is created by the [`map_init()`] method on [`ParallelIterator`]
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"]
346 pub struct MapInit
<I
: ParallelIterator
, INIT
, F
> {
352 impl<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("base", &self.base
).finish()
358 impl<I
, INIT
, F
> MapInit
<I
, INIT
, F
>
362 /// Create a new `MapInit` iterator.
363 pub(super) fn new(base
: I
, init
: INIT
, map_op
: F
) -> Self {
364 MapInit { base, init, map_op }
368 impl<I
, INIT
, T
, F
, R
> ParallelIterator
for MapInit
<I
, INIT
, F
>
371 INIT
: Fn() -> T
+ Sync
+ Send
,
372 F
: Fn(&mut T
, I
::Item
) -> R
+ Sync
+ Send
,
377 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
379 C
: UnindexedConsumer
<Self::Item
>,
381 let consumer1
= MapInitConsumer
::new(consumer
, &self.init
, &self.map_op
);
382 self.base
.drive_unindexed(consumer1
)
385 fn opt_len(&self) -> Option
<usize> {
390 impl<I
, INIT
, T
, F
, R
> IndexedParallelIterator
for MapInit
<I
, INIT
, F
>
392 I
: IndexedParallelIterator
,
393 INIT
: Fn() -> T
+ Sync
+ Send
,
394 F
: Fn(&mut T
, I
::Item
) -> R
+ Sync
+ Send
,
397 fn drive
<C
>(self, consumer
: C
) -> C
::Result
399 C
: Consumer
<Self::Item
>,
401 let consumer1
= MapInitConsumer
::new(consumer
, &self.init
, &self.map_op
);
402 self.base
.drive(consumer1
)
405 fn len(&self) -> usize {
409 fn with_producer
<CB
>(self, callback
: CB
) -> CB
::Output
411 CB
: ProducerCallback
<Self::Item
>,
413 return self.base
.with_producer(Callback
{
419 struct Callback
<CB
, INIT
, F
> {
425 impl<T
, INIT
, U
, F
, R
, CB
> ProducerCallback
<T
> for Callback
<CB
, INIT
, F
>
427 CB
: ProducerCallback
<R
>,
428 INIT
: Fn() -> U
+ Sync
,
429 F
: Fn(&mut U
, T
) -> R
+ Sync
,
432 type Output
= CB
::Output
;
434 fn callback
<P
>(self, base
: P
) -> CB
::Output
436 P
: Producer
<Item
= T
>,
438 let producer
= MapInitProducer
{
441 map_op
: &self.map_op
,
443 self.callback
.callback(producer
)
449 /// ////////////////////////////////////////////////////////////////////////
451 struct MapInitProducer
<'f
, P
, INIT
: 'f
, F
: 'f
> {
457 impl<'f
, P
, INIT
, U
, F
, R
> Producer
for MapInitProducer
<'f
, P
, INIT
, F
>
460 INIT
: Fn() -> U
+ Sync
,
461 F
: Fn(&mut U
, P
::Item
) -> R
+ Sync
,
465 type IntoIter
= MapWithIter
<'f
, P
::IntoIter
, U
, F
>;
467 fn into_iter(self) -> Self::IntoIter
{
469 base
: self.base
.into_iter(),
475 fn min_len(&self) -> usize {
478 fn max_len(&self) -> usize {
482 fn split_at(self, index
: usize) -> (Self, Self) {
483 let (left
, right
) = self.base
.split_at(index
);
498 fn fold_with
<G
>(self, folder
: G
) -> G
500 G
: Folder
<Self::Item
>,
502 let folder1
= MapWithFolder
{
507 self.base
.fold_with(folder1
).base
511 /// ////////////////////////////////////////////////////////////////////////
512 /// Consumer implementation
514 struct MapInitConsumer
<'f
, C
, INIT
: 'f
, F
: 'f
> {
520 impl<'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 }
526 impl<'f
, T
, INIT
, U
, R
, C
, F
> Consumer
<T
> for MapInitConsumer
<'f
, C
, INIT
, F
>
529 INIT
: Fn() -> U
+ Sync
,
530 F
: Fn(&mut U
, T
) -> R
+ Sync
,
533 type Folder
= MapWithFolder
<'f
, C
::Folder
, U
, F
>;
534 type Reducer
= C
::Reducer
;
535 type Result
= C
::Result
;
537 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
538 let (left
, right
, reducer
) = self.base
.split_at(index
);
540 MapInitConsumer
::new(left
, self.init
, self.map_op
),
541 MapInitConsumer
::new(right
, self.init
, self.map_op
),
546 fn into_folder(self) -> Self::Folder
{
548 base
: self.base
.into_folder(),
554 fn full(&self) -> bool
{
559 impl<'f
, T
, INIT
, U
, R
, C
, F
> UnindexedConsumer
<T
> for MapInitConsumer
<'f
, C
, INIT
, F
>
561 C
: UnindexedConsumer
<R
>,
562 INIT
: Fn() -> U
+ Sync
,
563 F
: Fn(&mut U
, T
) -> R
+ Sync
,
566 fn split_off_left(&self) -> Self {
567 MapInitConsumer
::new(self.base
.split_off_left(), self.init
, self.map_op
)
570 fn to_reducer(&self) -> Self::Reducer
{
571 self.base
.to_reducer()