@@ -1380,14 +1380,16 @@ impl<'a, T> Iterator for Windows<'a, T> {
1380
1380
1381
1381
#[ inline]
1382
1382
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 ..] ;
1390
1388
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
1391
1393
}
1392
1394
}
1393
1395
@@ -1427,7 +1429,7 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
1427
1429
fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
1428
1430
let ( end, overflow) = self . v . len ( ) . overflowing_sub ( n) ;
1429
1431
if end < self . size . get ( ) || overflow {
1430
- self . v = & [ ] ;
1432
+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
1431
1433
None
1432
1434
} else {
1433
1435
let ret = & self . v [ end - self . size . get ( ) ..end] ;
@@ -1536,17 +1538,15 @@ impl<'a, T> Iterator for Chunks<'a, T> {
1536
1538
#[ inline]
1537
1539
fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
1538
1540
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;
1549
1546
Some ( nth)
1547
+ } else {
1548
+ self . v = & self . v [ ..0 ] ; // cheaper than &[]
1549
+ None
1550
1550
}
1551
1551
}
1552
1552
@@ -1609,7 +1609,7 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
1609
1609
fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
1610
1610
let len = self . len ( ) ;
1611
1611
if n >= len {
1612
- self . v = & [ ] ;
1612
+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
1613
1613
None
1614
1614
} else {
1615
1615
let start = ( len - 1 - n) * self . chunk_size ;
@@ -1933,7 +1933,7 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
1933
1933
fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
1934
1934
let ( start, overflow) = n. overflowing_mul ( self . chunk_size ) ;
1935
1935
if start >= self . v . len ( ) || overflow {
1936
- self . v = & [ ] ;
1936
+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
1937
1937
None
1938
1938
} else {
1939
1939
let ( _, snd) = self . v . split_at ( start) ;
@@ -1971,7 +1971,7 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
1971
1971
fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
1972
1972
let len = self . len ( ) ;
1973
1973
if n >= len {
1974
- self . v = & [ ] ;
1974
+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
1975
1975
None
1976
1976
} else {
1977
1977
let start = ( len - 1 - n) * self . chunk_size ;
@@ -2638,7 +2638,7 @@ impl<'a, T> Iterator for RChunks<'a, T> {
2638
2638
fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
2639
2639
let ( end, overflow) = n. overflowing_mul ( self . chunk_size ) ;
2640
2640
if end >= self . v . len ( ) || overflow {
2641
- self . v = & [ ] ;
2641
+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
2642
2642
None
2643
2643
} else {
2644
2644
// Can't underflow because of the check above
@@ -2695,7 +2695,7 @@ impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
2695
2695
fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
2696
2696
let len = self . len ( ) ;
2697
2697
if n >= len {
2698
- self . v = & [ ] ;
2698
+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
2699
2699
None
2700
2700
} else {
2701
2701
// can't underflow because `n < len`
@@ -3023,7 +3023,7 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
3023
3023
fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
3024
3024
let ( end, overflow) = n. overflowing_mul ( self . chunk_size ) ;
3025
3025
if end >= self . v . len ( ) || overflow {
3026
- self . v = & [ ] ;
3026
+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
3027
3027
None
3028
3028
} else {
3029
3029
let ( fst, _) = self . v . split_at ( self . v . len ( ) - end) ;
@@ -3062,7 +3062,7 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
3062
3062
fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
3063
3063
let len = self . len ( ) ;
3064
3064
if n >= len {
3065
- self . v = & [ ] ;
3065
+ self . v = & self . v [ .. 0 ] ; // cheaper than &[]
3066
3066
None
3067
3067
} else {
3068
3068
// now that we know that `n` corresponds to a chunk,
0 commit comments