@@ -4,6 +4,7 @@ use super::super::{
4
4
Product , Rev , Scan , Skip , SkipWhile , StepBy , Sum , Take , TakeWhile , TrustedRandomAccessNoCoerce ,
5
5
Zip , try_process,
6
6
} ;
7
+ use super :: TrustedLen ;
7
8
use crate :: array;
8
9
use crate :: cmp:: { self , Ordering } ;
9
10
use crate :: num:: NonZero ;
@@ -3816,10 +3817,7 @@ pub trait Iterator {
3816
3817
}
3817
3818
}
3818
3819
3819
- match iter_compare ( self , other. into_iter ( ) , compare ( eq) ) {
3820
- ControlFlow :: Continue ( ord) => ord == Ordering :: Equal ,
3821
- ControlFlow :: Break ( ( ) ) => false ,
3822
- }
3820
+ SpecIterEq :: spec_iter_eq ( self , other. into_iter ( ) , compare ( eq) )
3823
3821
}
3824
3822
3825
3823
/// Determines if the elements of this [`Iterator`] are not equal to those of
@@ -4038,6 +4036,42 @@ pub trait Iterator {
4038
4036
}
4039
4037
}
4040
4038
4039
+ trait SpecIterEq < B : Iterator > : Iterator {
4040
+ fn spec_iter_eq < F > ( self , b : B , f : F ) -> bool
4041
+ where
4042
+ F : FnMut ( Self :: Item , <B as Iterator >:: Item ) -> ControlFlow < ( ) > ;
4043
+ }
4044
+
4045
+ impl < A : Iterator , B : Iterator > SpecIterEq < B > for A {
4046
+ #[ inline]
4047
+ default fn spec_iter_eq < F > ( self , b : B , f : F ) -> bool
4048
+ where
4049
+ F : FnMut ( Self :: Item , <B as Iterator >:: Item ) -> ControlFlow < ( ) > ,
4050
+ {
4051
+ iter_eq ( self , b, f)
4052
+ }
4053
+ }
4054
+
4055
+ impl < A : Iterator + TrustedLen , B : Iterator + TrustedLen > SpecIterEq < B > for A {
4056
+ #[ inline]
4057
+ fn spec_iter_eq < F > ( self , b : B , f : F ) -> bool
4058
+ where
4059
+ F : FnMut ( Self :: Item , <B as Iterator >:: Item ) -> ControlFlow < ( ) > ,
4060
+ {
4061
+ // we *can't* short-circuit if:
4062
+ match ( self . size_hint ( ) , b. size_hint ( ) ) {
4063
+ // ... both iterators have the same length
4064
+ ( ( _, Some ( a) ) , ( _, Some ( b) ) ) if a == b => { }
4065
+ // ... or both of them are longer than `usize::MAX` (i.e. have an unknown length).
4066
+ ( ( _, None ) , ( _, None ) ) => { }
4067
+ // otherwise, we can ascertain that they are unequal without actually comparing items
4068
+ _ => return false ,
4069
+ }
4070
+
4071
+ iter_eq ( self , b, f)
4072
+ }
4073
+ }
4074
+
4041
4075
/// Compares two iterators element-wise using the given function.
4042
4076
///
4043
4077
/// If `ControlFlow::Continue(())` is returned from the function, the comparison moves on to the next
@@ -4078,6 +4112,16 @@ where
4078
4112
}
4079
4113
}
4080
4114
4115
+ #[ inline]
4116
+ fn iter_eq < A , B , F > ( a : A , b : B , f : F ) -> bool
4117
+ where
4118
+ A : Iterator ,
4119
+ B : Iterator ,
4120
+ F : FnMut ( A :: Item , B :: Item ) -> ControlFlow < ( ) > ,
4121
+ {
4122
+ iter_compare ( a, b, f) . continue_value ( ) . is_some_and ( |ord| ord == Ordering :: Equal )
4123
+ }
4124
+
4081
4125
/// Implements `Iterator` for mutable references to iterators, such as those produced by [`Iterator::by_ref`].
4082
4126
///
4083
4127
/// This implementation passes all method calls on to the original iterator.
0 commit comments