@@ -108,6 +108,11 @@ where
108
108
{
109
109
self . inner . rfold ( init, fold)
110
110
}
111
+
112
+ #[ inline]
113
+ fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , usize > {
114
+ self . inner . advance_back_by ( n)
115
+ }
111
116
}
112
117
113
118
#[ stable( feature = "fused" , since = "1.26.0" ) ]
@@ -254,6 +259,11 @@ where
254
259
{
255
260
self . inner . rfold ( init, fold)
256
261
}
262
+
263
+ #[ inline]
264
+ fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , usize > {
265
+ self . inner . advance_back_by ( n)
266
+ }
257
267
}
258
268
259
269
#[ stable( feature = "iterator_flatten" , since = "1.29.0" ) ]
@@ -330,6 +340,46 @@ where
330
340
}
331
341
}
332
342
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
+
333
383
impl < I , U > Iterator for FlattenCompat < I , U >
334
384
where
335
385
I : Iterator < Item : IntoIterator < IntoIter = U , Item = U :: Item > > ,
@@ -452,42 +502,20 @@ where
452
502
}
453
503
454
504
#[ 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
456
506
where
457
507
Self : Sized ,
458
508
Fold : FnMut ( Acc , Self :: Item ) -> R ,
459
509
R : Try < Output = Acc > ,
460
510
{
461
511
#[ 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)
487
516
}
488
- self . frontiter = None ;
489
517
490
- try { init }
518
+ self . iter_try_rfold ( init, flatten ( fold ) )
491
519
}
492
520
493
521
#[ inline]
@@ -521,36 +549,19 @@ where
521
549
#[ inline]
522
550
#[ rustc_inherit_overflow_checks]
523
551
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) ,
544
558
}
545
559
}
546
560
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 ( ( ) ) ,
549
564
}
550
-
551
- self . frontiter = None ;
552
-
553
- Ok ( ( ) )
554
565
}
555
566
}
556
567
0 commit comments