Skip to content

Commit

Permalink
Auto merge of #530 - ToMe25:fix_set_diff_size_hint, r=Amanieu
Browse files Browse the repository at this point in the history
Improve Set Difference size_hint lower bound

This PR makes the Set `Difference` iterator generate a non-zero lower bound in some situations.

Specifically, it now returns a non-zero lower bound if the `difference` method is called on a larger set with a smaller set.
That is because in those cases the fact that sets can't really contains duplicates\* guarantees that a minimum of `self.len() - other.len()` items will be returned by the iterator.

\* Well, they can, but that is already documented to be causing a random mess

This implementation has the disadvantage that a single `next()` call may reduce the lower bound by more than one.
Every size hint generated, even the first largest one, is guaranteed to be correct, but it may be confusing if one `next()` call causes the lower bound to drop by more than one.

This could be avoided by storing the minimum number of resulting elements in the iterator and subtracting one each time `next()` is called, but I don't think its worth the added complexity.
  • Loading branch information
bors committed Jun 17, 2024
2 parents a34158c + f4361bc commit 65c553d
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,7 @@ where
let (_, upper) = self.iter.size_hint();
(0, upper)
}

#[cfg_attr(feature = "inline-more", inline)]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Expand Down Expand Up @@ -1916,9 +1917,10 @@ where

#[cfg_attr(feature = "inline-more", inline)]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
let (lower, upper) = self.iter.size_hint();
(lower.saturating_sub(self.other.len()), upper)
}

#[cfg_attr(feature = "inline-more", inline)]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Expand Down Expand Up @@ -1975,10 +1977,12 @@ where
fn next(&mut self) -> Option<&'a T> {
self.iter.next()
}

#[cfg_attr(feature = "inline-more", inline)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}

#[cfg_attr(feature = "inline-more", inline)]
fn fold<B, F>(self, init: B, f: F) -> B
where
Expand Down Expand Up @@ -2048,10 +2052,12 @@ where
fn next(&mut self) -> Option<&'a T> {
self.iter.next()
}

#[cfg_attr(feature = "inline-more", inline)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}

#[cfg_attr(feature = "inline-more", inline)]
fn fold<B, F>(self, init: B, f: F) -> B
where
Expand Down

0 comments on commit 65c553d

Please sign in to comment.