Skip to content

Commit cd4245d

Browse files
committed
Make char::DecodeUtf16::size_hist more precise
New implementation takes into account contents of `self.buf` and rounds lower bound up instead of down.
1 parent a7f3757 commit cd4245d

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

library/core/src/char/decode.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,21 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
120120
#[inline]
121121
fn size_hint(&self) -> (usize, Option<usize>) {
122122
let (low, high) = self.iter.size_hint();
123-
// we could be entirely valid surrogates (2 elements per
124-
// char), or entirely non-surrogates (1 element per char)
125-
(low / 2, high)
123+
124+
// `self.buf` will never contain the first part of a surrogate,
125+
// so the presence of `buf == Some(...)` always means +1
126+
// on lower and upper bound.
127+
let addition_from_buf = self.buf.is_some() as usize;
128+
129+
// `self.iter` could contain entirely valid surrogates (2 elements per
130+
// char), or entirely non-surrogates (1 element per char).
131+
//
132+
// On odd lower bound, at least one element must stay unpaired
133+
// (with other elements from `self.iter`), so we round up.
134+
let low = low.div_ceil(2) + addition_from_buf;
135+
let high = high.and_then(|h| h.checked_add(addition_from_buf));
136+
137+
(low, high)
126138
}
127139
}
128140

0 commit comments

Comments
 (0)