@@ -1380,14 +1380,16 @@ impl<'a, T> Iterator for Windows<'a, T> {
13801380
13811381 #[ inline]
13821382 fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
1383- let ( end, overflow) = self . size . get ( ) . overflowing_add ( n) ;
1384- if end > self . v . len ( ) || overflow {
1385- self . v = & [ ] ;
1386- None
1387- } else {
1388- let nth = & self . v [ n..end] ;
1389- self . v = & self . v [ n + 1 ..] ;
1383+ let size = self . size . get ( ) ;
1384+ if let Some ( rest) = self . v . get ( n..)
1385+ && let Some ( nth) = rest. get ( ..size)
1386+ {
1387+ self . v = & rest[ 1 ..] ;
13901388 Some ( nth)
1389+ } else {
1390+ // setting length to 0 is cheaper than overwriting the pointer when assigning &[]
1391+ self . v = & self . v [ ..0 ] ; // cheaper than &[]
1392+ None
13911393 }
13921394 }
13931395
@@ -1427,7 +1429,7 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
14271429 fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
14281430 let ( end, overflow) = self . v . len ( ) . overflowing_sub ( n) ;
14291431 if end < self . size . get ( ) || overflow {
1430- self . v = & [ ] ;
1432+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
14311433 None
14321434 } else {
14331435 let ret = & self . v [ end - self . size . get ( ) ..end] ;
@@ -1536,17 +1538,15 @@ impl<'a, T> Iterator for Chunks<'a, T> {
15361538 #[ inline]
15371539 fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
15381540 let ( start, overflow) = n. overflowing_mul ( self . chunk_size ) ;
1539- if start >= self . v . len ( ) || overflow {
1540- self . v = & [ ] ;
1541- None
1542- } else {
1543- let end = match start. checked_add ( self . chunk_size ) {
1544- Some ( sum) => cmp:: min ( self . v . len ( ) , sum) ,
1545- None => self . v . len ( ) ,
1546- } ;
1547- let nth = & self . v [ start..end] ;
1548- self . v = & self . v [ end..] ;
1541+ // min(len) makes a wrong start harmless, but enables optimizing this to brachless code
1542+ let chunk_start = & self . v [ start. min ( self . v . len ( ) ) ..] ;
1543+ let ( nth, remainder) = chunk_start. split_at ( self . chunk_size . min ( chunk_start. len ( ) ) ) ;
1544+ if !overflow && start < self . v . len ( ) {
1545+ self . v = remainder;
15491546 Some ( nth)
1547+ } else {
1548+ self . v = & self . v [ ..0 ] ; // cheaper than &[]
1549+ None
15501550 }
15511551 }
15521552
@@ -1609,7 +1609,7 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
16091609 fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
16101610 let len = self . len ( ) ;
16111611 if n >= len {
1612- self . v = & [ ] ;
1612+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
16131613 None
16141614 } else {
16151615 let start = ( len - 1 - n) * self . chunk_size ;
@@ -1933,7 +1933,7 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19331933 fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
19341934 let ( start, overflow) = n. overflowing_mul ( self . chunk_size ) ;
19351935 if start >= self . v . len ( ) || overflow {
1936- self . v = & [ ] ;
1936+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
19371937 None
19381938 } else {
19391939 let ( _, snd) = self . v . split_at ( start) ;
@@ -1971,7 +1971,7 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
19711971 fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
19721972 let len = self . len ( ) ;
19731973 if n >= len {
1974- self . v = & [ ] ;
1974+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
19751975 None
19761976 } else {
19771977 let start = ( len - 1 - n) * self . chunk_size ;
@@ -2638,7 +2638,7 @@ impl<'a, T> Iterator for RChunks<'a, T> {
26382638 fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
26392639 let ( end, overflow) = n. overflowing_mul ( self . chunk_size ) ;
26402640 if end >= self . v . len ( ) || overflow {
2641- self . v = & [ ] ;
2641+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
26422642 None
26432643 } else {
26442644 // Can't underflow because of the check above
@@ -2695,7 +2695,7 @@ impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
26952695 fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
26962696 let len = self . len ( ) ;
26972697 if n >= len {
2698- self . v = & [ ] ;
2698+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
26992699 None
27002700 } else {
27012701 // can't underflow because `n < len`
@@ -3023,7 +3023,7 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
30233023 fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
30243024 let ( end, overflow) = n. overflowing_mul ( self . chunk_size ) ;
30253025 if end >= self . v . len ( ) || overflow {
3026- self . v = & [ ] ;
3026+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
30273027 None
30283028 } else {
30293029 let ( fst, _) = self . v . split_at ( self . v . len ( ) - end) ;
@@ -3062,7 +3062,7 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
30623062 fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
30633063 let len = self . len ( ) ;
30643064 if n >= len {
3065- self . v = & [ ] ;
3065+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
30663066 None
30673067 } else {
30683068 // now that we know that `n` corresponds to a chunk,
0 commit comments