@@ -245,6 +245,25 @@ pub trait IteratorUtil<A> {
245
245
fn flat_map_ < ' r , B , U : Iterator < B > > ( self , f : & ' r fn ( A ) -> U )
246
246
-> FlatMapIterator < ' r , A , B , Self , U > ;
247
247
248
+ /// Creates an iterator that calls a function with a reference to each
249
+ /// element before yielding it. This is often useful for debugging an
250
+ /// iterator pipeline.
251
+ ///
252
+ /// # Example
253
+ ///
254
+ /// ~~~ {.rust}
255
+ ///let xs = [1u, 4, 2, 3, 8, 9, 6];
256
+ ///let sum = xs.iter()
257
+ /// .transform(|&x| x)
258
+ /// .peek_(|&x| debug!("filtering %u", x))
259
+ /// .filter(|&x| x % 2 == 0)
260
+ /// .peek_(|&x| debug!("%u made it through", x))
261
+ /// .sum();
262
+ ///println(sum.to_str());
263
+ /// ~~~
264
+ // FIXME: #5898: should be called `peek`
265
+ fn peek_ < ' r > ( self , f : & ' r fn ( & A ) ) -> PeekIterator < ' r , A , Self > ;
266
+
248
267
/// An adaptation of an external iterator to the for-loop protocol of rust.
249
268
///
250
269
/// # Example
@@ -442,6 +461,12 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
442
461
FlatMapIterator { iter : self , f : f, subiter : None }
443
462
}
444
463
464
+ // FIXME: #5898: should be called `peek`
465
+ #[ inline]
466
+ fn peek_ < ' r > ( self , f : & ' r fn ( & A ) ) -> PeekIterator < ' r , A , T > {
467
+ PeekIterator { iter : self , f : f}
468
+ }
469
+
445
470
/// A shim implementing the `for` loop iteration protocol for iterator objects
446
471
#[ inline]
447
472
fn advance ( & mut self , f : & fn ( A ) -> bool ) -> bool {
@@ -1041,6 +1066,32 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
1041
1066
}
1042
1067
}
1043
1068
1069
+ /// An iterator that calls a function with a reference to each
1070
+ /// element before yielding it.
1071
+ pub struct PeekIterator < ' self , A , T > {
1072
+ priv iter: T ,
1073
+ priv f: & ' self fn ( & A )
1074
+ }
1075
+
1076
+ impl <' self , A , T : Iterator < A > > Iterator < A > for PeekIterator < ' self , A , T > {
1077
+ #[ inline]
1078
+ fn next( & mut self ) -> Option < A > {
1079
+ let next = self . iter. next( ) ;
1080
+
1081
+ match next {
1082
+ Some ( ref a) => ( self . f) ( a) ,
1083
+ None => ( )
1084
+ }
1085
+
1086
+ next
1087
+ }
1088
+
1089
+ #[ inline]
1090
+ fn size_hint( & self ) -> ( uint, Option < uint > ) {
1091
+ self . iter. size_hint( )
1092
+ }
1093
+ }
1094
+
1044
1095
/// An iterator which just modifies the contained state throughout iteration.
1045
1096
pub struct UnfoldrIterator < ' self , A , St > {
1046
1097
priv f: & ' self fn( & mut St ) -> Option < A > ,
@@ -1236,6 +1287,20 @@ mod tests {
1236
1287
assert_eq ! ( i, ys. len( ) ) ;
1237
1288
}
1238
1289
1290
+ #[ test]
1291
+ fn test_peek( ) {
1292
+ let xs = [ 1 u, 2 , 3 , 4 ] ;
1293
+ let mut n = 0 ;
1294
+
1295
+ let ys = xs. iter( )
1296
+ . transform( |& x| x)
1297
+ . peek_( |_| n += 1 )
1298
+ . collect :: < ~[ uint ] > ( ) ;
1299
+
1300
+ assert_eq ! ( n, xs. len( ) ) ;
1301
+ assert_eq ! ( xs, ys. as_slice( ) ) ;
1302
+ }
1303
+
1239
1304
#[ test]
1240
1305
fn test_unfoldr( ) {
1241
1306
fn count( st: & mut uint) -> Option < uint > {
0 commit comments