@@ -1933,6 +1933,18 @@ pub trait MutableVector<'self, T> {
1933
1933
/// Returns a reversed iterator that allows modifying each value
1934
1934
fn mut_rev_iter ( self ) -> MutRevIterator < ' self , T > ;
1935
1935
1936
+ /**
1937
+ * Returns an iterator over `size` elements of the vector at a time.
1938
+ * The chunks are mutable and do not overlap. If `size` does not divide the
1939
+ * length of the vector, then the last chunk will not have length
1940
+ * `size`.
1941
+ *
1942
+ * # Failure
1943
+ *
1944
+ * Fails if `size` is 0.
1945
+ */
1946
+ fn mut_chunks ( self , chunk_size : uint ) -> MutChunkIter < ' self , T > ;
1947
+
1936
1948
/**
1937
1949
* Returns a mutable reference to the first element in this slice
1938
1950
* and adjusts the slice in place so that it no longer contains
@@ -2069,6 +2081,13 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
2069
2081
self . mut_iter ( ) . invert ( )
2070
2082
}
2071
2083
2084
+ #[ inline]
2085
+ fn mut_chunks ( self , chunk_size : uint ) -> MutChunkIter < ' self , T > {
2086
+ assert ! ( chunk_size > 0 ) ;
2087
+ let len = self . len ( ) ;
2088
+ MutChunkIter { v : self , chunk_size : chunk_size, remaining : len }
2089
+ }
2090
+
2072
2091
fn mut_shift_ref ( & mut self ) -> & ' self mut T {
2073
2092
unsafe {
2074
2093
let s: & mut Slice < T > = cast:: transmute ( self ) ;
@@ -2556,6 +2575,42 @@ impl<'self, T> Clone for VecIterator<'self, T> {
2556
2575
iterator ! { struct VecMutIterator -> * mut T , & ' self mut T }
2557
2576
pub type MutRevIterator < ' self , T > = Invert < VecMutIterator < ' self , T > > ;
2558
2577
2578
+ /// An iterator over a vector in (non-overlapping) mutable chunks (`size` elements at a time). When
2579
+ /// the vector len is not evenly divided by the chunk size, the last slice of the iteration will be
2580
+ /// the remainder.
2581
+ pub struct MutChunkIter < ' self , T > {
2582
+ priv v: & ' self mut [ T ] ,
2583
+ priv chunk_size : uint ,
2584
+ priv remaining : uint
2585
+ }
2586
+
2587
+ impl < ' self , T > Iterator < & ' self mut [ T ] > for MutChunkIter < ' self , T > {
2588
+ #[ inline]
2589
+ fn next ( & mut self ) -> Option < & ' self mut [ T ] > {
2590
+ if self . remaining == 0 {
2591
+ None
2592
+ } else {
2593
+ let sz = cmp:: min ( self . remaining , self . chunk_size ) ;
2594
+ let tmp = util:: replace ( & mut self . v , & mut [ ] ) ;
2595
+ let ( head, tail) = tmp. mut_split ( sz) ;
2596
+ self . v = tail;
2597
+ self . remaining -= sz;
2598
+ Some ( head)
2599
+ }
2600
+ }
2601
+
2602
+ #[ inline]
2603
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
2604
+ if self . remaining == 0 {
2605
+ ( 0 , Some ( 0 ) )
2606
+ } else {
2607
+ let ( n, rem) = self . remaining . div_rem ( & self . chunk_size ) ;
2608
+ let n = if rem > 0 { n + 1 } else { n } ;
2609
+ ( n, Some ( n) )
2610
+ }
2611
+ }
2612
+ }
2613
+
2559
2614
/// An iterator that moves out of a vector.
2560
2615
#[ deriving( Clone ) ]
2561
2616
pub struct MoveIterator < T > {
@@ -3966,6 +4021,24 @@ mod tests {
3966
4021
x. pop_ref ( ) ;
3967
4022
}
3968
4023
4024
+ #[ test]
4025
+ fn test_mut_chunks ( ) {
4026
+ let mut v = [ 0u8 , 1 , 2 , 3 , 4 , 5 , 6 ] ;
4027
+ for ( i, chunk) in v. mut_chunks ( 3 ) . enumerate ( ) {
4028
+ for x in chunk. mut_iter ( ) {
4029
+ * x = i as u8 ;
4030
+ }
4031
+ }
4032
+ let result = [ 0u8 , 0 , 0 , 1 , 1 , 1 , 2 ] ;
4033
+ assert_eq ! ( v, result) ;
4034
+ }
4035
+
4036
+ #[ test]
4037
+ #[ should_fail]
4038
+ fn test_mut_chunks_0 ( ) {
4039
+ let mut v = [ 1 , 2 , 3 , 4 ] ;
4040
+ let _it = v. mut_chunks ( 0 ) ;
4041
+ }
3969
4042
3970
4043
#[ test]
3971
4044
fn test_mut_shift_ref ( ) {
0 commit comments