Skip to content

Commit 4064a6b

Browse files
committed
Specialize Iterator::{eq|cmp|partial_cmp}_by for TrustedLen iterators
1 parent c3fe9e7 commit 4064a6b

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

library/core/src/iter/traits/iterator.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
78
use crate::array;
89
use crate::cmp::{self, Ordering};
910
use crate::num::NonZero;
@@ -3615,7 +3616,7 @@ pub trait Iterator {
36153616
}
36163617
}
36173618

3618-
match iter_compare(self, other.into_iter(), compare(cmp)) {
3619+
match SpecIterCompare::spec_iter_compare(self, other.into_iter(), compare(cmp)) {
36193620
ControlFlow::Continue(ord) => ord,
36203621
ControlFlow::Break(ord) => ord,
36213622
}
@@ -3707,7 +3708,7 @@ pub trait Iterator {
37073708
}
37083709
}
37093710

3710-
match iter_compare(self, other.into_iter(), compare(partial_cmp)) {
3711+
match SpecIterCompare::spec_iter_compare(self, other.into_iter(), compare(partial_cmp)) {
37113712
ControlFlow::Continue(ord) => Some(ord),
37123713
ControlFlow::Break(ord) => ord,
37133714
}
@@ -3762,7 +3763,7 @@ pub trait Iterator {
37623763
}
37633764
}
37643765

3765-
match iter_compare(self, other.into_iter(), compare(eq)) {
3766+
match SpecIterCompare::spec_iter_compare(self, other.into_iter(), compare(eq)) {
37663767
ControlFlow::Continue(ord) => ord == Ordering::Equal,
37673768
ControlFlow::Break(()) => false,
37683769
}
@@ -3984,6 +3985,41 @@ pub trait Iterator {
39843985
}
39853986
}
39863987

3988+
trait SpecIterCompare<B: Iterator>: Iterator {
3989+
fn spec_iter_compare<F, T>(self, b: B, f: F) -> ControlFlow<T, Ordering>
3990+
where
3991+
F: FnMut(Self::Item, B::Item) -> ControlFlow<T>;
3992+
}
3993+
3994+
impl<A: Iterator, B: Iterator> SpecIterCompare<B> for A {
3995+
#[inline]
3996+
default fn spec_iter_compare<F, T>(self, b: B, f: F) -> ControlFlow<T, Ordering>
3997+
where
3998+
F: FnMut(A::Item, <B as Iterator>::Item) -> ControlFlow<T>,
3999+
{
4000+
iter_compare(self, b, f)
4001+
}
4002+
}
4003+
4004+
impl<A: Iterator + TrustedLen, B: Iterator + TrustedLen> SpecIterCompare<B> for A {
4005+
#[inline]
4006+
fn spec_iter_compare<F, T>(self, b: B, f: F) -> ControlFlow<T, Ordering>
4007+
where
4008+
F: FnMut(Self::Item, <B as Iterator>::Item) -> ControlFlow<T>,
4009+
{
4010+
if let (_, Some(a)) = self.size_hint()
4011+
&& let (_, Some(b)) = b.size_hint()
4012+
{
4013+
let ord = a.cmp(&b);
4014+
if ord != Ordering::Equal {
4015+
return ControlFlow::Continue(ord);
4016+
}
4017+
}
4018+
4019+
iter_compare(self, b, f)
4020+
}
4021+
}
4022+
39874023
/// Compares two iterators element-wise using the given function.
39884024
///
39894025
/// If `ControlFlow::Continue(())` is returned from the function, the comparison moves on to the next

0 commit comments

Comments
 (0)