@@ -485,6 +485,39 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
485
485
}
486
486
}
487
487
488
+ impl < I > StepBy < I > where I : ExactSizeIterator {
489
+ // The zero-based index starting from the end of the iterator of the
490
+ // last element. Used in the `DoubleEndedIterator` implementation.
491
+ fn next_back_index ( & self ) -> usize {
492
+ let rem = self . iter . len ( ) % ( self . step + 1 ) ;
493
+ if self . first_take {
494
+ if rem == 0 { self . step } else { rem - 1 }
495
+ } else {
496
+ rem
497
+ }
498
+ }
499
+ }
500
+
501
+ #[ stable( feature = "double_ended_step_by_iterator" , since = "1.38.0" ) ]
502
+ impl < I > DoubleEndedIterator for StepBy < I > where I : DoubleEndedIterator + ExactSizeIterator {
503
+ #[ inline]
504
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
505
+ self . iter . nth_back ( self . next_back_index ( ) )
506
+ }
507
+
508
+ #[ inline]
509
+ fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
510
+ // `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
511
+ // is out of bounds because the length of `self.iter` does not exceed
512
+ // `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
513
+ // zero-indexed
514
+ let n = n
515
+ . saturating_mul ( self . step + 1 )
516
+ . saturating_add ( self . next_back_index ( ) ) ;
517
+ self . iter . nth_back ( n)
518
+ }
519
+ }
520
+
488
521
// StepBy can only make the iterator shorter, so the len will still fit.
489
522
#[ stable( feature = "iterator_step_by" , since = "1.28.0" ) ]
490
523
impl < I > ExactSizeIterator for StepBy < I > where I : ExactSizeIterator { }
@@ -1158,6 +1191,45 @@ impl<I: Iterator> Iterator for Peekable<I> {
1158
1191
}
1159
1192
}
1160
1193
1194
+ #[ stable( feature = "double_ended_peek_iterator" , since = "1.38.0" ) ]
1195
+ impl < I > DoubleEndedIterator for Peekable < I > where I : DoubleEndedIterator {
1196
+ #[ inline]
1197
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
1198
+ self . iter . next_back ( ) . or_else ( || self . peeked . take ( ) . and_then ( |x| x) )
1199
+ }
1200
+
1201
+ #[ inline]
1202
+ fn try_rfold < B , F , R > ( & mut self , init : B , mut f : F ) -> R where
1203
+ Self : Sized , F : FnMut ( B , Self :: Item ) -> R , R : Try < Ok =B >
1204
+ {
1205
+ match self . peeked . take ( ) {
1206
+ Some ( None ) => return Try :: from_ok ( init) ,
1207
+ Some ( Some ( v) ) => match self . iter . try_rfold ( init, & mut f) . into_result ( ) {
1208
+ Ok ( acc) => f ( acc, v) ,
1209
+ Err ( e) => {
1210
+ self . peeked = Some ( Some ( v) ) ;
1211
+ Try :: from_error ( e)
1212
+ }
1213
+ } ,
1214
+ None => self . iter . try_rfold ( init, f) ,
1215
+ }
1216
+ }
1217
+
1218
+ #[ inline]
1219
+ fn rfold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
1220
+ where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
1221
+ {
1222
+ match self . peeked {
1223
+ Some ( None ) => return init,
1224
+ Some ( Some ( v) ) => {
1225
+ let acc = self . iter . rfold ( init, & mut fold) ;
1226
+ fold ( acc, v)
1227
+ }
1228
+ None => self . iter . rfold ( init, fold) ,
1229
+ }
1230
+ }
1231
+ }
1232
+
1161
1233
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1162
1234
impl < I : ExactSizeIterator > ExactSizeIterator for Peekable < I > { }
1163
1235
@@ -1627,6 +1699,51 @@ impl<I> Iterator for Take<I> where I: Iterator{
1627
1699
}
1628
1700
}
1629
1701
1702
+ #[ stable( feature = "double_ended_take_iterator" , since = "1.38.0" ) ]
1703
+ impl < I > DoubleEndedIterator for Take < I > where I : DoubleEndedIterator + ExactSizeIterator {
1704
+ #[ inline]
1705
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
1706
+ if self . n == 0 {
1707
+ None
1708
+ } else {
1709
+ let n = self . n ;
1710
+ self . n -= 1 ;
1711
+ self . iter . nth_back ( self . iter . len ( ) . saturating_sub ( n) )
1712
+ }
1713
+ }
1714
+
1715
+ #[ inline]
1716
+ fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
1717
+ let len = self . iter . len ( ) ;
1718
+ if self . n > n {
1719
+ let m = len. saturating_sub ( self . n ) + n;
1720
+ self . n -= n + 1 ;
1721
+ self . iter . nth_back ( m)
1722
+ } else {
1723
+ if len > 0 {
1724
+ self . iter . nth_back ( len - 1 ) ;
1725
+ }
1726
+ None
1727
+ }
1728
+ }
1729
+
1730
+ #[ inline]
1731
+ fn try_rfold < Acc , Fold , R > ( & mut self , init : Acc , fold : Fold ) -> R where
1732
+ Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok = Acc >
1733
+ {
1734
+ if self . n == 0 {
1735
+ Try :: from_ok ( init)
1736
+ } else {
1737
+ let len = self . iter . len ( ) ;
1738
+ if len > self . n && self . iter . nth_back ( len - self . n - 1 ) . is_none ( ) {
1739
+ Try :: from_ok ( init)
1740
+ } else {
1741
+ self . iter . try_rfold ( init, fold)
1742
+ }
1743
+ }
1744
+ }
1745
+ }
1746
+
1630
1747
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1631
1748
impl < I > ExactSizeIterator for Take < I > where I : ExactSizeIterator { }
1632
1749
0 commit comments