use core::borrow::Borrow;
use core::cmp::Ordering::{self, Less, Greater, Equal};
-use core::cmp::max;
+use core::cmp::{max, min};
use core::fmt::{self, Debug};
use core::iter::{Peekable, FromIterator, FusedIterator};
use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds};
}
enum IntersectionInner<'a, T: 'a> {
Stitch {
- small_iter: Iter<'a, T>, // for size_hint, should be the smaller of the sets
- other_iter: Iter<'a, T>,
+ a: Iter<'a, T>,
+ b: Iter<'a, T>,
},
Search {
small_iter: Iter<'a, T>,
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.inner {
IntersectionInner::Stitch {
- small_iter,
- other_iter,
+ a,
+ b,
} => f
.debug_tuple("Intersection")
- .field(&small_iter)
- .field(&other_iter)
+ .field(&a)
+ .field(&b)
.finish(),
IntersectionInner::Search {
small_iter,
// Iterate both sets jointly, spotting matches along the way.
Intersection {
inner: IntersectionInner::Stitch {
- small_iter: small.iter(),
- other_iter: other.iter(),
+ a: small.iter(),
+ b: other.iter(),
},
}
} else {
Intersection {
inner: match &self.inner {
IntersectionInner::Stitch {
- small_iter,
- other_iter,
+ a,
+ b,
} => IntersectionInner::Stitch {
- small_iter: small_iter.clone(),
- other_iter: other_iter.clone(),
+ a: a.clone(),
+ b: b.clone(),
},
IntersectionInner::Search {
small_iter,
fn next(&mut self) -> Option<&'a T> {
match &mut self.inner {
IntersectionInner::Stitch {
- small_iter,
- other_iter,
+ a,
+ b,
} => {
- let mut small_next = small_iter.next()?;
- let mut other_next = other_iter.next()?;
+ let mut a_next = a.next()?;
+ let mut b_next = b.next()?;
loop {
- match Ord::cmp(small_next, other_next) {
- Less => small_next = small_iter.next()?,
- Greater => other_next = other_iter.next()?,
- Equal => return Some(small_next),
+ match Ord::cmp(a_next, b_next) {
+ Less => a_next = a.next()?,
+ Greater => b_next = b.next()?,
+ Equal => return Some(a_next),
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let min_len = match &self.inner {
- IntersectionInner::Stitch { small_iter, .. } => small_iter.len(),
+ IntersectionInner::Stitch { a, b } => min(a.len(), b.len()),
IntersectionInner::Search { small_iter, .. } => small_iter.len(),
};
(0, Some(min_len))
&[1, 3, 11, 77, 103]);
}
+#[test]
+fn test_intersection_size_hint() {
+ let x: BTreeSet<i32> = [3, 4].iter().copied().collect();
+ let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
+ let mut iter = x.intersection(&y);
+ assert_eq!(iter.size_hint(), (0, Some(2)));
+ assert_eq!(iter.next(), Some(&3));
+ assert_eq!(iter.size_hint(), (0, Some(0)));
+ assert_eq!(iter.next(), None);
+}
+
#[test]
fn test_difference() {
fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {