Skip to content

Commit 83925dd

Browse files
author
Michael Spector
committed
Allow reverse iteration of lowercase'd/uppercase'd chars
1 parent 7bf0736 commit 83925dd

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

library/alloc/tests/str.rs

+31
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,37 @@ fn test_rev_iterator() {
11251125
assert_eq!(pos, v.len());
11261126
}
11271127

1128+
#[test]
1129+
fn test_to_lowercase_rev_iterator() {
1130+
let s = "AÖßÜ💩ΣΤΙΓΜΑΣDžfiİ";
1131+
let v = ['\u{307}', 'i', 'fi', 'dž', 'σ', 'α', 'μ', 'γ', 'ι', 'τ', 'σ', '💩', 'ü', 'ß', 'ö', 'a'];
1132+
1133+
let mut pos = 0;
1134+
let it = s.chars().flat_map(|c| c.to_lowercase()).rev();
1135+
1136+
for c in it {
1137+
assert_eq!(c, v[pos]);
1138+
pos += 1;
1139+
}
1140+
assert_eq!(pos, v.len());
1141+
}
1142+
1143+
#[test]
1144+
fn test_to_uppercase_rev_iterator() {
1145+
let s = "aößü💩στιγμαςDžfiᾀ";
1146+
let v =
1147+
['Ι', 'Ἀ', 'I', 'F', 'DŽ', 'Σ', 'Α', 'Μ', 'Γ', 'Ι', 'Τ', 'Σ', '💩', 'Ü', 'S', 'S', 'Ö', 'A'];
1148+
1149+
let mut pos = 0;
1150+
let it = s.chars().flat_map(|c| c.to_uppercase()).rev();
1151+
1152+
for c in it {
1153+
assert_eq!(c, v[pos]);
1154+
pos += 1;
1155+
}
1156+
assert_eq!(pos, v.len());
1157+
}
1158+
11281159
#[test]
11291160
#[cfg_attr(miri, ignore)] // Miri is too slow
11301161
fn test_chars_decoding() {

library/core/src/char/mod.rs

+34
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,13 @@ impl Iterator for ToLowercase {
393393
}
394394
}
395395

396+
#[stable(feature = "rust1", since = "1.0.0")]
397+
impl DoubleEndedIterator for ToLowercase {
398+
fn next_back(&mut self) -> Option<char> {
399+
self.0.next_back()
400+
}
401+
}
402+
396403
#[stable(feature = "fused", since = "1.26.0")]
397404
impl FusedIterator for ToLowercase {}
398405

@@ -420,6 +427,13 @@ impl Iterator for ToUppercase {
420427
}
421428
}
422429

430+
#[stable(feature = "rust1", since = "1.0.0")]
431+
impl DoubleEndedIterator for ToUppercase {
432+
fn next_back(&mut self) -> Option<char> {
433+
self.0.next_back()
434+
}
435+
}
436+
423437
#[stable(feature = "fused", since = "1.26.0")]
424438
impl FusedIterator for ToUppercase {}
425439

@@ -479,6 +493,26 @@ impl Iterator for CaseMappingIter {
479493
}
480494
}
481495

496+
impl DoubleEndedIterator for CaseMappingIter {
497+
fn next_back(&mut self) -> Option<char> {
498+
match *self {
499+
CaseMappingIter::Three(a, b, c) => {
500+
*self = CaseMappingIter::Two(a, b);
501+
Some(c)
502+
}
503+
CaseMappingIter::Two(b, c) => {
504+
*self = CaseMappingIter::One(b);
505+
Some(c)
506+
}
507+
CaseMappingIter::One(c) => {
508+
*self = CaseMappingIter::Zero;
509+
Some(c)
510+
}
511+
CaseMappingIter::Zero => None,
512+
}
513+
}
514+
}
515+
482516
impl fmt::Display for CaseMappingIter {
483517
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
484518
match *self {

library/core/tests/char.rs

+6
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ fn test_to_lowercase() {
9191
let iter: String = c.to_lowercase().collect();
9292
let disp: String = c.to_lowercase().to_string();
9393
assert_eq!(iter, disp);
94+
let iter_rev: String = c.to_lowercase().rev().collect();
95+
let disp_rev: String = disp.chars().rev().collect();
96+
assert_eq!(iter_rev, disp_rev);
9497
iter
9598
}
9699
assert_eq!(lower('A'), "a");
@@ -118,6 +121,9 @@ fn test_to_uppercase() {
118121
let iter: String = c.to_uppercase().collect();
119122
let disp: String = c.to_uppercase().to_string();
120123
assert_eq!(iter, disp);
124+
let iter_rev: String = c.to_uppercase().rev().collect();
125+
let disp_rev: String = disp.chars().rev().collect();
126+
assert_eq!(iter_rev, disp_rev);
121127
iter
122128
}
123129
assert_eq!(upper('a'), "A");

0 commit comments

Comments
 (0)