Skip to content

Commit

Permalink
Auto merge of #33289 - birkenfeld:chain-find, r=bluss
Browse files Browse the repository at this point in the history
Implement find() on Chain iterators

This results in a roughly 2x speedup compared to the default impl
"inherited" from Iterator.

Benchmark: https://gist.github.com/birkenfeld/aa9b92cb7d55666dd4821207527eaf5b
  • Loading branch information
bors committed May 2, 2016
2 parents d3c2c71 + e6201cf commit e1a575c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,23 @@ impl<A, B> Iterator for Chain<A, B> where
}
}

#[inline]
fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
P: FnMut(&Self::Item) -> bool,
{
match self.state {
ChainState::Both => match self.a.find(&mut predicate) {
None => {
self.state = ChainState::Back;
self.b.find(predicate)
}
v => v
},
ChainState::Front => self.a.find(predicate),
ChainState::Back => self.b.find(predicate),
}
}

#[inline]
fn last(self) -> Option<A::Item> {
match self.state {
Expand Down
13 changes: 13 additions & 0 deletions src/libcoretest/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,19 @@ fn test_iterator_chain_count() {
assert_eq!(zs.iter().chain(&ys).count(), 4);
}

#[test]
fn test_iterator_chain_find() {
let xs = [0, 1, 2, 3, 4, 5];
let ys = [30, 40, 50, 60];
let mut iter = xs.iter().chain(&ys);
assert_eq!(iter.find(|&&i| i == 4), Some(&4));
assert_eq!(iter.next(), Some(&5));
assert_eq!(iter.find(|&&i| i == 40), Some(&40));
assert_eq!(iter.next(), Some(&50));
assert_eq!(iter.find(|&&i| i == 100), None);
assert_eq!(iter.next(), None);
}

#[test]
fn test_filter_map() {
let it = (0..).step_by(1).take(10)
Expand Down

0 comments on commit e1a575c

Please sign in to comment.