@@ -4,6 +4,7 @@ use super::super::{
44 Product , Rev , Scan , Skip , SkipWhile , StepBy , Sum , Take , TakeWhile , TrustedRandomAccessNoCoerce ,
55 Zip , try_process,
66} ;
7+ use super :: TrustedLen ;
78use crate :: array;
89use crate :: cmp:: { self , Ordering } ;
910use crate :: num:: NonZero ;
@@ -3816,10 +3817,7 @@ pub trait Iterator {
38163817 }
38173818 }
38183819
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) )
38233821 }
38243822
38253823 /// Determines if the elements of this [`Iterator`] are not equal to those of
@@ -4038,6 +4036,42 @@ pub trait Iterator {
40384036 }
40394037}
40404038
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+
40414075/// Compares two iterators element-wise using the given function.
40424076///
40434077/// If `ControlFlow::Continue(())` is returned from the function, the comparison moves on to the next
@@ -4078,6 +4112,16 @@ where
40784112 }
40794113}
40804114
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+
40814125/// Implements `Iterator` for mutable references to iterators, such as those produced by [`Iterator::by_ref`].
40824126///
40834127/// This implementation passes all method calls on to the original iterator.
0 commit comments