1 use super::plumbing
::*;
4 use std
::fmt
::{self, Debug}
;
6 /// `Filter` takes a predicate `filter_op` and filters out elements that match.
7 /// This struct is created by the [`filter()`] method on [`ParallelIterator`]
9 /// [`filter()`]: trait.ParallelIterator.html#method.filter
10 /// [`ParallelIterator`]: trait.ParallelIterator.html
11 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13 pub struct Filter
<I
: ParallelIterator
, P
> {
18 impl<I
: ParallelIterator
+ Debug
, P
> Debug
for Filter
<I
, P
> {
19 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
20 f
.debug_struct("Filter").field("base", &self.base
).finish()
24 impl<I
, P
> Filter
<I
, P
>
28 /// Create a new `Filter` iterator.
29 pub(super) fn new(base
: I
, filter_op
: P
) -> Self {
30 Filter { base, filter_op }
34 impl<I
, P
> ParallelIterator
for Filter
<I
, P
>
37 P
: Fn(&I
::Item
) -> bool
+ Sync
+ Send
,
41 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
43 C
: UnindexedConsumer
<Self::Item
>,
45 let consumer1
= FilterConsumer
::new(consumer
, &self.filter_op
);
46 self.base
.drive_unindexed(consumer1
)
50 /// ////////////////////////////////////////////////////////////////////////
51 /// Consumer implementation
53 struct FilterConsumer
<'p
, C
, P
> {
58 impl<'p
, C
, P
> FilterConsumer
<'p
, C
, P
> {
59 fn new(base
: C
, filter_op
: &'p P
) -> Self {
60 FilterConsumer { base, filter_op }
64 impl<'p
, T
, C
, P
: 'p
> Consumer
<T
> for FilterConsumer
<'p
, C
, P
>
67 P
: Fn(&T
) -> bool
+ Sync
,
69 type Folder
= FilterFolder
<'p
, C
::Folder
, P
>;
70 type Reducer
= C
::Reducer
;
71 type Result
= C
::Result
;
73 fn split_at(self, index
: usize) -> (Self, Self, C
::Reducer
) {
74 let (left
, right
, reducer
) = self.base
.split_at(index
);
76 FilterConsumer
::new(left
, self.filter_op
),
77 FilterConsumer
::new(right
, self.filter_op
),
82 fn into_folder(self) -> Self::Folder
{
84 base
: self.base
.into_folder(),
85 filter_op
: self.filter_op
,
89 fn full(&self) -> bool
{
94 impl<'p
, T
, C
, P
: 'p
> UnindexedConsumer
<T
> for FilterConsumer
<'p
, C
, P
>
96 C
: UnindexedConsumer
<T
>,
97 P
: Fn(&T
) -> bool
+ Sync
,
99 fn split_off_left(&self) -> Self {
100 FilterConsumer
::new(self.base
.split_off_left(), &self.filter_op
)
103 fn to_reducer(&self) -> Self::Reducer
{
104 self.base
.to_reducer()
108 struct FilterFolder
<'p
, C
, P
> {
113 impl<'p
, C
, P
, T
> Folder
<T
> for FilterFolder
<'p
, C
, P
>
116 P
: Fn(&T
) -> bool
+ 'p
,
118 type Result
= C
::Result
;
120 fn consume(self, item
: T
) -> Self {
121 let filter_op
= self.filter_op
;
122 if filter_op(&item
) {
123 let base
= self.base
.consume(item
);
124 FilterFolder { base, filter_op }
130 // This cannot easily specialize `consume_iter` to be better than
131 // the default, because that requires checking `self.base.full()`
132 // during a call to `self.base.consume_iter()`. (#632)
134 fn complete(self) -> Self::Result
{
138 fn full(&self) -> bool
{