@@ -1415,26 +1415,21 @@ impl<'a, T> Iterator for Windows<'a, T> {
14151415#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14161416impl < ' a , T > DoubleEndedIterator for Windows < ' a , T > {
14171417 #[ inline]
1418- fn next_back ( & mut self ) -> Option < & ' a [ T ] > {
1419- if self . size . get ( ) > self . v . len ( ) {
1420- None
1421- } else {
1422- let ret = Some ( & self . v [ self . v . len ( ) - self . size . get ( ) ..] ) ;
1423- self . v = & self . v [ ..self . v . len ( ) - 1 ] ;
1424- ret
1425- }
1418+ fn next_back ( & mut self ) -> Option < Self :: Item > {
1419+ self . nth_back ( 0 )
14261420 }
14271421
14281422 #[ inline]
14291423 fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
1430- let ( end, overflow) = self . v . len ( ) . overflowing_sub ( n) ;
1431- if end < self . size . get ( ) || overflow {
1424+ if let Some ( end) = self . v . len ( ) . checked_sub ( n)
1425+ && let Some ( start) = end. checked_sub ( self . size . get ( ) )
1426+ {
1427+ let res = & self . v [ start..end] ;
1428+ self . v = & self . v [ ..end - 1 ] ;
1429+ Some ( res)
1430+ } else {
14321431 self . v = & self . v [ ..0 ] ; // cheaper than &[]
14331432 None
1434- } else {
1435- let ret = & self . v [ end - self . size . get ( ) ..end] ;
1436- self . v = & self . v [ ..end - 1 ] ;
1437- Some ( ret)
14381433 }
14391434 }
14401435}
@@ -1523,9 +1518,7 @@ impl<'a, T> Iterator for Chunks<'a, T> {
15231518 if self . v . is_empty ( ) {
15241519 ( 0 , Some ( 0 ) )
15251520 } else {
1526- let n = self . v . len ( ) / self . chunk_size ;
1527- let rem = self . v . len ( ) % self . chunk_size ;
1528- let n = if rem > 0 { n + 1 } else { n } ;
1521+ let n = self . v . len ( ) . div_ceil ( self . chunk_size ) ;
15291522 ( n, Some ( n) )
15301523 }
15311524 }
@@ -1613,7 +1606,7 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
16131606 None
16141607 } else {
16151608 let start = ( len - 1 - n) * self . chunk_size ;
1616- let end = ( start + self . chunk_size ) . min ( self . v . len ( ) ) ;
1609+ let end = start + ( self . v . len ( ) - start ) . min ( self . chunk_size ) ;
16171610 let nth_back = & self . v [ start..end] ;
16181611 self . v = & self . v [ ..start] ;
16191612 Some ( nth_back)
@@ -1702,9 +1695,7 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
17021695 if self . v . is_empty ( ) {
17031696 ( 0 , Some ( 0 ) )
17041697 } else {
1705- let n = self . v . len ( ) / self . chunk_size ;
1706- let rem = self . v . len ( ) % self . chunk_size ;
1707- let n = if rem > 0 { n + 1 } else { n } ;
1698+ let n = self . v . len ( ) . div_ceil ( self . chunk_size ) ;
17081699 ( n, Some ( n) )
17091700 }
17101701 }
@@ -1903,13 +1894,10 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19031894
19041895 #[ inline]
19051896 fn next ( & mut self ) -> Option < & ' a [ T ] > {
1906- if self . v . len ( ) < self . chunk_size {
1907- None
1908- } else {
1909- let ( fst, snd) = self . v . split_at ( self . chunk_size ) ;
1910- self . v = snd;
1911- Some ( fst)
1912- }
1897+ self . v . split_at_checked ( self . chunk_size ) . and_then ( |( chunk, rest) | {
1898+ self . v = rest;
1899+ Some ( chunk)
1900+ } )
19131901 }
19141902
19151903 #[ inline]
@@ -1925,14 +1913,14 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19251913
19261914 #[ inline]
19271915 fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
1928- let ( start, overflow) = n. overflowing_mul ( self . chunk_size ) ;
1929- if start >= self . v . len ( ) || overflow {
1916+ if let Some ( start) = n. checked_mul ( self . chunk_size )
1917+ && start < self . v . len ( )
1918+ {
1919+ self . v = & self . v [ start..] ;
1920+ self . next ( )
1921+ } else {
19301922 self . v = & self . v [ ..0 ] ; // cheaper than &[]
19311923 None
1932- } else {
1933- let ( _, snd) = self . v . split_at ( start) ;
1934- self . v = snd;
1935- self . next ( )
19361924 }
19371925 }
19381926
@@ -2061,15 +2049,11 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20612049
20622050 #[ inline]
20632051 fn next ( & mut self ) -> Option < & ' a mut [ T ] > {
2064- if self . v . len ( ) < self . chunk_size {
2065- None
2066- } else {
2067- // SAFETY: self.chunk_size is inbounds because we compared above against self.v.len()
2068- let ( head, tail) = unsafe { self . v . split_at_mut ( self . chunk_size ) } ;
2069- self . v = tail;
2070- // SAFETY: Nothing else points to or will point to the contents of this slice.
2071- Some ( unsafe { & mut * head } )
2072- }
2052+ // SAFETY: we have `&mut self`, so are allowed to temporarily materialize a mut slice
2053+ unsafe { & mut * self . v } . split_at_mut_checked ( self . chunk_size ) . and_then ( |( chunk, rest) | {
2054+ self . v = rest;
2055+ Some ( chunk)
2056+ } )
20732057 }
20742058
20752059 #[ inline]
@@ -2085,15 +2069,15 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20852069
20862070 #[ inline]
20872071 fn nth ( & mut self , n : usize ) -> Option < & ' a mut [ T ] > {
2088- let ( start, overflow) = n. overflowing_mul ( self . chunk_size ) ;
2089- if start >= self . v . len ( ) || overflow {
2072+ if let Some ( start) = n. checked_mul ( self . chunk_size )
2073+ && start < self . v . len ( )
2074+ {
2075+ // SAFETY: `start < self.v.len()`
2076+ self . v = unsafe { self . v . split_at_mut ( start) . 1 } ;
2077+ self . next ( )
2078+ } else {
20902079 self . v = & mut [ ] ;
20912080 None
2092- } else {
2093- // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2094- let ( _, snd) = unsafe { self . v . split_at_mut ( start) } ;
2095- self . v = snd;
2096- self . next ( )
20972081 }
20982082 }
20992083
@@ -2341,9 +2325,7 @@ impl<'a, T> Iterator for RChunks<'a, T> {
23412325 if self . v . is_empty ( ) {
23422326 ( 0 , Some ( 0 ) )
23432327 } else {
2344- let n = self . v . len ( ) / self . chunk_size ;
2345- let rem = self . v . len ( ) % self . chunk_size ;
2346- let n = if rem > 0 { n + 1 } else { n } ;
2328+ let n = self . v . len ( ) . div_ceil ( self . chunk_size ) ;
23472329 ( n, Some ( n) )
23482330 }
23492331 }
@@ -2355,17 +2337,17 @@ impl<'a, T> Iterator for RChunks<'a, T> {
23552337
23562338 #[ inline]
23572339 fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
2358- let ( end, overflow) = n. overflowing_mul ( self . chunk_size ) ;
2359- if end >= self . v . len ( ) || overflow {
2340+ if let Some ( end) = n. checked_mul ( self . chunk_size )
2341+ && end < self . v . len ( )
2342+ {
2343+ let end = self . v . len ( ) - end;
2344+ let rest = & self . v [ ..end] ;
2345+ let ( rest, chunk) = rest. split_at ( end. saturating_sub ( self . chunk_size ) ) ;
2346+ self . v = rest;
2347+ Some ( chunk)
2348+ } else {
23602349 self . v = & self . v [ ..0 ] ; // cheaper than &[]
23612350 None
2362- } else {
2363- // Can't underflow because of the check above
2364- let end = self . v . len ( ) - end;
2365- let start = end. saturating_sub ( self . chunk_size ) ;
2366- let nth = & self . v [ start..end] ;
2367- self . v = & self . v [ 0 ..start] ;
2368- Some ( nth)
23692351 }
23702352 }
23712353
@@ -2508,9 +2490,7 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
25082490 if self . v . is_empty ( ) {
25092491 ( 0 , Some ( 0 ) )
25102492 } else {
2511- let n = self . v . len ( ) / self . chunk_size ;
2512- let rem = self . v . len ( ) % self . chunk_size ;
2513- let n = if rem > 0 { n + 1 } else { n } ;
2493+ let n = self . v . len ( ) . div_ceil ( self . chunk_size ) ;
25142494 ( n, Some ( n) )
25152495 }
25162496 }
0 commit comments