From 83925dd453ca67c611e45cbd6c17d7a4d3041bde Mon Sep 17 00:00:00 2001 From: Michael Spector Date: Sat, 11 Sep 2021 18:40:04 +0300 Subject: [PATCH] Allow reverse iteration of lowercase'd/uppercase'd chars --- library/alloc/tests/str.rs | 31 +++++++++++++++++++++++++++++++ library/core/src/char/mod.rs | 34 ++++++++++++++++++++++++++++++++++ library/core/tests/char.rs | 6 ++++++ 3 files changed, 71 insertions(+) diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs index d3a87c056cf..9ec57d7e644 100644 --- a/library/alloc/tests/str.rs +++ b/library/alloc/tests/str.rs @@ -1125,6 +1125,37 @@ fn test_rev_iterator() { assert_eq!(pos, v.len()); } +#[test] +fn test_to_lowercase_rev_iterator() { + let s = "AÖßÜ💩ΣΤΙΓΜΑΣDžfiİ"; + let v = ['\u{307}', 'i', 'fi', 'dž', 'σ', 'α', 'μ', 'γ', 'ι', 'τ', 'σ', '💩', 'ü', 'ß', 'ö', 'a']; + + let mut pos = 0; + let it = s.chars().flat_map(|c| c.to_lowercase()).rev(); + + for c in it { + assert_eq!(c, v[pos]); + pos += 1; + } + assert_eq!(pos, v.len()); +} + +#[test] +fn test_to_uppercase_rev_iterator() { + let s = "aößü💩στιγμαςDžfiᾀ"; + let v = + ['Ι', 'Ἀ', 'I', 'F', 'DŽ', 'Σ', 'Α', 'Μ', 'Γ', 'Ι', 'Τ', 'Σ', '💩', 'Ü', 'S', 'S', 'Ö', 'A']; + + let mut pos = 0; + let it = s.chars().flat_map(|c| c.to_uppercase()).rev(); + + for c in it { + assert_eq!(c, v[pos]); + pos += 1; + } + assert_eq!(pos, v.len()); +} + #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_chars_decoding() { diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 0728523d0a4..a9e7144eb64 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -393,6 +393,13 @@ fn size_hint(&self) -> (usize, Option) { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for ToLowercase { + fn next_back(&mut self) -> Option { + self.0.next_back() + } +} + #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToLowercase {} @@ -420,6 +427,13 @@ fn size_hint(&self) -> (usize, Option) { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for ToUppercase { + fn next_back(&mut self) -> Option { + self.0.next_back() + } +} + #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToUppercase {} @@ -479,6 +493,26 @@ fn size_hint(&self) -> (usize, Option) { } } +impl DoubleEndedIterator for CaseMappingIter { + fn next_back(&mut self) -> Option { + match *self { + CaseMappingIter::Three(a, b, c) => { + *self = CaseMappingIter::Two(a, b); + Some(c) + } + CaseMappingIter::Two(b, c) => { + *self = CaseMappingIter::One(b); + Some(c) + } + CaseMappingIter::One(c) => { + *self = CaseMappingIter::Zero; + Some(c) + } + CaseMappingIter::Zero => None, + } + } +} + impl fmt::Display for CaseMappingIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { diff --git a/library/core/tests/char.rs b/library/core/tests/char.rs index 51eca1e05d3..ee196db5363 100644 --- a/library/core/tests/char.rs +++ b/library/core/tests/char.rs @@ -91,6 +91,9 @@ fn lower(c: char) -> String { let iter: String = c.to_lowercase().collect(); let disp: String = c.to_lowercase().to_string(); assert_eq!(iter, disp); + let iter_rev: String = c.to_lowercase().rev().collect(); + let disp_rev: String = disp.chars().rev().collect(); + assert_eq!(iter_rev, disp_rev); iter } assert_eq!(lower('A'), "a"); @@ -118,6 +121,9 @@ fn upper(c: char) -> String { let iter: String = c.to_uppercase().collect(); let disp: String = c.to_uppercase().to_string(); assert_eq!(iter, disp); + let iter_rev: String = c.to_uppercase().rev().collect(); + let disp_rev: String = disp.chars().rev().collect(); + assert_eq!(iter_rev, disp_rev); iter } assert_eq!(upper('a'), "A");