@@ -108,6 +108,11 @@ where
108108 {
109109 self . inner . rfold ( init, fold)
110110 }
111+
112+ #[ inline]
113+ fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , usize > {
114+ self . inner . advance_back_by ( n)
115+ }
111116}
112117
113118#[ stable( feature = "fused" , since = "1.26.0" ) ]
@@ -254,6 +259,11 @@ where
254259 {
255260 self . inner . rfold ( init, fold)
256261 }
262+
263+ #[ inline]
264+ fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , usize > {
265+ self . inner . advance_back_by ( n)
266+ }
257267}
258268
259269#[ stable( feature = "iterator_flatten" , since = "1.29.0" ) ]
@@ -330,6 +340,46 @@ where
330340 }
331341}
332342
343+ impl < I , U > FlattenCompat < I , U >
344+ where
345+ I : DoubleEndedIterator < Item : IntoIterator < IntoIter = U > > ,
346+ {
347+ /// Folds over the inner iterators in reverse order as long as the given function returns
348+ /// successfully, always storing the most recent inner iterator in `self.backiter`.
349+ ///
350+ /// Folds over the inner iterators, not over their elements. Is used by the `try_rfold` and
351+ /// `advance_back_by` methods.
352+ #[ inline]
353+ fn iter_try_rfold < Acc , Fold , R > ( & mut self , mut acc : Acc , mut fold : Fold ) -> R
354+ where
355+ Fold : FnMut ( Acc , & mut U ) -> R ,
356+ R : Try < Output = Acc > ,
357+ {
358+ #[ inline]
359+ fn flatten < ' a , T : IntoIterator , Acc , R : Try > (
360+ backiter : & ' a mut Option < T :: IntoIter > ,
361+ fold : & ' a mut impl FnMut ( Acc , & mut T :: IntoIter ) -> R ,
362+ ) -> impl FnMut ( Acc , T ) -> R + ' a {
363+ move |acc, iter| fold ( acc, backiter. insert ( iter. into_iter ( ) ) )
364+ }
365+
366+ if let Some ( iter) = & mut self . backiter {
367+ acc = fold ( acc, iter) ?;
368+ }
369+ self . backiter = None ;
370+
371+ acc = self . iter . try_rfold ( acc, flatten ( & mut self . backiter , & mut fold) ) ?;
372+ self . backiter = None ;
373+
374+ if let Some ( iter) = & mut self . frontiter {
375+ acc = fold ( acc, iter) ?;
376+ }
377+ self . frontiter = None ;
378+
379+ try { acc }
380+ }
381+ }
382+
333383impl < I , U > Iterator for FlattenCompat < I , U >
334384where
335385 I : Iterator < Item : IntoIterator < IntoIter = U , Item = U :: Item > > ,
@@ -452,42 +502,20 @@ where
452502 }
453503
454504 #[ inline]
455- fn try_rfold < Acc , Fold , R > ( & mut self , mut init : Acc , mut fold : Fold ) -> R
505+ fn try_rfold < Acc , Fold , R > ( & mut self , init : Acc , fold : Fold ) -> R
456506 where
457507 Self : Sized ,
458508 Fold : FnMut ( Acc , Self :: Item ) -> R ,
459509 R : Try < Output = Acc > ,
460510 {
461511 #[ inline]
462- fn flatten < ' a , T : IntoIterator , Acc , R : Try < Output = Acc > > (
463- backiter : & ' a mut Option < T :: IntoIter > ,
464- fold : & ' a mut impl FnMut ( Acc , T :: Item ) -> R ,
465- ) -> impl FnMut ( Acc , T ) -> R + ' a
466- where
467- T :: IntoIter : DoubleEndedIterator ,
468- {
469- move |acc, x| {
470- let mut mid = x. into_iter ( ) ;
471- let r = mid. try_rfold ( acc, & mut * fold) ;
472- * backiter = Some ( mid) ;
473- r
474- }
475- }
476-
477- if let Some ( ref mut back) = self . backiter {
478- init = back. try_rfold ( init, & mut fold) ?;
479- }
480- self . backiter = None ;
481-
482- init = self . iter . try_rfold ( init, flatten ( & mut self . backiter , & mut fold) ) ?;
483- self . backiter = None ;
484-
485- if let Some ( ref mut front) = self . frontiter {
486- init = front. try_rfold ( init, & mut fold) ?;
512+ fn flatten < U : DoubleEndedIterator , Acc , R : Try < Output = Acc > > (
513+ mut fold : impl FnMut ( Acc , U :: Item ) -> R ,
514+ ) -> impl FnMut ( Acc , & mut U ) -> R {
515+ move |acc, iter| iter. try_rfold ( acc, & mut fold)
487516 }
488- self . frontiter = None ;
489517
490- try { init }
518+ self . iter_try_rfold ( init, flatten ( fold ) )
491519 }
492520
493521 #[ inline]
@@ -521,36 +549,19 @@ where
521549 #[ inline]
522550 #[ rustc_inherit_overflow_checks]
523551 fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , usize > {
524- let mut rem = n;
525- loop {
526- if let Some ( ref mut back) = self . backiter {
527- match back. advance_back_by ( rem) {
528- ret @ Ok ( _) => return ret,
529- Err ( advanced) => rem -= advanced,
530- }
531- }
532- match self . iter . next_back ( ) {
533- Some ( iterable) => self . backiter = Some ( iterable. into_iter ( ) ) ,
534- _ => break ,
535- }
536- }
537-
538- self . backiter = None ;
539-
540- if let Some ( ref mut front) = self . frontiter {
541- match front. advance_back_by ( rem) {
542- ret @ Ok ( _) => return ret,
543- Err ( advanced) => rem -= advanced,
552+ #[ inline]
553+ #[ rustc_inherit_overflow_checks]
554+ fn advance < U : DoubleEndedIterator > ( n : usize , iter : & mut U ) -> ControlFlow < ( ) , usize > {
555+ match iter. advance_back_by ( n) {
556+ Ok ( ( ) ) => ControlFlow :: BREAK ,
557+ Err ( advanced) => ControlFlow :: Continue ( n - advanced) ,
544558 }
545559 }
546560
547- if rem > 0 {
548- return Err ( n - rem) ;
561+ match self . iter_try_rfold ( n, advance) {
562+ ControlFlow :: Continue ( remaining) if remaining > 0 => Err ( n - remaining) ,
563+ _ => Ok ( ( ) ) ,
549564 }
550-
551- self . frontiter = None ;
552-
553- Ok ( ( ) )
554565 }
555566}
556567
0 commit comments