@@ -485,6 +485,39 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
485485 }
486486}
487487
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+
488521// StepBy can only make the iterator shorter, so the len will still fit.
489522#[ stable( feature = "iterator_step_by" , since = "1.28.0" ) ]
490523impl < I > ExactSizeIterator for StepBy < I > where I : ExactSizeIterator { }
@@ -1158,6 +1191,45 @@ impl<I: Iterator> Iterator for Peekable<I> {
11581191 }
11591192}
11601193
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+
11611233#[ stable( feature = "rust1" , since = "1.0.0" ) ]
11621234impl < I : ExactSizeIterator > ExactSizeIterator for Peekable < I > { }
11631235
@@ -1613,6 +1685,51 @@ impl<I> Iterator for Take<I> where I: Iterator{
16131685 }
16141686}
16151687
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+
16161733#[ stable( feature = "rust1" , since = "1.0.0" ) ]
16171734impl < I > ExactSizeIterator for Take < I > where I : ExactSizeIterator { }
16181735
0 commit comments