Skip to content

Commit 23bc6ee

Browse files
committed
---
yaml --- r: 60435 b: refs/heads/auto c: 9ffbe69 h: refs/heads/master i: 60433: b6f470a 60431: 685ef65 v: v3
1 parent 2c5332a commit 23bc6ee

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
1414
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1515
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1616
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
17-
refs/heads/auto: f7e58ebe84513ed65b1694311f8c4f35e53e8c0e
17+
refs/heads/auto: 9ffbe69234317859ca910fe5c419cacf4089d60b
1818
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1919
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c

branches/auto/src/libcore/iterator.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub trait IteratorUtil<A> {
3434
// FIXME: #5898: should be called map
3535
fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, Self>;
3636
fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, Self>;
37+
fn filter_map<'r, B>(self, f: &'r fn(A) -> Option<B>) -> FilterMapIterator<'r, A, B, Self>;
3738
fn enumerate(self) -> EnumerateIterator<Self>;
3839
fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, Self>;
3940
fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>;
@@ -74,6 +75,11 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
7475
FilterIterator{iter: self, predicate: predicate}
7576
}
7677

78+
#[inline(always)]
79+
fn filter_map<'r, B>(self, f: &'r fn(A) -> Option<B>) -> FilterMapIterator<'r, A, B, T> {
80+
FilterMapIterator { iter: self, f: f }
81+
}
82+
7783
#[inline(always)]
7884
fn enumerate(self) -> EnumerateIterator<T> {
7985
EnumerateIterator{iter: self, count: 0}
@@ -213,6 +219,28 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
213219
}
214220
}
215221

222+
pub struct FilterMapIterator<'self, A, B, T> {
223+
priv iter: T,
224+
priv f: &'self fn(A) -> Option<B>
225+
}
226+
227+
impl<'self, A, B, T: Iterator<A>> Iterator<B> for FilterMapIterator<'self, A, B, T> {
228+
#[inline]
229+
fn next(&mut self) -> Option<B> {
230+
loop {
231+
match self.iter.next() {
232+
None => { return None; }
233+
Some(a) => {
234+
match (self.f)(a) {
235+
Some(b) => { return Some(b); }
236+
None => { loop; }
237+
}
238+
}
239+
}
240+
}
241+
}
242+
}
243+
216244
pub struct EnumerateIterator<T> {
217245
priv iter: T,
218246
priv count: uint
@@ -432,6 +460,13 @@ mod tests {
432460
assert_eq!(i, expected.len());
433461
}
434462

463+
#[test]
464+
fn test_filter_map() {
465+
let it = Counter::new(0u, 1u).take(10)
466+
.filter_map(|x: uint| if x.is_even() { Some(x*x) } else { None });
467+
assert_eq!(it.to_vec(), ~[0*0, 2*2, 4*4, 6*6, 8*8]);
468+
}
469+
435470
#[test]
436471
fn test_iterator_enumerate() {
437472
let xs = [0u, 1, 2, 3, 4, 5];

0 commit comments

Comments
 (0)