1
Fork 0

std: remove each_char* fns and methods from str, replaced by iterators.

This commit is contained in:
Huon Wilson 2013-06-08 22:04:46 +10:00
parent 513d2292e5
commit 4b806b4d06
10 changed files with 80 additions and 149 deletions

View file

@ -22,6 +22,7 @@ use procsrv;
use util; use util;
use util::logv; use util::logv;
use core::iterator::IteratorUtil;
use core::io; use core::io;
use core::os; use core::os;
use core::str; use core::str;
@ -780,7 +781,7 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps,
Some(~"")); Some(~""));
let mut exitcode : int = 0; let mut exitcode : int = 0;
for str::each_char(exitcode_out) |c| { for exitcode_out.iter().advance |c| {
if !c.is_digit() { break; } if !c.is_digit() { break; }
exitcode = exitcode * 10 + match c { exitcode = exitcode * 10 + match c {
'0' .. '9' => c as int - ('0' as int), '0' .. '9' => c as int - ('0' as int),

View file

@ -414,6 +414,7 @@ mod test {
use super::{FileInput, pathify, input_vec, input_vec_state}; use super::{FileInput, pathify, input_vec, input_vec_state};
use core::iterator::IteratorUtil;
use core::io; use core::io;
use core::str; use core::str;
use core::uint; use core::uint;
@ -455,7 +456,7 @@ mod test {
let fi = FileInput::from_vec(copy filenames); let fi = FileInput::from_vec(copy filenames);
for "012".each_chari |line, c| { for "012".iter().enumerate().advance |(line, c)| {
assert_eq!(fi.read_byte(), c as int); assert_eq!(fi.read_byte(), c as int);
assert_eq!(fi.state().line_num, line); assert_eq!(fi.state().line_num, line);
assert_eq!(fi.state().line_num_file, 0); assert_eq!(fi.state().line_num_file, 0);

View file

@ -18,6 +18,7 @@
use core::prelude::*; use core::prelude::*;
use core::iterator::IteratorUtil;
use core::char; use core::char;
use core::float; use core::float;
use core::hashmap::HashMap; use core::hashmap::HashMap;
@ -58,7 +59,7 @@ pub struct Error {
fn escape_str(s: &str) -> ~str { fn escape_str(s: &str) -> ~str {
let mut escaped = ~"\""; let mut escaped = ~"\"";
for str::each_char(s) |c| { for s.iter().advance |c| {
match c { match c {
'"' => escaped += "\\\"", '"' => escaped += "\\\"",
'\\' => escaped += "\\\\", '\\' => escaped += "\\\\",
@ -913,7 +914,8 @@ impl serialize::Decoder for Decoder {
fn read_char(&mut self) -> char { fn read_char(&mut self) -> char {
let mut v = ~[]; let mut v = ~[];
for str::each_char(self.read_str()) |c| { v.push(c) } let s = self.read_str();
for s.iter().advance |c| { v.push(c) }
if v.len() != 1 { fail!("string must have one character") } if v.len() != 1 { fail!("string must have one character") }
v[0] v[0]
} }

View file

@ -14,6 +14,7 @@
use core::prelude::*; use core::prelude::*;
use core::iterator::IteratorUtil;
use core::cmp::Eq; use core::cmp::Eq;
use core::io::{Reader, ReaderUtil}; use core::io::{Reader, ReaderUtil};
use core::io; use core::io;
@ -358,7 +359,7 @@ pub fn query_to_str(query: &Query) -> ~str {
// returns the scheme and the rest of the url, or a parsing error // returns the scheme and the rest of the url, or a parsing error
pub fn get_scheme(rawurl: &str) -> Result<(~str, ~str), ~str> { pub fn get_scheme(rawurl: &str) -> Result<(~str, ~str), ~str> {
for str::each_chari(rawurl) |i,c| { for rawurl.iter().enumerate().advance |(i,c)| {
match c { match c {
'A' .. 'Z' | 'a' .. 'z' => loop, 'A' .. 'Z' | 'a' .. 'z' => loop,
'0' .. '9' | '+' | '-' | '.' => { '0' .. '9' | '+' | '-' | '.' => {
@ -418,7 +419,7 @@ fn get_authority(rawurl: &str) ->
let mut colon_count = 0; let mut colon_count = 0;
let mut (pos, begin, end) = (0, 2, len); let mut (pos, begin, end) = (0, 2, len);
for str::each_chari(rawurl) |i,c| { for rawurl.iter().enumerate().advance |(i,c)| {
if i < 2 { loop; } // ignore the leading // if i < 2 { loop; } // ignore the leading //
// deal with input class first // deal with input class first
@ -562,7 +563,7 @@ fn get_path(rawurl: &str, authority: bool) ->
Result<(~str, ~str), ~str> { Result<(~str, ~str), ~str> {
let len = str::len(rawurl); let len = str::len(rawurl);
let mut end = len; let mut end = len;
for str::each_chari(rawurl) |i,c| { for rawurl.iter().enumerate().advance |(i,c)| {
match c { match c {
'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '&' |'\'' | '(' | ')' | '.' 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '&' |'\'' | '(' | ')' | '.'
| '@' | ':' | '%' | '/' | '+' | '!' | '*' | ',' | ';' | '=' | '@' | ':' | '%' | '/' | '+' | '!' | '*' | ',' | ';' | '='

View file

@ -22,6 +22,7 @@ use middle::trans::common::CrateContext;
use middle::ty; use middle::ty;
use util::ppaux; use util::ppaux;
use core::iterator::IteratorUtil;
use core::char; use core::char;
use core::hash::Streaming; use core::hash::Streaming;
use core::hash; use core::hash;
@ -636,7 +637,7 @@ pub fn get_symbol_hash(ccx: @CrateContext, t: ty::t) -> @str {
// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
pub fn sanitize(s: &str) -> ~str { pub fn sanitize(s: &str) -> ~str {
let mut result = ~""; let mut result = ~"";
for str::each_char(s) |c| { for s.iter().advance |c| {
match c { match c {
// Escape these with $ sequences // Escape these with $ sequences
'@' => result += "$SP$", '@' => result += "$SP$",

View file

@ -43,6 +43,7 @@ fn main () {
use cast; use cast;
use cmp; use cmp;
use int; use int;
use iterator::IteratorUtil;
use local_data; use local_data;
use prelude::*; use prelude::*;
use str; use str;
@ -479,7 +480,7 @@ impl<R: Rng> RngUtil for R {
fn gen_char_from(&mut self, chars: &str) -> char { fn gen_char_from(&mut self, chars: &str) -> char {
assert!(!chars.is_empty()); assert!(!chars.is_empty());
let mut cs = ~[]; let mut cs = ~[];
for str::each_char(chars) |c| { cs.push(c) } for chars.iter().advance |c| { cs.push(c) }
self.choose(cs) self.choose(cs)
} }

View file

@ -22,6 +22,7 @@ use intrinsic;
use intrinsic::{TyDesc, TyVisitor, visit_tydesc}; use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
use intrinsic::Opaque; use intrinsic::Opaque;
use io::{Writer, WriterUtil}; use io::{Writer, WriterUtil};
use iterator::IteratorUtil;
use libc::c_void; use libc::c_void;
use managed; use managed;
use ptr; use ptr;
@ -209,7 +210,7 @@ impl ReprVisitor {
pub fn write_escaped_slice(&self, slice: &str) { pub fn write_escaped_slice(&self, slice: &str) {
self.writer.write_char('"'); self.writer.write_char('"');
for slice.each_char |ch| { for slice.iter().advance |ch| {
self.writer.write_escaped_char(ch); self.writer.write_escaped_char(ch);
} }
self.writer.write_char('"'); self.writer.write_char('"');

View file

@ -25,7 +25,7 @@ use clone::Clone;
use cmp::{TotalOrd, Ordering, Less, Equal, Greater}; use cmp::{TotalOrd, Ordering, Less, Equal, Greater};
use container::Container; use container::Container;
use iter::Times; use iter::Times;
use iterator::Iterator; use iterator::{Iterator, IteratorUtil};
use libc; use libc;
use option::{None, Option, Some}; use option::{None, Option, Some};
use old_iter::{BaseIter, EqIter}; use old_iter::{BaseIter, EqIter};
@ -608,11 +608,7 @@ pub fn byte_slice_no_callback<'a>(s: &'a str) -> &'a [u8] {
/// Convert a string to a unique vector of characters /// Convert a string to a unique vector of characters
pub fn to_chars(s: &str) -> ~[char] { pub fn to_chars(s: &str) -> ~[char] {
let mut buf = ~[]; s.iter().collect()
for each_char(s) |c| {
buf.push(c);
}
buf
} }
/** /**
@ -856,12 +852,12 @@ pub fn levdistance(s: &str, t: &str) -> uint {
let mut dcol = vec::from_fn(tlen + 1, |x| x); let mut dcol = vec::from_fn(tlen + 1, |x| x);
for s.each_chari |i, sc| { for s.iter().enumerate().advance |(i, sc)| {
let mut current = i; let mut current = i;
dcol[0] = current + 1; dcol[0] = current + 1;
for t.each_chari |j, tc| { for t.iter().enumerate().advance |(j, tc)| {
let next = dcol[j + 1]; let next = dcol[j + 1];
@ -943,7 +939,7 @@ pub fn each_split_within<'a>(ss: &'a str,
let mut cont = true; let mut cont = true;
let slice: &fn() = || { cont = it(slice(ss, slice_start, last_end)) }; let slice: &fn() = || { cont = it(slice(ss, slice_start, last_end)) };
let machine: &fn(uint, char) -> bool = |i, c| { let machine: &fn((uint, char)) -> bool = |(i, c)| {
let whitespace = if char::is_whitespace(c) { Ws } else { Cr }; let whitespace = if char::is_whitespace(c) { Ws } else { Cr };
let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim }; let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim };
@ -968,12 +964,12 @@ pub fn each_split_within<'a>(ss: &'a str,
cont cont
}; };
str::each_chari(ss, machine); ss.iter().enumerate().advance(machine);
// Let the automaton 'run out' by supplying trailing whitespace // Let the automaton 'run out' by supplying trailing whitespace
let mut fake_i = ss.len(); let mut fake_i = ss.len();
while cont && match state { B | C => true, A => false } { while cont && match state { B | C => true, A => false } {
machine(fake_i, ' '); machine((fake_i, ' '));
fake_i += 1; fake_i += 1;
} }
return cont; return cont;
@ -1247,7 +1243,7 @@ pub fn any(ss: &str, pred: &fn(char) -> bool) -> bool {
pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str { pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str {
let mut result = ~""; let mut result = ~"";
reserve(&mut result, len(ss)); reserve(&mut result, len(ss));
for ss.each_char |cc| { for ss.iter().advance |cc| {
str::push_char(&mut result, ff(cc)); str::push_char(&mut result, ff(cc));
} }
result result
@ -1289,55 +1285,6 @@ pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) -> bool {
return true; return true;
} }
/// Iterate over each char of a string, without allocating
#[inline(always)]
pub fn each_char(s: &str, it: &fn(char) -> bool) -> bool {
let mut i = 0;
let len = len(s);
while i < len {
let CharRange {ch, next} = char_range_at(s, i);
if !it(ch) { return false; }
i = next;
}
return true;
}
/// Iterates over the chars in a string, with indices
#[inline(always)]
pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) -> bool {
let mut pos = 0;
let mut ch_pos = 0u;
let len = s.len();
while pos < len {
let CharRange {ch, next} = char_range_at(s, pos);
pos = next;
if !it(ch_pos, ch) { return false; }
ch_pos += 1u;
}
return true;
}
/// Iterates over the chars in a string in reverse
#[inline(always)]
pub fn each_char_reverse(s: &str, it: &fn(char) -> bool) -> bool {
each_chari_reverse(s, |_, c| it(c))
}
/// Iterates over the chars in a string in reverse, with indices
#[inline(always)]
pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) -> bool {
let mut pos = s.len();
let mut ch_pos = s.char_len();
while pos > 0 {
let CharRange {ch, next} = char_range_at_reverse(s, pos);
pos = next;
ch_pos -= 1;
if !it(ch_pos, ch) { return false; }
}
return true;
}
/* /*
Section: Searching Section: Searching
*/ */
@ -1880,7 +1827,7 @@ pub fn is_utf16(v: &[u16]) -> bool {
/// Converts to a vector of `u16` encoded as UTF-16 /// Converts to a vector of `u16` encoded as UTF-16
pub fn to_utf16(s: &str) -> ~[u16] { pub fn to_utf16(s: &str) -> ~[u16] {
let mut u = ~[]; let mut u = ~[];
for s.each_char |ch| { for s.iter().advance |ch| {
// Arithmetic with u32 literals is easier on the eyes than chars. // Arithmetic with u32 literals is easier on the eyes than chars.
let mut ch = ch as u32; let mut ch = ch as u32;
@ -2396,7 +2343,7 @@ pub fn capacity(s: &const ~str) -> uint {
pub fn escape_default(s: &str) -> ~str { pub fn escape_default(s: &str) -> ~str {
let mut out: ~str = ~""; let mut out: ~str = ~"";
reserve_at_least(&mut out, str::len(s)); reserve_at_least(&mut out, str::len(s));
for s.each_char |c| { for s.iter().advance |c| {
push_str(&mut out, char::escape_default(c)); push_str(&mut out, char::escape_default(c));
} }
out out
@ -2406,7 +2353,7 @@ pub fn escape_default(s: &str) -> ~str {
pub fn escape_unicode(s: &str) -> ~str { pub fn escape_unicode(s: &str) -> ~str {
let mut out: ~str = ~""; let mut out: ~str = ~"";
reserve_at_least(&mut out, str::len(s)); reserve_at_least(&mut out, str::len(s));
for s.each_char |c| { for s.iter().advance |c| {
push_str(&mut out, char::escape_unicode(c)); push_str(&mut out, char::escape_unicode(c));
} }
out out
@ -2608,15 +2555,12 @@ pub trait StrSlice<'self> {
fn any(&self, it: &fn(char) -> bool) -> bool; fn any(&self, it: &fn(char) -> bool) -> bool;
fn contains<'a>(&self, needle: &'a str) -> bool; fn contains<'a>(&self, needle: &'a str) -> bool;
fn contains_char(&self, needle: char) -> bool; fn contains_char(&self, needle: char) -> bool;
fn char_iter(&self) -> StrCharIterator<'self>; fn iter(&self) -> StrCharIterator<'self>;
fn rev_iter(&self) -> StrCharRevIterator<'self>;
fn each(&self, it: &fn(u8) -> bool) -> bool; fn each(&self, it: &fn(u8) -> bool) -> bool;
fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool; fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool;
fn each_reverse(&self, it: &fn(u8) -> bool) -> bool; fn each_reverse(&self, it: &fn(u8) -> bool) -> bool;
fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool; fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool;
fn each_char(&self, it: &fn(char) -> bool) -> bool;
fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool;
fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool;
fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool;
fn ends_with(&self, needle: &str) -> bool; fn ends_with(&self, needle: &str) -> bool;
fn is_empty(&self) -> bool; fn is_empty(&self) -> bool;
fn is_whitespace(&self) -> bool; fn is_whitespace(&self) -> bool;
@ -2670,12 +2614,19 @@ impl<'self> StrSlice<'self> for &'self str {
} }
#[inline] #[inline]
fn char_iter(&self) -> StrCharIterator<'self> { fn iter(&self) -> StrCharIterator<'self> {
StrCharIterator { StrCharIterator {
index: 0, index: 0,
string: *self string: *self
} }
} }
#[inline]
fn rev_iter(&self) -> StrCharRevIterator<'self> {
StrCharRevIterator {
index: self.len(),
string: *self
}
}
/// Iterate over the bytes in a string /// Iterate over the bytes in a string
#[inline] #[inline]
@ -2691,25 +2642,6 @@ impl<'self> StrSlice<'self> for &'self str {
fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool { fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool {
eachi_reverse(*self, it) eachi_reverse(*self, it)
} }
/// Iterate over the chars in a string
#[inline]
fn each_char(&self, it: &fn(char) -> bool) -> bool { each_char(*self, it) }
/// Iterate over the chars in a string, with indices
#[inline]
fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool {
each_chari(*self, it)
}
/// Iterate over the chars in a string in reverse
#[inline]
fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool {
each_char_reverse(*self, it)
}
/// Iterate over the chars in a string in reverse, with indices from the
/// end
#[inline]
fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool {
each_chari_reverse(*self, it)
}
/// Returns true if one string ends with another /// Returns true if one string ends with another
#[inline] #[inline]
fn ends_with(&self, needle: &str) -> bool { fn ends_with(&self, needle: &str) -> bool {
@ -2880,6 +2812,25 @@ impl<'self> Iterator<char> for StrCharIterator<'self> {
} }
} }
} }
/// External iterator for a string's characters in reverse order. Use
/// with the `std::iterator` module.
pub struct StrCharRevIterator<'self> {
priv index: uint,
priv string: &'self str,
}
impl<'self> Iterator<char> for StrCharRevIterator<'self> {
#[inline]
fn next(&mut self) -> Option<char> {
if self.index > 0 {
let CharRange {ch, next} = char_range_at_reverse(self.string, self.index);
self.index = next;
Some(ch)
} else {
None
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@ -4067,52 +4018,6 @@ mod tests {
} }
} }
#[test]
fn test_each_char() {
let s = ~"ศไทย中华Việt Nam";
let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
let mut pos = 0;
for s.each_char |ch| {
assert_eq!(ch, v[pos]);
pos += 1;
}
}
#[test]
fn test_each_chari() {
let s = ~"ศไทย中华Việt Nam";
let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
let mut pos = 0;
for s.each_chari |i, ch| {
assert_eq!(pos, i);
assert_eq!(ch, v[pos]);
pos += 1;
}
}
#[test]
fn test_each_char_reverse() {
let s = ~"ศไทย中华Việt Nam";
let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
let mut pos = v.len();
for s.each_char_reverse |ch| {
pos -= 1;
assert_eq!(ch, v[pos]);
}
}
#[test]
fn test_each_chari_reverse() {
let s = ~"ศไทย中华Việt Nam";
let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
let mut pos = v.len();
for s.each_chari_reverse |i, ch| {
pos -= 1;
assert_eq!(pos, i);
assert_eq!(ch, v[pos]);
}
}
#[test] #[test]
fn test_escape_unicode() { fn test_escape_unicode() {
assert_eq!(escape_unicode("abc"), ~"\\x61\\x62\\x63"); assert_eq!(escape_unicode("abc"), ~"\\x61\\x62\\x63");
@ -4168,7 +4073,23 @@ mod tests {
let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
let mut pos = 0; let mut pos = 0;
let mut it = s.char_iter(); let mut it = s.iter();
for it.advance |c| {
assert_eq!(c, v[pos]);
pos += 1;
}
assert_eq!(pos, v.len());
}
#[test]
fn test_rev_iterator() {
use iterator::*;
let s = ~"ศไทย中华Việt Nam";
let v = ~['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
let mut pos = 0;
let mut it = s.rev_iter();
for it.advance |c| { for it.advance |c| {
assert_eq!(c, v[pos]); assert_eq!(c, v[pos]);

View file

@ -21,6 +21,7 @@ use parse::token;
use parse::token::{get_ident_interner}; use parse::token::{get_ident_interner};
use parse; use parse;
use core::iterator::IteratorUtil;
use core::io; use core::io;
use core::str; use core::str;
use core::uint; use core::uint;
@ -78,7 +79,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
if line.trim().is_empty() { if line.trim().is_empty() {
loop; loop;
} }
for line.each_chari |j, c| { for line.iter().enumerate().advance |(j, c)| {
if j >= i { if j >= i {
break; break;
} }
@ -91,7 +92,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
return do lines.map |line| { return do lines.map |line| {
let mut chars = ~[]; let mut chars = ~[];
for str::each_char(*line) |c| { chars.push(c) } for line.iter().advance |c| { chars.push(c) }
if i > chars.len() { if i > chars.len() {
~"" ~""
} else { } else {

View file

@ -14,6 +14,7 @@
extern mod extra; extern mod extra;
use std::iterator::IteratorUtil;
use std::io::ReaderUtil; use std::io::ReaderUtil;
use std::io; use std::io;
use std::str; use std::str;
@ -67,7 +68,7 @@ fn read_board_grid<rdr:'static + io::Reader>(in: rdr) -> ~[~[square]] {
let mut grid = ~[]; let mut grid = ~[];
for in.each_line |line| { for in.each_line |line| {
let mut row = ~[]; let mut row = ~[];
for str::each_char(line) |c| { for line.iter().advance |c| {
row.push(square_from_char(c)) row.push(square_from_char(c))
} }
grid.push(row) grid.push(row)