@@ -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 ( ) - 1 ) / self . chunk_size + 1 ;
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)
@@ -1903,13 +1896,10 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19031896
19041897 #[ inline]
19051898 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- }
1899+ self . v . split_at_checked ( self . chunk_size ) . and_then ( |( chunk, rest) | {
1900+ self . v = rest;
1901+ Some ( chunk)
1902+ } )
19131903 }
19141904
19151905 #[ inline]
@@ -1925,14 +1915,14 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19251915
19261916 #[ inline]
19271917 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 {
1918+ if let Some ( start) = n. checked_mul ( self . chunk_size )
1919+ && start < self . v . len ( )
1920+ {
1921+ self . v = & self . v [ start..] ;
1922+ self . next ( )
1923+ } else {
19301924 self . v = & self . v [ ..0 ] ; // cheaper than &[]
19311925 None
1932- } else {
1933- let ( _, snd) = self . v . split_at ( start) ;
1934- self . v = snd;
1935- self . next ( )
19361926 }
19371927 }
19381928
@@ -2061,15 +2051,11 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20612051
20622052 #[ inline]
20632053 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- }
2054+ // SAFETY: we have `&mut self`, so are allowed to temporarily materialize a mut slice
2055+ unsafe { & mut * self . v } . split_at_mut_checked ( self . chunk_size ) . and_then ( |( chunk, rest) | {
2056+ self . v = rest;
2057+ Some ( chunk)
2058+ } )
20732059 }
20742060
20752061 #[ inline]
@@ -2085,15 +2071,15 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20852071
20862072 #[ inline]
20872073 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 {
2074+ if let Some ( start) = n. checked_mul ( self . chunk_size )
2075+ && start < self . v . len ( )
2076+ {
2077+ // SAFETY: `start < self.v.len()`
2078+ self . v = unsafe { self . v . split_at_mut ( start) . 1 } ;
2079+ self . next ( )
2080+ } else {
20902081 self . v = & mut [ ] ;
20912082 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 ( )
20972083 }
20982084 }
20992085
0 commit comments