iter: Implement .fold() for .chain()

Chain can do something interesting here where it passes on the fold
into its inner iterators.

The lets the underlying iterator's custom fold() be used, and skips the
regular chain logic in next.
This commit is contained in:
Ulrik Sverdrup 2016-10-25 15:21:49 +02:00
parent 780acda325
commit a16626fc42
2 changed files with 31 additions and 0 deletions

View File

@ -550,6 +550,25 @@ impl<A, B> Iterator for Chain<A, B> where
}
}
fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
where F: FnMut(Acc, Self::Item) -> Acc,
{
let mut accum = init;
match self.state {
ChainState::Both | ChainState::Front => {
accum = self.a.fold(accum, &mut f);
}
_ => { }
}
match self.state {
ChainState::Both | ChainState::Back => {
accum = self.b.fold(accum, &mut f);
}
_ => { }
}
accum
}
#[inline]
fn nth(&mut self, mut n: usize) -> Option<A::Item> {
match self.state {

View File

@ -985,6 +985,18 @@ fn test_empty() {
assert_eq!(it.next(), None);
}
#[test]
fn test_chain_fold() {
let xs = [1, 2, 3];
let ys = [1, 2, 0];
let mut iter = xs.iter().chain(&ys);
iter.next();
let mut result = Vec::new();
iter.fold((), |(), &elt| result.push(elt));
assert_eq!(&[2, 3, 1, 2, 0], &result[..]);
}
#[bench]
fn bench_rposition(b: &mut Bencher) {
let it: Vec<usize> = (0..300).collect();