Skip to content

Commit 00f5916

Browse files
committed
std: replace the str::each* fns/methods with byte iterators
1 parent 4b806b4 commit 00f5916

File tree

6 files changed

+79
-161
lines changed

6 files changed

+79
-161
lines changed

src/libextra/time.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use core::i32;
1616
use core::int;
1717
use core::io;
1818
use core::str;
19+
use core::iterator::IteratorUtil;
1920

2021
static NSEC_PER_SEC: i32 = 1_000_000_000_i32;
2122

@@ -261,7 +262,7 @@ impl Tm {
261262
priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
262263
fn match_str(s: &str, pos: uint, needle: &str) -> bool {
263264
let mut i = pos;
264-
for str::each(needle) |ch| {
265+
for needle.bytes_iter().advance |ch| {
265266
if s[i] != ch {
266267
return false;
267268
}

src/libstd/str.rs

Lines changed: 69 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use str;
3535
use to_str::ToStr;
3636
use uint;
3737
use vec;
38-
use vec::{OwnedVector, OwnedCopyableVector};
38+
use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector};
3939

4040
#[cfg(not(test))] use cmp::{Eq, Ord, Equiv, TotalEq};
4141

@@ -1249,42 +1249,6 @@ pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str {
12491249
result
12501250
}
12511251

1252-
/// Iterate over the bytes in a string
1253-
#[inline(always)]
1254-
pub fn each(s: &str, it: &fn(u8) -> bool) -> bool {
1255-
eachi(s, |_i, b| it(b))
1256-
}
1257-
1258-
/// Iterate over the bytes in a string, with indices
1259-
#[inline(always)]
1260-
pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) -> bool {
1261-
let mut pos = 0;
1262-
let len = s.len();
1263-
1264-
while pos < len {
1265-
if !it(pos, s[pos]) { return false; }
1266-
pos += 1;
1267-
}
1268-
return true;
1269-
}
1270-
1271-
/// Iterate over the bytes in a string in reverse
1272-
#[inline(always)]
1273-
pub fn each_reverse(s: &str, it: &fn(u8) -> bool) -> bool {
1274-
eachi_reverse(s, |_i, b| it(b) )
1275-
}
1276-
1277-
/// Iterate over the bytes in a string in reverse, with indices
1278-
#[inline(always)]
1279-
pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) -> bool {
1280-
let mut pos = s.len();
1281-
while pos > 0 {
1282-
pos -= 1;
1283-
if !it(pos, s[pos]) { return false; }
1284-
}
1285-
return true;
1286-
}
1287-
12881252
/*
12891253
Section: Searching
12901254
*/
@@ -1604,7 +1568,7 @@ pub fn rfind_between(s: &str, start: uint, end: uint, f: &fn(char) -> bool) -> O
16041568
// Utility used by various searching functions
16051569
fn match_at<'a,'b>(haystack: &'a str, needle: &'b str, at: uint) -> bool {
16061570
let mut i = at;
1607-
for each(needle) |c| { if haystack[i] != c { return false; } i += 1u; }
1571+
for needle.bytes_iter().advance |c| { if haystack[i] != c { return false; } i += 1u; }
16081572
return true;
16091573
}
16101574

@@ -2557,10 +2521,8 @@ pub trait StrSlice<'self> {
25572521
fn contains_char(&self, needle: char) -> bool;
25582522
fn iter(&self) -> StrCharIterator<'self>;
25592523
fn rev_iter(&self) -> StrCharRevIterator<'self>;
2560-
fn each(&self, it: &fn(u8) -> bool) -> bool;
2561-
fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool;
2562-
fn each_reverse(&self, it: &fn(u8) -> bool) -> bool;
2563-
fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool;
2524+
fn bytes_iter(&self) -> StrBytesIterator<'self>;
2525+
fn bytes_rev_iter(&self) -> StrBytesRevIterator<'self>;
25642526
fn ends_with(&self, needle: &str) -> bool;
25652527
fn is_empty(&self) -> bool;
25662528
fn is_whitespace(&self) -> bool;
@@ -2628,20 +2590,14 @@ impl<'self> StrSlice<'self> for &'self str {
26282590
}
26292591
}
26302592
2631-
/// Iterate over the bytes in a string
2632-
#[inline]
2633-
fn each(&self, it: &fn(u8) -> bool) -> bool { each(*self, it) }
2634-
/// Iterate over the bytes in a string, with indices
2635-
#[inline]
2636-
fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool { eachi(*self, it) }
2637-
/// Iterate over the bytes in a string
2638-
#[inline]
2639-
fn each_reverse(&self, it: &fn(u8) -> bool) -> bool { each_reverse(*self, it) }
2640-
/// Iterate over the bytes in a string, with indices
2641-
#[inline]
2642-
fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool {
2643-
eachi_reverse(*self, it)
2593+
fn bytes_iter(&self) -> StrBytesIterator<'self> {
2594+
StrBytesIterator { it: as_bytes_slice(*self).iter() }
26442595
}
2596+
fn bytes_rev_iter(&self) -> StrBytesRevIterator<'self> {
2597+
StrBytesRevIterator { it: as_bytes_slice(*self).rev_iter() }
2598+
}
2599+
2600+
26452601
/// Returns true if one string ends with another
26462602
#[inline]
26472603
fn ends_with(&self, needle: &str) -> bool {
@@ -2832,6 +2788,32 @@ impl<'self> Iterator<char> for StrCharRevIterator<'self> {
28322788
}
28332789
}
28342790
2791+
/// External iterator for a string's bytes. Use with the `std::iterator`
2792+
/// module.
2793+
pub struct StrBytesIterator<'self> {
2794+
priv it: vec::VecIterator<'self, u8>
2795+
}
2796+
2797+
impl<'self> Iterator<u8> for StrBytesIterator<'self> {
2798+
#[inline]
2799+
fn next(&mut self) -> Option<u8> {
2800+
self.it.next().map_consume(|&x| x)
2801+
}
2802+
}
2803+
2804+
/// External iterator for a string's bytes in reverse order. Use with
2805+
/// the `std::iterator` module.
2806+
pub struct StrBytesRevIterator<'self> {
2807+
priv it: vec::VecRevIterator<'self, u8>
2808+
}
2809+
2810+
impl<'self> Iterator<u8> for StrBytesRevIterator<'self> {
2811+
#[inline]
2812+
fn next(&mut self) -> Option<u8> {
2813+
self.it.next().map_consume(|&x| x)
2814+
}
2815+
}
2816+
28352817
#[cfg(test)]
28362818
mod tests {
28372819
use iterator::IteratorUtil;
@@ -3922,102 +3904,6 @@ mod tests {
39223904
}
39233905
}
39243906
3925-
#[test]
3926-
fn test_each() {
3927-
let s = ~"ศไทย中华Việt Nam";
3928-
let v = [
3929-
224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3930-
184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3931-
109
3932-
];
3933-
let mut pos = 0;
3934-
3935-
for s.each |b| {
3936-
assert_eq!(b, v[pos]);
3937-
pos += 1;
3938-
}
3939-
}
3940-
3941-
#[test]
3942-
fn test_each_empty() {
3943-
for "".each |b| {
3944-
assert_eq!(b, 0u8);
3945-
}
3946-
}
3947-
3948-
#[test]
3949-
fn test_eachi() {
3950-
let s = ~"ศไทย中华Việt Nam";
3951-
let v = [
3952-
224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3953-
184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3954-
109
3955-
];
3956-
let mut pos = 0;
3957-
3958-
for s.eachi |i, b| {
3959-
assert_eq!(pos, i);
3960-
assert_eq!(b, v[pos]);
3961-
pos += 1;
3962-
}
3963-
}
3964-
3965-
#[test]
3966-
fn test_eachi_empty() {
3967-
for "".eachi |i, b| {
3968-
assert_eq!(i, 0);
3969-
assert_eq!(b, 0);
3970-
}
3971-
}
3972-
3973-
#[test]
3974-
fn test_each_reverse() {
3975-
let s = ~"ศไทย中华Việt Nam";
3976-
let v = [
3977-
224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3978-
184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3979-
109
3980-
];
3981-
let mut pos = v.len();
3982-
3983-
for s.each_reverse |b| {
3984-
pos -= 1;
3985-
assert_eq!(b, v[pos]);
3986-
}
3987-
}
3988-
3989-
#[test]
3990-
fn test_each_empty_reverse() {
3991-
for "".each_reverse |b| {
3992-
assert_eq!(b, 0u8);
3993-
}
3994-
}
3995-
3996-
#[test]
3997-
fn test_eachi_reverse() {
3998-
let s = ~"ศไทย中华Việt Nam";
3999-
let v = [
4000-
224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
4001-
184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
4002-
109
4003-
];
4004-
let mut pos = v.len();
4005-
4006-
for s.eachi_reverse |i, b| {
4007-
pos -= 1;
4008-
assert_eq!(pos, i);
4009-
assert_eq!(b, v[pos]);
4010-
}
4011-
}
4012-
4013-
#[test]
4014-
fn test_eachi_reverse_empty() {
4015-
for "".eachi_reverse |i, b| {
4016-
assert_eq!(i, 0);
4017-
assert_eq!(b, 0);
4018-
}
4019-
}
4020-
40213907
#[test]
40223908
fn test_escape_unicode() {
40233909
assert_eq!(escape_unicode("abc"), ~"\\x61\\x62\\x63");
@@ -4097,4 +3983,36 @@ mod tests {
40973983
}
40983984
assert_eq!(pos, v.len());
40993985
}
3986+
3987+
#[test]
3988+
fn test_bytes_iterator() {
3989+
let s = ~"ศไทย中华Việt Nam";
3990+
let v = [
3991+
224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3992+
184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3993+
109
3994+
];
3995+
let mut pos = 0;
3996+
3997+
for s.bytes_iter().advance |b| {
3998+
assert_eq!(b, v[pos]);
3999+
pos += 1;
4000+
}
4001+
}
4002+
4003+
#[test]
4004+
fn test_bytes_rev_iterator() {
4005+
let s = ~"ศไทย中华Việt Nam";
4006+
let v = [
4007+
224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
4008+
184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
4009+
109
4010+
];
4011+
let mut pos = v.len();
4012+
4013+
for s.bytes_rev_iter().advance |b| {
4014+
pos -= 1;
4015+
assert_eq!(b, v[pos]);
4016+
}
4017+
}
41004018
}

