Skip to content

Commit 10e6869

Browse files
committed
auto merge of #5955 : thestinger/rust/iterator, r=graydon
2 parents 465666d + a2e5350 commit 10e6869

File tree

2 files changed

+251
-61
lines changed

2 files changed

+251
-61
lines changed

src/libcore/iterator.rs

+251-23
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! Composable iterator objects
11+
/*! Composable external iterators
12+
13+
The `Iterator` trait defines an interface for objects which implement iteration as a state machine.
14+
15+
Algorithms like `zip` are provided as `Iterator` implementations which wrap other objects
16+
implementing the `Iterator` trait.
17+
18+
*/
1219

1320
use prelude::*;
1421

@@ -17,18 +24,34 @@ pub trait Iterator<A> {
1724
fn next(&mut self) -> Option<A>;
1825
}
1926

27+
/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
28+
/// implementations of the `Iterator` trait.
29+
///
30+
/// In the future these will be default methods instead of a utility trait.
2031
pub trait IteratorUtil<A> {
32+
fn chain(self, other: Self) -> ChainIterator<Self>;
2133
fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<Self, U>;
2234
// FIXME: #5898: should be called map
2335
fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, Self>;
2436
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>;
2737
fn enumerate(self) -> EnumerateIterator<Self>;
38+
fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, Self>;
39+
fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>;
40+
fn skip(self, n: uint) -> SkipIterator<Self>;
41+
fn take(self, n: uint) -> TakeIterator<Self>;
2842
fn advance(&mut self, f: &fn(A) -> bool);
2943
}
3044

45+
/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
46+
/// implementations of the `Iterator` trait.
47+
///
48+
/// In the future these will be default methods instead of a utility trait.
3149
impl<A, T: Iterator<A>> IteratorUtil<A> for T {
50+
#[inline(always)]
51+
fn chain(self, other: T) -> ChainIterator<T> {
52+
ChainIterator{a: self, b: other, flag: false}
53+
}
54+
3255
#[inline(always)]
3356
fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<T, U> {
3457
ZipIterator{a: self, b: other}
@@ -51,15 +74,25 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
5174
}
5275

5376
#[inline(always)]
54-
fn dropwhile<'r>(self, predicate: &'r fn(&A) -> bool) -> DropWhileIterator<'r, A, T> {
55-
DropWhileIterator{iter: self, flag: false, predicate: predicate}
77+
fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, T> {
78+
SkipWhileIterator{iter: self, flag: false, predicate: predicate}
5679
}
5780

5881
#[inline(always)]
59-
fn takewhile<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, T> {
82+
fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, T> {
6083
TakeWhileIterator{iter: self, flag: false, predicate: predicate}
6184
}
6285

86+
#[inline(always)]
87+
fn skip(self, n: uint) -> SkipIterator<T> {
88+
SkipIterator{iter: self, n: n}
89+
}
90+
91+
#[inline(always)]
92+
fn take(self, n: uint) -> TakeIterator<T> {
93+
TakeIterator{iter: self, n: n}
94+
}
95+
6396
/// A shim implementing the `for` loop iteration protocol for iterator objects
6497
#[inline]
6598
fn advance(&mut self, f: &fn(A) -> bool) {
@@ -74,6 +107,28 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
74107
}
75108
}
76109

110+
pub struct ChainIterator<T> {
111+
priv a: T,
112+
priv b: T,
113+
priv flag: bool
114+
}
115+
116+
impl<A, T: Iterator<A>> Iterator<A> for ChainIterator<T> {
117+
#[inline]
118+
fn next(&mut self) -> Option<A> {
119+
if self.flag {
120+
self.b.next()
121+
} else {
122+
match self.a.next() {
123+
Some(x) => return Some(x),
124+
_ => ()
125+
}
126+
self.flag = true;
127+
self.b.next()
128+
}
129+
}
130+
}
131+
77132
pub struct ZipIterator<T, U> {
78133
priv a: T,
79134
priv b: U
@@ -89,6 +144,21 @@ impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<T, U
89144
}
90145
}
91146

