1 use super::plumbing
::*;
4 use std
::fmt
::{self, Debug}
;
6 /// `Positions` takes a predicate `predicate` and filters out elements that match,
7 /// yielding their indices.
9 /// This struct is created by the [`positions()`] method on [`IndexedParallelIterator`]
11 /// [`positions()`]: trait.IndexedParallelIterator.html#method.positions
12 /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
13 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
15 pub struct Positions
<I
: IndexedParallelIterator
, P
> {
20 impl<I
: IndexedParallelIterator
+ Debug
, P
> Debug
for Positions
<I
, P
> {
21 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
22 f
.debug_struct("Positions")
23 .field("base", &self.base
)
28 impl<I
, P
> Positions
<I
, P
>
30 I
: IndexedParallelIterator
,
32 /// Create a new `Positions` iterator.
33 pub(super) fn new(base
: I
, predicate
: P
) -> Self {
34 Positions { base, predicate }
38 impl<I
, P
> ParallelIterator
for Positions
<I
, P
>
40 I
: IndexedParallelIterator
,
41 P
: Fn(I
::Item
) -> bool
+ Sync
+ Send
,
45 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
47 C
: UnindexedConsumer
<Self::Item
>,
49 let consumer1
= PositionsConsumer
::new(consumer
, &self.predicate
, 0);
50 self.base
.drive(consumer1
)
54 /// ////////////////////////////////////////////////////////////////////////
55 /// Consumer implementation
57 struct PositionsConsumer
<'p
, C
, P
> {
63 impl<'p
, C
, P
> PositionsConsumer
<'p
, C
, P
> {
64 fn new(base
: C
, predicate
: &'p P
, offset
: usize) -> Self {
73 impl<'p
, T
, C
, P
> Consumer
<T
> for PositionsConsumer
<'p
, C
, P
>
76 P
: Fn(T
) -> bool
+ Sync
,
78 type Folder
= PositionsFolder
<'p
, C
::Folder
, P
>;
79 type Reducer
= C
::Reducer
;
80 type Result
= C
::Result
;
82 fn split_at(self, index
: usize) -> (Self, Self, C
::Reducer
) {
83 let (left
, right
, reducer
) = self.base
.split_at(index
);
85 PositionsConsumer
::new(left
, self.predicate
, self.offset
),
86 PositionsConsumer
::new(right
, self.predicate
, self.offset
+ index
),
91 fn into_folder(self) -> Self::Folder
{
93 base
: self.base
.into_folder(),
94 predicate
: self.predicate
,
99 fn full(&self) -> bool
{
104 struct PositionsFolder
<'p
, F
, P
> {
110 impl<F
, P
, T
> Folder
<T
> for PositionsFolder
<'_
, F
, P
>
115 type Result
= F
::Result
;
117 fn consume(mut self, item
: T
) -> Self {
118 let index
= self.offset
;
120 if (self.predicate
)(item
) {
121 self.base
= self.base
.consume(index
);
126 // This cannot easily specialize `consume_iter` to be better than
127 // the default, because that requires checking `self.base.full()`
128 // during a call to `self.base.consume_iter()`. (#632)
130 fn complete(self) -> Self::Result
{
134 fn full(&self) -> bool
{