@@ -479,6 +479,7 @@ pub fn each_permutation<T:Clone>(values: &[T], fun: &fn(perm : &[T]) -> bool) ->
479
479
480
480
/// An iterator over the (overlapping) slices of length `size` within
481
481
/// a vector.
482
+ #[ deriving( Clone ) ]
482
483
pub struct WindowIter < ' self , T > {
483
484
priv v: & ' self [ T ] ,
484
485
priv size : uint
@@ -498,23 +499,57 @@ impl<'self, T> Iterator<&'self [T]> for WindowIter<'self, T> {
498
499
499
500
/// An iterator over a vector in (non-overlapping) chunks (`size`
500
501
/// elements at a time).
502
+ ///
503
+ /// When the vector len is not evenly divided by the chunk size,
504
+ /// the last slice of the iteration will be the remainer.
505
+ #[ deriving( Clone ) ]
501
506
pub struct ChunkIter < ' self , T > {
502
507
priv v: & ' self [ T ] ,
503
508
priv size : uint
504
509
}
505
510
506
511
impl < ' self , T > Iterator < & ' self [ T ] > for ChunkIter < ' self , T > {
507
512
fn next ( & mut self ) -> Option < & ' self [ T ] > {
508
- if self . size == 0 {
513
+ if self . v . len ( ) == 0 {
509
514
None
510
- } else if self . size >= self . v . len ( ) {
511
- // finished
512
- self . size = 0 ;
513
- Some ( self . v )
514
515
} else {
515
- let ret = Some ( self . v . slice ( 0 , self . size ) ) ;
516
- self . v = self . v . slice ( self . size , self . v . len ( ) ) ;
517
- ret
516
+ let chunksz = cmp:: min ( self . v . len ( ) , self . size ) ;
517
+ let ( fst, snd) = ( self . v . slice_to ( chunksz) ,
518
+ self . v . slice_from ( chunksz) ) ;
519
+ self . v = snd;
520
+ Some ( fst)
521
+ }
522
+ }
523
+ }
524
+
525
+ impl < ' self , T > DoubleEndedIterator < & ' self [ T ] > for ChunkIter < ' self , T > {
526
+ fn next_back ( & mut self ) -> Option < & ' self [ T ] > {
527
+ if self . v . len ( ) == 0 {
528
+ None
529
+ } else {
530
+ let remainder = self . v . len ( ) % self . size ;
531
+ let chunksz = if remainder != 0 { remainder } else { self . size } ;
532
+ let ( fst, snd) = ( self . v . slice_to ( self . v . len ( ) - chunksz) ,
533
+ self . v . slice_from ( self . v . len ( ) - chunksz) ) ;
534
+ self . v = fst;
535
+ Some ( snd)
536
+ }
537
+ }
538
+ }
539
+
540
+ impl < ' self , T > RandomAccessIterator < & ' self [ T ] > for ChunkIter < ' self , T > {
541
+ #[ inline]
542
+ fn indexable ( & self ) -> uint {
543
+ self . v . len ( ) /self . size + if self . v . len ( ) % self . size != 0 { 1 } else { 0 }
544
+ }
545
+
546
+ #[ inline]
547
+ fn idx ( & self , index : uint ) -> Option < & ' self [ T ] > {
548
+ if index < self . indexable ( ) {
549
+ let lo = index * self . size ;
550
+ Some ( self . v . slice ( lo, cmp:: min ( lo, self . v . len ( ) - self . size ) + self . size ) )
551
+ } else {
552
+ None
518
553
}
519
554
}
520
555
}
@@ -3378,6 +3413,14 @@ mod tests {
3378
3413
assert_eq ! ( v. chunk_iter( 2 ) . collect:: <~[ & [ int] ] >( ) , ~[ & [ 1 i, 2 ] , & [ 3 , 4 ] , & [ 5 ] ] ) ;
3379
3414
assert_eq ! ( v. chunk_iter( 3 ) . collect:: <~[ & [ int] ] >( ) , ~[ & [ 1 i, 2 , 3 ] , & [ 4 , 5 ] ] ) ;
3380
3415
assert_eq ! ( v. chunk_iter( 6 ) . collect:: <~[ & [ int] ] >( ) , ~[ & [ 1 i, 2 , 3 , 4 , 5 ] ] ) ;
3416
+
3417
+ assert_eq ! ( v. chunk_iter( 2 ) . invert( ) . collect:: <~[ & [ int] ] >( ) , ~[ & [ 5 i] , & [ 3 , 4 ] , & [ 1 , 2 ] ] ) ;
3418
+ let it = v. chunk_iter ( 2 ) ;
3419
+ assert_eq ! ( it. indexable( ) , 3 ) ;
3420
+ assert_eq ! ( it. idx( 0 ) . unwrap( ) , & [ 1 , 2 ] ) ;
3421
+ assert_eq ! ( it. idx( 1 ) . unwrap( ) , & [ 3 , 4 ] ) ;
3422
+ assert_eq ! ( it. idx( 2 ) . unwrap( ) , & [ 5 ] ) ;
3423
+ assert_eq ! ( it. idx( 3 ) , None ) ;
3381
3424
}
3382
3425
3383
3426
#[ test]
0 commit comments