Skip to content

Commit a2f2cc2

Browse files
authored
Merge pull request #184 from bluss/fold-using
Add method fold_with to Producer and UnindexedProducer
2 parents ee5799c + 31449c8 commit a2f2cc2

File tree

2 files changed

+45
-16
lines changed

2 files changed

+45
-16
lines changed

src/par_iter/chain.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ impl<A, B> Producer for ChainProducer<A, B>
185185
ChainProducer::new(0, a_right, b_right))
186186
}
187187
}
188+
189+
fn fold_with<F>(self, mut folder: F) -> F
190+
where F: Folder<A::Item>,
191+
{
192+
folder = self.a.fold_with(folder);
193+
if folder.full() {
194+
folder
195+
} else {
196+
self.b.fold_with(folder)
197+
}
198+
}
188199
}
189200

190201
impl<A, B> IntoIterator for ChainProducer<A, B>

src/par_iter/internal.rs

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ pub trait Producer: IntoIterator + Send + Sized {
2828
/// Split into two producers; one produces items `0..index`, the
2929
/// other `index..N`. Index must be less than `N`.
3030
fn split_at(self, index: usize) -> (Self, Self);
31+
32+
/// Iterate the producer, feeding each element to `folder`, and
33+
/// stop when the folder is full (or all elements have been consumed).
34+
///
35+
/// The provided implementation is sufficient for most iterables.
36+
fn fold_with<F>(self, mut folder: F) -> F
37+
where F: Folder<Self::Item>,
38+
{
39+
for item in self {
40+
folder = folder.consume(item);
41+
if folder.full() {
42+
break;
43+
}
44+
}
45+
folder
46+
}
3147
}
3248

3349
/// A consumer which consumes items that are fed to it.
@@ -95,6 +111,22 @@ pub trait UnindexedConsumer<ITEM>: Consumer<ITEM> {
95111
pub trait UnindexedProducer: IntoIterator + Send + Sized {
96112
fn can_split(&self) -> bool;
97113
fn split(self) -> (Self, Self);
114+
115+
/// Iterate the producer, feeding each element to `folder`, and
116+
/// stop when the folder is full (or all elements have been consumed).
117+
///
118+
/// The provided implementation is sufficient for most iterables.
119+
fn fold_with<F>(self, mut folder: F) -> F
120+
where F: Folder<Self::Item>,
121+
{
122+
for item in self {
123+
folder = folder.consume(item);
124+
if folder.full() {
125+
break;
126+
}
127+
}
128+
folder
129+
}
98130
}
99131

100132
/// A splitter controls the policy for splitting into smaller work items.
@@ -207,14 +239,7 @@ pub fn bridge_producer_consumer<P, C>(len: usize, mut producer: P, mut consumer:
207239
|| helper(len - mid, splitter, right_producer, right_consumer));
208240
reducer.reduce(left_result, right_result)
209241
} else {
210-
let mut folder = consumer.into_folder();
211-
for item in producer {
212-
folder = folder.consume(item);
213-
if folder.full() {
214-
break;
215-
}
216-
}
217-
folder.complete()
242+
producer.fold_with(consumer.into_folder()).complete()
218243
}
219244
}
220245
}
@@ -245,13 +270,6 @@ fn bridge_unindexed_producer_consumer<P, C>(mut splitter: Splitter,
245270
|| bridge_unindexed_producer_consumer(splitter, right_producer, right_consumer));
246271
reducer.reduce(left_result, right_result)
247272
} else {
248-
let mut folder = consumer.into_folder();
249-
for item in producer {
250-
folder = folder.consume(item);
251-
if folder.full() {
252-
break;
253-
}
254-
}
255-
folder.complete()
273+
producer.fold_with(consumer.into_folder()).complete()
256274
}
257275
}

0 commit comments

Comments
 (0)