Skip to content

Commit 41d7ab4

Browse files
authored
Merge pull request #16 from cuviper/more-fold
Specialize folds for Chain, FlatMap, and Inspect
2 parents cf3aad7 + e2d7adc commit 41d7ab4

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

src/lib.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,24 @@ where
622622
BothBackward | Back => self.b.get(),
623623
}
624624
}
625+
626+
#[inline]
627+
fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
628+
where
629+
Self: Sized,
630+
F: FnMut(Acc, &Self::Item) -> Acc,
631+
{
632+
let mut accum = init;
633+
match self.state {
634+
ChainState::Back => {}
635+
_ => accum = self.a.fold(accum, &mut f),
636+
}
637+
match self.state {
638+
ChainState::Front => {}
639+
_ => accum = self.b.fold(accum, &mut f),
640+
}
641+
accum
642+
}
625643
}
626644

627645
impl<A, B> DoubleEndedStreamingIterator for Chain<A, B>
@@ -646,6 +664,24 @@ where
646664
Back => self.b.advance_back(),
647665
}
648666
}
667+
668+
#[inline]
669+
fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
670+
where
671+
Self: Sized,
672+
F: FnMut(Acc, &Self::Item) -> Acc,
673+
{
674+
let mut accum = init;
675+
match self.state {
676+
ChainState::Front => {}
677+
_ => accum = self.b.rfold(accum, &mut f),
678+
}
679+
match self.state {
680+
ChainState::Back => {}
681+
_ => accum = self.a.rfold(accum, &mut f),
682+
}
683+
accum
684+
}
649685
}
650686

651687
/// A normal, non-streaming, iterator which converts the elements of a streaming iterator into owned
@@ -1031,6 +1067,20 @@ where
10311067
fn get(&self) -> Option<&Self::Item> {
10321068
self.sub_iter.as_ref().and_then(J::get)
10331069
}
1070+
1071+
#[inline]
1072+
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
1073+
where
1074+
Self: Sized,
1075+
Fold: FnMut(Acc, &Self::Item) -> Acc,
1076+
{
1077+
let mut acc = init;
1078+
if let Some(iter) = self.sub_iter {
1079+
acc = iter.fold(acc, &mut fold);
1080+
}
1081+
let mut f = self.f;
1082+
self.it.fold(acc, |acc, item| f(item).fold(acc, &mut fold))
1083+
}
10341084
}
10351085

10361086
/// A regular, non-streaming iterator which both filters and maps elements of a streaming iterator with a closure.
@@ -1200,6 +1250,19 @@ where
12001250
fn size_hint(&self) -> (usize, Option<usize>) {
12011251
self.it.size_hint()
12021252
}
1253+
1254+
#[inline]
1255+
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
1256+
where
1257+
Self: Sized,
1258+
Fold: FnMut(Acc, &Self::Item) -> Acc,
1259+
{
1260+
let mut f = self.f;
1261+
self.it.fold(init, |acc, item| {
1262+
f(item);
1263+
fold(acc, item)
1264+
})
1265+
}
12031266
}
12041267

12051268
impl<I, F> DoubleEndedStreamingIterator for Inspect<I, F>
@@ -1212,6 +1275,19 @@ where
12121275
(self.f)(item);
12131276
}
12141277
}
1278+
1279+
#[inline]
1280+
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
1281+
where
1282+
Self: Sized,
1283+
Fold: FnMut(Acc, &Self::Item) -> Acc,
1284+
{
1285+
let mut f = self.f;
1286+
self.it.rfold(init, |acc, item| {
1287+
f(item);
1288+
fold(acc, item)
1289+
})
1290+
}
12151291
}
12161292

12171293
/// A streaming iterator which transforms the elements of a streaming iterator.

0 commit comments

Comments
 (0)