8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
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
+ */
12
19
13
20
use prelude:: * ;
14
21
@@ -17,18 +24,34 @@ pub trait Iterator<A> {
17
24
fn next ( & mut self ) -> Option < A > ;
18
25
}
19
26
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.
20
31
pub trait IteratorUtil < A > {
32
+ fn chain ( self , other : Self ) -> ChainIterator < Self > ;
21
33
fn zip < B , U : Iterator < B > > ( self , other : U ) -> ZipIterator < Self , U > ;
22
34
// FIXME: #5898: should be called map
23
35
fn transform < ' r , B > ( self , f : & ' r fn ( A ) -> B ) -> MapIterator < ' r , A , B , Self > ;
24
36
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 > ;
27
37
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 > ;
28
42
fn advance ( & mut self , f : & fn ( A ) -> bool ) ;
29
43
}
30
44
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.
31
49
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
+
32
55
#[ inline( always) ]
33
56
fn zip < B , U : Iterator < B > > ( self , other : U ) -> ZipIterator < T , U > {
34
57
ZipIterator { a : self , b : other}
@@ -51,15 +74,25 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
51
74
}
52
75
53
76
#[ 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}
56
79
}
57
80
58
81
#[ 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 > {
60
83
TakeWhileIterator { iter : self , flag : false , predicate : predicate}
61
84
}
62
85
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
+
63
96
/// A shim implementing the `for` loop iteration protocol for iterator objects
64
97
#[ inline]
65
98
fn advance ( & mut self , f : & fn ( A ) -> bool ) {
@@ -74,6 +107,28 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
74
107
}
75
108
}
76
109
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
+
77
132
pub struct ZipIterator < T , U > {
78
133
priv a: T ,
79
134
priv b: U
@@ -89,6 +144,21 @@ impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<T, U
89
144
}
90
145
}
91
146
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
+
92
162
pub struct FilterIterator < ' self , A , T > {
93
163
priv iter : T ,
94
164
priv predicate : & ' self fn ( & A ) -> bool
@@ -108,21 +178,6 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
108
178
}
109
179
}
110
180
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
-
126
181
pub struct EnumerateIterator < T > {
127
182
priv iter : T ,
128
183
priv count : uint
@@ -142,13 +197,13 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<T> {
142
197
}
143
198
}
144
199
145
- pub struct DropWhileIterator < ' self , A , T > {
200
+ pub struct SkipWhileIterator < ' self , A , T > {
146
201
priv iter : T ,
147
202
priv flag : bool ,
148
203
priv predicate : & ' self fn ( & A ) -> bool
149
204
}
150
205
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 > {
152
207
#[ inline]
153
208
fn next ( & mut self ) -> Option < A > {
154
209
let mut next = self . iter . next ( ) ;
@@ -199,3 +254,176 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhileIterator<'self, A, T> {
199
254
}
200
255
}
201
256
}
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 = [ 0 u, 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 = [ 0 u, 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 = [ 0 u, 1 , 2 , 3 , 5 , 13 , 15 , 16 , 17 , 19 ] ;
360
+ let ys = [ 0 u, 1 , 2 , 3 , 5 , 13 ] ;
361
+ let mut it = xs. iter ( ) . take_while ( |& x| * x < 15 u) ;
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 = [ 0 u, 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 < 15 u) ;
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 = [ 0 u, 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 = [ 0 u, 1 , 2 , 3 , 5 , 13 , 15 , 16 , 17 , 19 ] ;
399
+ let ys = [ 0 u, 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
+ }
0 commit comments