Skip to content

Commit

Permalink
Make char::DecodeUtf16::size_hist more precise
Browse files Browse the repository at this point in the history
New implementation takes into account contents of `self.buf` and rounds
lower bound up instead of down.
  • Loading branch information
WaffleLapkin committed Jan 26, 2022
1 parent a7f3757 commit cd4245d
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions library/core/src/char/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,21 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, high) = self.iter.size_hint();
// we could be entirely valid surrogates (2 elements per
// char), or entirely non-surrogates (1 element per char)
(low / 2, high)

// `self.buf` will never contain the first part of a surrogate,
// so the presence of `buf == Some(...)` always means +1
// on lower and upper bound.
let addition_from_buf = self.buf.is_some() as usize;

// `self.iter` could contain entirely valid surrogates (2 elements per
// char), or entirely non-surrogates (1 element per char).
//
// On odd lower bound, at least one element must stay unpaired
// (with other elements from `self.iter`), so we round up.
let low = low.div_ceil(2) + addition_from_buf;
let high = high.and_then(|h| h.checked_add(addition_from_buf));

(low, high)
}
}

Expand Down

0 comments on commit cd4245d

Please sign in to comment.