Skip to content

Implement size_hint for several unicode-based iterators. #50208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/libcore/char/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,11 +404,16 @@ impl Iterator for ToLowercase {
fn next(&mut self) -> Option<char> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for ToLowercase {}

impl ExactSizeIterator for ToLowercase {}

/// Returns an iterator that yields the uppercase equivalent of a `char`.
///
/// This `struct` is created by the [`to_uppercase`] method on [`char`]. See
Expand All @@ -426,11 +431,16 @@ impl Iterator for ToUppercase {
fn next(&mut self) -> Option<char> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for ToUppercase {}

impl ExactSizeIterator for ToUppercase {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the line above it, this should have an attribute, something like

#[stable(feature = "case_mapping_len", since = "1.27.0")]


#[derive(Debug, Clone)]
enum CaseMappingIter {
Three(char, char, char),
Expand Down Expand Up @@ -472,8 +482,26 @@ impl Iterator for CaseMappingIter {
CaseMappingIter::Zero => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match *self {
CaseMappingIter::Three(_, _, _) => {
(3, Some(3))
}
CaseMappingIter::Two(_, _) => {
(2, Some(2))
}
CaseMappingIter::One(_) => {
(1, Some(1))
}
CaseMappingIter::Zero => (0, Some(0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I'm confident this is correct, I think it'd still be good to have a test to pin the behaviour; a bunch of things like assert_eq!('a'.to_lowercase().len(), 1), perhaps.

}
}
}

impl FusedIterator for CaseMappingIter {}

impl ExactSizeIterator for CaseMappingIter {}

impl fmt::Display for CaseMappingIter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expand Down
11 changes: 10 additions & 1 deletion src/libcore/str/lossy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use str as core_str;
use fmt;
use fmt::Write;
use mem;
use iter::FusedIterator;

/// Lossy UTF-8 string.
#[unstable(feature = "str_internals", issue = "0")]
Expand Down Expand Up @@ -146,7 +147,13 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
broken: &[],
};
self.source = &[];
return Some(r);
Some(r)
}

fn size_hint(&self) -> (usize, Option<usize>) {
// We might return no characters (we encounter an error).
// We will return the most characters when the input is all ASCII.
(0, Some(self.source.len()))
}
}

Expand Down Expand Up @@ -177,6 +184,8 @@ impl fmt::Display for Utf8Lossy {
}
}

impl<'a> FusedIterator for Utf8LossyChunksIter<'a> {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there tests that verify this? (There might be something already; I dunno.)


impl fmt::Debug for Utf8Lossy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_char('"')?;
Expand Down
4 changes: 4 additions & 0 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4316,6 +4316,10 @@ impl<'a> Iterator for SplitWhitespace<'a> {
fn next(&mut self) -> Option<&'a str> {
self.inner.next()
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}

#[stable(feature = "split_whitespace", since = "1.1.0")]
Expand Down