@@ -3461,36 +3461,27 @@ pub trait Iterator {
3461
3461
/// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
3462
3462
/// ```
3463
3463
#[ unstable( feature = "iter_order_by" , issue = "64295" ) ]
3464
- fn cmp_by < I , F > ( mut self , other : I , mut cmp : F ) -> Ordering
3464
+ fn cmp_by < I , F > ( self , other : I , cmp : F ) -> Ordering
3465
3465
where
3466
3466
Self : Sized ,
3467
3467
I : IntoIterator ,
3468
3468
F : FnMut ( Self :: Item , I :: Item ) -> Ordering ,
3469
3469
{
3470
- let mut other = other. into_iter ( ) ;
3471
-
3472
- loop {
3473
- let x = match self . next ( ) {
3474
- None => {
3475
- if other. next ( ) . is_none ( ) {
3476
- return Ordering :: Equal ;
3477
- } else {
3478
- return Ordering :: Less ;
3479
- }
3480
- }
3481
- Some ( val) => val,
3482
- } ;
3483
-
3484
- let y = match other. next ( ) {
3485
- None => return Ordering :: Greater ,
3486
- Some ( val) => val,
3487
- } ;
3488
-
3489
- match cmp ( x, y) {
3490
- Ordering :: Equal => ( ) ,
3491
- non_eq => return non_eq,
3470
+ #[ inline]
3471
+ fn compare < X , Y , F > ( mut cmp : F ) -> impl FnMut ( X , Y ) -> ControlFlow < Ordering >
3472
+ where
3473
+ F : FnMut ( X , Y ) -> Ordering ,
3474
+ {
3475
+ move |x, y| match cmp ( x, y) {
3476
+ Ordering :: Equal => ControlFlow :: CONTINUE ,
3477
+ non_eq => ControlFlow :: Break ( non_eq) ,
3492
3478
}
3493
3479
}
3480
+
3481
+ match iter_compare ( self , other. into_iter ( ) , compare ( cmp) ) {
3482
+ ControlFlow :: Continue ( ord) => ord,
3483
+ ControlFlow :: Break ( ord) => ord,
3484
+ }
3494
3485
}
3495
3486
3496
3487
/// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those
@@ -3546,36 +3537,27 @@ pub trait Iterator {
3546
3537
/// );
3547
3538
/// ```
3548
3539
#[ unstable( feature = "iter_order_by" , issue = "64295" ) ]
3549
- fn partial_cmp_by < I , F > ( mut self , other : I , mut partial_cmp : F ) -> Option < Ordering >
3540
+ fn partial_cmp_by < I , F > ( self , other : I , partial_cmp : F ) -> Option < Ordering >
3550
3541
where
3551
3542
Self : Sized ,
3552
3543
I : IntoIterator ,
3553
3544
F : FnMut ( Self :: Item , I :: Item ) -> Option < Ordering > ,
3554
3545
{
3555
- let mut other = other. into_iter ( ) ;
3556
-
3557
- loop {
3558
- let x = match self . next ( ) {
3559
- None => {
3560
- if other. next ( ) . is_none ( ) {
3561
- return Some ( Ordering :: Equal ) ;
3562
- } else {
3563
- return Some ( Ordering :: Less ) ;
3564
- }
3565
- }
3566
- Some ( val) => val,
3567
- } ;
3568
-
3569
- let y = match other. next ( ) {
3570
- None => return Some ( Ordering :: Greater ) ,
3571
- Some ( val) => val,
3572
- } ;
3573
-
3574
- match partial_cmp ( x, y) {
3575
- Some ( Ordering :: Equal ) => ( ) ,
3576
- non_eq => return non_eq,
3546
+ #[ inline]
3547
+ fn compare < X , Y , F > ( mut partial_cmp : F ) -> impl FnMut ( X , Y ) -> ControlFlow < Option < Ordering > >
3548
+ where
3549
+ F : FnMut ( X , Y ) -> Option < Ordering > ,
3550
+ {
3551
+ move |x, y| match partial_cmp ( x, y) {
3552
+ Some ( Ordering :: Equal ) => ControlFlow :: CONTINUE ,
3553
+ non_eq => ControlFlow :: Break ( non_eq) ,
3577
3554
}
3578
3555
}
3556
+
3557
+ match iter_compare ( self , other. into_iter ( ) , compare ( partial_cmp) ) {
3558
+ ControlFlow :: Continue ( ord) => Some ( ord) ,
3559
+ ControlFlow :: Break ( ord) => ord,
3560
+ }
3579
3561
}
3580
3562
3581
3563
/// Determines if the elements of this [`Iterator`] are equal to those of
@@ -3613,29 +3595,26 @@ pub trait Iterator {
3613
3595
/// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y));
3614
3596
/// ```
3615
3597
#[ unstable( feature = "iter_order_by" , issue = "64295" ) ]
3616
- fn eq_by < I , F > ( mut self , other : I , mut eq : F ) -> bool
3598
+ fn eq_by < I , F > ( self , other : I , eq : F ) -> bool
3617
3599
where
3618
3600
Self : Sized ,
3619
3601
I : IntoIterator ,
3620
3602
F : FnMut ( Self :: Item , I :: Item ) -> bool ,
3621
3603
{
3622
- let mut other = other. into_iter ( ) ;
3623
-
3624
- loop {
3625
- let x = match self . next ( ) {
3626
- None => return other. next ( ) . is_none ( ) ,
3627
- Some ( val) => val,
3628
- } ;
3629
-
3630
- let y = match other. next ( ) {
3631
- None => return false ,
3632
- Some ( val) => val,
3633
- } ;
3634
-
3635
- if !eq ( x, y) {
3636
- return false ;
3604
+ #[ inline]
3605
+ fn compare < X , Y , F > ( mut eq : F ) -> impl FnMut ( X , Y ) -> ControlFlow < ( ) >
3606
+ where
3607
+ F : FnMut ( X , Y ) -> bool ,
3608
+ {
3609
+ move |x, y| {
3610
+ if eq ( x, y) { ControlFlow :: CONTINUE } else { ControlFlow :: BREAK }
3637
3611
}
3638
3612
}
3613
+
3614
+ match iter_compare ( self , other. into_iter ( ) , compare ( eq) ) {
3615
+ ControlFlow :: Continue ( ord) => ord == Ordering :: Equal ,
3616
+ ControlFlow :: Break ( ( ) ) => false ,
3617
+ }
3639
3618
}
3640
3619
3641
3620
/// Determines if the elements of this [`Iterator`] are unequal to those of
@@ -3860,6 +3839,46 @@ pub trait Iterator {
3860
3839
}
3861
3840
}
3862
3841
3842
+ /// Compares two iterators element-wise using the given function.
3843
+ ///
3844
+ /// If `ControlFlow::CONTINUE` is returned from the function, the comparison moves on to the next
3845
+ /// elements of both iterators. Returning `ControlFlow::Break(x)` short-circuits the iteration and
3846
+ /// returns `ControlFlow::Break(x)`. If one of the iterators runs out of elements,
3847
+ /// `ControlFlow::Continue(ord)` is returned where `ord` is the result of comparing the lengths of
3848
+ /// the iterators.
3849
+ ///
3850
+ /// Isolates the logic shared by ['cmp_by'](Iterator::cmp_by),
3851
+ /// ['partial_cmp_by'](Iterator::partial_cmp_by), and ['eq_by'](Iterator::eq_by).
3852
+ #[ inline]
3853
+ fn iter_compare < A , B , F , T > ( mut a : A , mut b : B , f : F ) -> ControlFlow < T , Ordering >
3854
+ where
3855
+ A : Iterator ,
3856
+ B : Iterator ,
3857
+ F : FnMut ( A :: Item , B :: Item ) -> ControlFlow < T > ,
3858
+ {
3859
+ #[ inline]
3860
+ fn compare < ' a , B , X , T > (
3861
+ b : & ' a mut B ,
3862
+ mut f : impl FnMut ( X , B :: Item ) -> ControlFlow < T > + ' a ,
3863
+ ) -> impl FnMut ( X ) -> ControlFlow < ControlFlow < T , Ordering > > + ' a
3864
+ where
3865
+ B : Iterator ,
3866
+ {
3867
+ move |x| match b. next ( ) {
3868
+ None => ControlFlow :: Break ( ControlFlow :: Continue ( Ordering :: Greater ) ) ,
3869
+ Some ( y) => f ( x, y) . map_break ( ControlFlow :: Break ) ,
3870
+ }
3871
+ }
3872
+
3873
+ match a. try_for_each ( compare ( & mut b, f) ) {
3874
+ ControlFlow :: Continue ( ( ) ) => ControlFlow :: Continue ( match b. next ( ) {
3875
+ None => Ordering :: Equal ,
3876
+ Some ( _) => Ordering :: Less ,
3877
+ } ) ,
3878
+ ControlFlow :: Break ( x) => x,
3879
+ }
3880
+ }
3881
+
3863
3882
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3864
3883
impl < I : Iterator + ?Sized > Iterator for & mut I {
3865
3884
type Item = I :: Item ;
0 commit comments