147+
pub struct MapIterator<'self, A, B, T> {
148+
priv iter: T,
149+
priv f: &'self fn(A) -> B
150+
}
151+
152+
impl<'self, A, B, T: Iterator<A>> Iterator<B> for MapIterator<'self, A, B, T> {
153+
#[inline]
154+
fn next(&mut self) -> Option<B> {
155+
match self.iter.next() {
156+
Some(a) => Some((self.f)(a)),
157+
_ => None
158+
}
159+
}
160+
}
161+
92162
pub struct FilterIterator<'self, A, T> {
93163
priv iter: T,
94164
priv predicate: &'self fn(&A) -> bool
@@ -108,21 +178,6 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
108178
}
109179
}
110180

111-
pub struct MapIterator<'self, A, B, T> {
112-
priv iter: T,
113-
priv f: &'self fn(A) -> B
114-
}
115-
116-
impl<'self, A, B, T: Iterator<A>> Iterator<B> for MapIterator<'self, A, B, T> {
117-
#[inline]
118-
fn next(&mut self) -> Option<B> {
119-
match self.iter.next() {
120-
Some(a) => Some((self.f)(a)),
121-
_ => None
122-
}
123-
}
124-
}
125-
126181
pub struct EnumerateIterator<T> {
127182
priv iter: T,
128183
priv count: uint
@@ -142,13 +197,13 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<T> {
142197
}
143198
}
144199

145-
pub struct DropWhileIterator<'self, A, T> {
200+
pub struct SkipWhileIterator<'self, A, T> {
146201
priv iter: T,
147202
priv flag: bool,
148203
priv predicate: &'self fn(&A) -> bool
149204
}
150205

