Skip to content

Commit

Permalink
iter: Implement .fold() for .chain()
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bluss committed Oct 25, 2016
1 parent 780acda commit a16626f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 12 additions & 0 deletions src/libcoretest/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit a16626f

Please sign in to comment.