Implement find() on Chain iterators

This results in a roughly 2x speedup compared to the default impl
"inherited" from Iterator.
This commit is contained in:
Georg Brandl 2016-04-30 11:16:30 +02:00
parent 9b63263d0d
commit e6201cfb5c
2 changed files with 30 additions and 0 deletions

View File

@ -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 {

View File

@ -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)