151-
impl<'self, A, T: Iterator<A>> Iterator<A> for DropWhileIterator<'self, A, T> {
206+
impl<'self, A, T: Iterator<A>> Iterator<A> for SkipWhileIterator<'self, A, T> {
152207
#[inline]
153208
fn next(&mut self) -> Option<A> {
154209
let mut next = self.iter.next();
@@ -199,3 +254,176 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhileIterator<'self, A, T> {
199254
}
200255
}
201256
}
257+
258+
pub struct SkipIterator<T> {
259+
priv iter: T,
260+
priv n: uint
261+
}
262+
263+
impl<A, T: Iterator<A>> Iterator<A> for SkipIterator<T> {
264+
#[inline]
265+
fn next(&mut self) -> Option<A> {
266+
let mut next = self.iter.next();
267+
if self.n == 0 {
268+
next
269+
} else {
270+
let n = self.n;
271+
for n.times {
272+
match next {
273+
Some(_) => {
274+
next = self.iter.next();
275+
loop
276+
}
277+
None => {
278+
self.n = 0;
279+
return None
280+
}
281+
}
282+
}
283+
self.n = 0;
284+
next
285+
}
286+
}
287+
}
288+
289+
pub struct TakeIterator<T> {
290+
priv iter: T,
291+
priv n: uint
292+
}
293+
294+
impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<T> {
295+
#[inline]
296+
fn next(&mut self) -> Option<A> {
297+
let next = self.iter.next();
298+
if self.n != 0 {
299+
self.n -= 1;
300+
next
301+
} else {
302+
None
303+
}
304+
}
305+
}
306+
307+
pub struct UnfoldrIterator<'self, A, St> {
308+
priv f: &'self fn(&mut St) -> Option<A>,
309+
priv state: St
310+
}
311+
312+
pub impl<'self, A, St> UnfoldrIterator<'self, A, St> {
313+
#[inline]
314+
fn new(f: &'self fn(&mut St) -> Option<A>, initial_state: St) -> UnfoldrIterator<'self, A, St> {
315+
UnfoldrIterator {
316+
f: f,
317+
state: initial_state
318+
}
319+
}
320+
}
321+
322+
impl<'self, A, St> Iterator<A> for UnfoldrIterator<'self, A, St> {
323+
#[inline]
324+
fn next(&mut self) -> Option<A> {
325+
(self.f)(&mut self.state)
326+
}
327+
}
328+
329+
#[cfg(test)]
330+
mod tests {
331+
use super::*;
332+
use prelude::*;
333+
334+
#[test]
335+
fn test_iterator_chain() {
336+
let xs = [0u, 1, 2, 3, 4, 5];
337+
let ys = [30, 40, 50, 60];
338+
let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
339+
let mut it = xs.iter().chain(ys.iter());
340+
let mut i = 0;
341+
for it.advance |&x: &uint| {
342+
assert_eq!(x, expected[i]);
343+
i += 1;
344+
}
345+
assert_eq!(i, expected.len());
346+
}
347+
348+
#[test]
349+
fn test_iterator_enumerate() {
350+
let xs = [0u, 1, 2, 3, 4, 5];
351+
let mut it = xs.iter().enumerate();
352+
for it.advance |(i, &x): (uint, &uint)| {
353+
assert_eq!(i, x);
354+
}
355+
}
356+
357+
#[test]
358+
fn test_iterator_take_while() {
359+
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
360+
let ys = [0u, 1, 2, 3, 5, 13];
361+
let mut it = xs.iter().take_while(|&x| *x < 15u);
362+
let mut i = 0;
363+
for it.advance |&x: &uint| {
364+
assert_eq!(x, ys[i]);
365+
i += 1;
366+
}
367+
assert_eq!(i, ys.len());
368+
}
369+
370+
#[test]
371+
fn test_iterator_skip_while() {
372+
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
373+
let ys = [15, 16, 17, 19];
374+
let mut it = xs.iter().skip_while(|&x| *x < 15u);
375+
let mut i = 0;
376+
for it.advance |&x: &uint| {
377+
assert_eq!(x, ys[i]);
378+
i += 1;
379+
}
380+
assert_eq!(i, ys.len());
381+
}
382+
383+
#[test]
384+
fn test_iterator_skip() {
385+
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
386+
let ys = [13, 15, 16, 17, 19, 20, 30];
387+
let mut it = xs.iter().skip(5);
388+
let mut i = 0;
389+
for it.advance |&x: &uint| {
390+
assert_eq!(x, ys[i]);
391+
i += 1;
392+
}
393+
assert_eq!(i, ys.len());
394+
}
395+
396+
#[test]
397+
fn test_iterator_take() {
398+
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
399+
let ys = [0u, 1, 2, 3, 5];
400+
let mut it = xs.iter().take(5);
401+
let mut i = 0;
402+
for it.advance |&x: &uint| {
403+
assert_eq!(x, ys[i]);
404+
i += 1;
405+
}
406+
assert_eq!(i, ys.len());
407+
}
408+
409+
#[test]
410+
fn test_unfoldr() {
411+
fn count(st: &mut uint) -> Option<uint> {
412+
if *st < 10 {
413+
let ret = Some(*st);
414+
*st += 1;
415+
ret
416+
} else {
417+
None
418+
}
419+
}
420+
421+
let mut it = UnfoldrIterator::new(count, 0);
422+
let mut i = 0;
423+
for it.advance |counted| {
424+
assert_eq!(counted, i);
425+
i += 1;
426+
}
427+
assert_eq!(i, 10);
428+
}
429+
}

src/libcore/vec.rs

-38
Original file line numberDiff line numberDiff line change
@@ -4474,42 +4474,4 @@ mod tests {
44744474
i += 1;
44754475
}
44764476
}
4477-
4478-
#[test]
4479-
fn test_iterator_enumerate() {
4480-
use iterator::*;
4481-
let xs = [0u, 1, 2, 3, 4, 5];
4482-
let mut it = xs.iter().enumerate();
4483-
for it.advance |(i, &x): (uint, &uint)| {
4484-
assert_eq!(i, x);
4485-
}
4486-
}
4487-
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-
}
45154477
}

0 commit comments

Comments
 (0)