From 8d21e50154598ebdbc782c7e088018a47b73ccee Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 24 Apr 2018 23:49:59 -0400 Subject: [PATCH 1/3] Implement size_hint for several unicode-based iterators. This continues work on issue #49205. This PR also implements ExactSizeIterator and FusedIterator where they make sense. --- src/libcore/char/mod.rs | 30 ++++++++++++++++++++++++++++++ src/libcore/str/lossy.rs | 8 +++++++- src/libcore/str/mod.rs | 4 ++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs index 4f6c302247dd2..33958e617d486 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -404,11 +404,17 @@ impl Iterator for ToLowercase { fn next(&mut self) -> Option { self.0.next() } + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } } #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToLowercase {} +#[unstable(feature = "exact_unicode_iters", issue = "0")] +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 @@ -426,11 +432,17 @@ impl Iterator for ToUppercase { fn next(&mut self) -> Option { self.0.next() } + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } } #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToUppercase {} +#[unstable(feature = "exact_unicode_iters", issue = "0")] +impl ExactSizeIterator for ToUppercase {} + #[derive(Debug, Clone)] enum CaseMappingIter { Three(char, char, char), @@ -472,8 +484,26 @@ impl Iterator for CaseMappingIter { CaseMappingIter::Zero => None, } } + fn size_hint(&self) -> (usize, Option) { + match *self { + CaseMappingIter::Three(_, _, _) => { + (3, Some(3)) + } + CaseMappingIter::Two(_, _) => { + (2, Some(2)) + } + CaseMappingIter::One(_) => { + (1, Some(1)) + } + CaseMappingIter::Zero => (0, Some(0)) + } + } } +impl FusedIterator for CaseMappingIter {} + +impl ExactSizeIterator for CaseMappingIter {} + impl fmt::Display for CaseMappingIter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index 30b7267da7c5e..ab4bec299e40f 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -146,7 +146,11 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { broken: &[], }; self.source = &[]; - return Some(r); + Some(r) + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.source.len())) } } @@ -177,6 +181,8 @@ impl fmt::Display for Utf8Lossy { } } +impl FusedIterator for Utf8LossyChunksIter {} + impl fmt::Debug for Utf8Lossy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_char('"')?; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index b39d9feb35b7e..aa111fd42434a 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -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) { + self.inner.size_hint() + } } #[stable(feature = "split_whitespace", since = "1.1.0")] From 97e7466a9f60baa6459cca2dbbd336694c5a9c44 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Wed, 25 Apr 2018 00:08:22 -0400 Subject: [PATCH 2/3] Fix missing use statement --- src/libcore/str/lossy.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index ab4bec299e40f..b87b8d9736db0 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -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")] @@ -181,7 +182,7 @@ impl fmt::Display for Utf8Lossy { } } -impl FusedIterator for Utf8LossyChunksIter {} +impl<'a> FusedIterator for Utf8LossyChunksIter<'a> {} impl fmt::Debug for Utf8Lossy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From 12c0361c7808a85fd1d165494b7873f9aa624468 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Thu, 26 Apr 2018 17:38:32 -0400 Subject: [PATCH 3/3] Add a comment, remove unstable annotation --- src/libcore/char/mod.rs | 2 -- src/libcore/str/lossy.rs | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs index 33958e617d486..7c7ed2877f537 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -412,7 +412,6 @@ impl Iterator for ToLowercase { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToLowercase {} -#[unstable(feature = "exact_unicode_iters", issue = "0")] impl ExactSizeIterator for ToLowercase {} /// Returns an iterator that yields the uppercase equivalent of a `char`. @@ -440,7 +439,6 @@ impl Iterator for ToUppercase { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToUppercase {} -#[unstable(feature = "exact_unicode_iters", issue = "0")] impl ExactSizeIterator for ToUppercase {} #[derive(Debug, Clone)] diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index b87b8d9736db0..01e1c3eaaae01 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -151,6 +151,8 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } fn size_hint(&self) -> (usize, Option) { + // 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())) } }