src/libstd/str/ascii.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use str;
1515
use str::StrSlice;
1616
use cast;
1717
use old_iter::BaseIter;
18+
use iterator::IteratorUtil;
1819
use vec::{CopyableVector, ImmutableVector, OwnedVector};
1920

2021
/// Datatype to hold one ascii character. It is 8 bit long.
@@ -101,10 +102,7 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self str {
101102

102103
#[inline(always)]
103104
fn is_ascii(&self) -> bool {
104-
for self.each |b| {
105-
if !b.is_ascii() { return false; }
106-
}
107-
true
105+
self.bytes_iter().all(|b| b.is_ascii())
108106
}
109107
}
110108

src/libsyntax/ext/bytes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
/* The compiler code necessary to support the bytes! extension. */
1212

13+
use core::iterator::IteratorUtil;
1314
use ast;
1415
use codemap::span;
1516
use ext::base::*;
@@ -27,7 +28,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) -> bas
2728
ast::expr_lit(lit) => match lit.node {
2829
// string literal, push each byte to vector expression
2930
ast::lit_str(s) => {
30-
for s.each |byte| {
31+
for s.bytes_iter().advance |byte| {
3132
bytes.push(cx.expr_u8(sp, byte));
3233
}
3334
}

src/test/run-pass/linear-for-loop.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::str;
11+
use std::iterator::IteratorUtil;
1212

1313
pub fn main() {
1414
let x = ~[1, 2, 3];
@@ -18,7 +18,7 @@ pub fn main() {
1818
assert_eq!(y, 6);
1919
let s = ~"hello there";
2020
let mut i: int = 0;
21-
for str::each(s) |c| {
21+
for s.bytes_iter().advance |c| {
2222
if i == 0 { assert!((c == 'h' as u8)); }
2323
if i == 1 { assert!((c == 'e' as u8)); }
2424
if i == 2 { assert!((c == 'l' as u8)); }

src/test/run-pass/utf8.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::str;
11+
use std::iterator::IteratorUtil;
1212

1313
pub fn main() {
1414
let yen: char = '¥'; // 0xa5
@@ -43,7 +43,7 @@ pub fn main() {
4343

4444
fn check_str_eq(a: ~str, b: ~str) {
4545
let mut i: int = 0;
46-
for str::each(a) |ab| {
46+
for a.bytes_iter().advance |ab| {
4747
debug!(i);
4848
debug!(ab);
4949
let bb: u8 = b[i];

0 commit comments

Comments
 (0)