@@ -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
@@ -1613,6 +1685,51 @@ impl<I> Iterator for Take<I> where I: Iterator{
1613
1685
}
1614
1686
}
1615
1687
1688
+ #[ stable( feature = "double_ended_take_iterator" , since = "1.38.0" ) ]
1689
+ impl < I > DoubleEndedIterator for Take < I > where I : DoubleEndedIterator + ExactSizeIterator {
1690
+ #[ inline]
1691
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
1692
+ if self . n == 0 {
1693
+ None
1694
+ } else {
1695
+ let n = self . n ;
1696
+ self . n -= 1 ;
1697
+ self . iter . nth_back ( self . iter . len ( ) . saturating_sub ( n) )
1698
+ }
1699
+ }
1700
+
1701
+ #[ inline]
1702
+ fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
1703
+ let len = self . iter . len ( ) ;
1704
+ if self . n > n {
1705
+ let m = len. saturating_sub ( self . n ) + n;
1706
+ self . n -= n + 1 ;
1707
+ self . iter . nth_back ( m)
1708
+ } else {
1709
+ if len > 0 {
1710
+ self . iter . nth_back ( len - 1 ) ;
1711
+ }
1712
+ None
1713
+ }
1714
+ }
1715
+
1716
+ #[ inline]
1717
+ fn try_rfold < Acc , Fold , R > ( & mut self , init : Acc , fold : Fold ) -> R where
1718
+ Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok = Acc >
1719
+ {
1720
+ if self . n == 0 {
1721
+ Try :: from_ok ( init)
1722
+ } else {
1723
+ let len = self . iter . len ( ) ;
1724
+ if len > self . n && self . iter . nth_back ( len - self . n - 1 ) . is_none ( ) {
1725
+ Try :: from_ok ( init)
1726
+ } else {
1727
+ self . iter . try_rfold ( init, fold)
1728
+ }
1729
+ }
1730
+ }
1731
+ }
1732
+
1616
1733
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1617
1734
impl < I > ExactSizeIterator for Take < I > where I : ExactSizeIterator { }
1618
1735
0 commit comments