Skip to content

Commit a523abd

Browse files
committed
add dropwhile and takewhile iterators
1 parent d29ef7a commit a523abd

File tree

2 files changed

+99
-9
lines changed

2 files changed

+99
-9
lines changed

src/libcore/iterator.rs

+70
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub trait IteratorUtil<A> {
2222
// FIXME: #5898: should be called map
2323
fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, Self>;
2424
fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, Self>;
25+
fn dropwhile<'r>(self, predicate: &'r fn(&A) -> bool) -> DropWhileIterator<'r, A, Self>;
26+
fn takewhile<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>;
2527
fn enumerate(self) -> EnumerateIterator<Self>;
2628
fn advance(&mut self, f: &fn(A) -> bool);
2729
}
@@ -48,6 +50,16 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
4850
EnumerateIterator{iter: self, count: 0}
4951
}
5052

53+
#[inline(always)]
54+
fn dropwhile<'r>(self, predicate: &'r fn(&A) -> bool) -> DropWhileIterator<'r, A, T> {
55+
DropWhileIterator{iter: self, flag: false, predicate: predicate}
56+
}
57+
58+
#[inline(always)]
59+
fn takewhile<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, T> {
60+
TakeWhileIterator{iter: self, flag: false, predicate: predicate}
61+
}
62+
5163
/// A shim implementing the `for` loop iteration protocol for iterator objects
5264
#[inline]
5365
fn advance(&mut self, f: &fn(A) -> bool) {
@@ -129,3 +141,61 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<T> {
129141
}
130142
}
131143
}
144+
145+
pub struct DropWhileIterator<'self, A, T> {
146+
priv iter: T,
147+
priv flag: bool,
148+
priv predicate: &'self fn(&A) -> bool
149+
}
150+
151+
impl<'self, A, T: Iterator<A>> Iterator<A> for DropWhileIterator<'self, A, T> {
152+
#[inline]
153+
fn next(&mut self) -> Option<A> {
154+
let mut next = self.iter.next();
155+
if self.flag {
156+
next
157+
} else {
158+
loop {
159+
match next {
160+
Some(x) => {
161+
if (self.predicate)(&x) {
162+
next = self.iter.next();
163+
loop
164+
} else {
165+
self.flag = true;
166+
return Some(x)
167+
}
168+
}
169+
None => return None
170+
}
171+
}
172+
}
173+
}
174+
}
175+
176+
pub struct TakeWhileIterator<'self, A, T> {
177+
priv iter: T,
178+
priv flag: bool,
179+
priv predicate: &'self fn(&A) -> bool
180+
}
181+
182+
impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhileIterator<'self, A, T> {
183+
#[inline]
184+
fn next(&mut self) -> Option<A> {
185+
if self.flag {
186+
None
187+
} else {
188+
match self.iter.next() {
189+
Some(x) => {
190+
if (self.predicate)(&x) {
191+
Some(x)
192+
} else {
193+
self.flag = true;
194+
None
195+
}
196+
}
197+
None => None
198+
}
199+
}
200+
}
201+
}

src/libcore/vec.rs

+29-9
Original file line numberDiff line numberDiff line change
@@ -4478,18 +4478,38 @@ mod tests {
44784478
#[test]
44794479
fn test_iterator_enumerate() {
44804480
use iterator::*;
4481-
let xs = [0u,1,2,3,4,5];
4481+
let xs = [0u, 1, 2, 3, 4, 5];
44824482
let mut it = xs.iter().enumerate();
44834483
for it.advance |(i, &x): (uint, &uint)| {
44844484
assert_eq!(i, x);
44854485
}
44864486
}
4487-
}
44884487

4489-
// Local Variables:
4490-
// mode: rust;
4491-
// fill-column: 78;
4492-
// indent-tabs-mode: nil
4493-
// c-basic-offset: 4
4494-
// buffer-file-coding-system: utf-8-unix
4495-
// End:
4488+
#[test]
4489+
fn test_iterator_takewhile() {
4490+
use iterator::*;
4491+
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
4492+
let ys = [0u, 1, 2, 3, 5, 13];
4493+
let mut it = xs.iter().takewhile(|&x| *x < 15u);
4494+
let mut i = 0;
4495+
for it.advance |&x: &uint| {
4496+
assert_eq!(x, ys[i]);
4497+
i += 1;
4498+
}
4499+
assert_eq!(i, ys.len());
4500+
}
4501+
4502+
#[test]
4503+
fn test_iterator_dropwhile() {
4504+
use iterator::*;
4505+
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
4506+
let ys = [15, 16, 17, 19];
4507+
let mut it = xs.iter().dropwhile(|&x| *x < 15u);
4508+
let mut i = 0;
4509+
for it.advance |&x: &uint| {
4510+
assert_eq!(x, ys[i]);
4511+
i += 1;
4512+
}
4513+
assert_eq!(i, ys.len());
4514+
}
4515+
}

0 commit comments

Comments
 (0)