about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Spector <spektom@gmail.com>2021-09-11 18:40:04 +0300
committerMichael Spector <spektom@gmail.com>2021-09-11 18:40:04 +0300
commit83925dd453ca67c611e45cbd6c17d7a4d3041bde (patch)
tree584957021fc240a1d0f23e1c2dc457eef2b84b25
parent7bf0736e130e2203c58654f7353dbf9575e49d5c (diff)
downloadrust-83925dd453ca67c611e45cbd6c17d7a4d3041bde.tar.gz
rust-83925dd453ca67c611e45cbd6c17d7a4d3041bde.zip
Allow reverse iteration of lowercase'd/uppercase'd chars
-rw-r--r--library/alloc/tests/str.rs31
-rw-r--r--library/core/src/char/mod.rs34
-rw-r--r--library/core/tests/char.rs6
3 files changed, 71 insertions, 0 deletions
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
@@ -1126,6 +1126,37 @@ fn test_rev_iterator() {
 }
 
 #[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() {
     let mut bytes = [0; 4];
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 @@ impl Iterator for ToLowercase {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl DoubleEndedIterator for ToLowercase {
+    fn next_back(&mut self) -> Option<char> {
+        self.0.next_back()
+    }
+}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl FusedIterator for ToLowercase {}
 
@@ -420,6 +427,13 @@ impl Iterator for ToUppercase {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl DoubleEndedIterator for ToUppercase {
+    fn next_back(&mut self) -> Option<char> {
+        self.0.next_back()
+    }
+}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl FusedIterator for ToUppercase {}
 
@@ -479,6 +493,26 @@ impl Iterator for CaseMappingIter {
     }
 }
 
+impl DoubleEndedIterator for CaseMappingIter {
+    fn next_back(&mut self) -> Option<char> {
+        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 test_to_lowercase() {
         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 test_to_uppercase() {
         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");