Added str::any, str::bytes_iter, str::windowed, and vec::windowed functions

This commit is contained in:
Kevin Cantu 2012-01-23 02:41:40 -08:00 committed by Niko Matsakis
parent 0493a7c87d
commit d4b287e852
2 changed files with 158 additions and 7 deletions

View file

@ -14,8 +14,8 @@
char_at, bytes, is_ascii, shift_byte, pop_byte,
unsafe_from_byte, unsafe_from_bytes, from_char, char_range_at,
from_cstr, sbuf, as_buf, push_byte, utf8_char_width, safe_slice,
contains, iter_chars, loop_chars, loop_chars_sub,
escape;
contains, iter_chars, chars_iter, bytes_iter,
loop_chars, loop_chars_sub, escape, any, all, map, windowed;
#[abi = "cdecl"]
native mod rustrt {
@ -346,7 +346,6 @@ fn char_range_at(s: str, i: uint) -> {ch: char, next: uint} {
Iterate over the characters in a string
*/
fn iter_chars(s: str, it: fn(char)) {
let pos = 0u, len = byte_len(s);
while (pos < len) {
@ -356,6 +355,34 @@ fn iter_chars(s: str, it: fn(char)) {
}
}
/*
Function: chars_iter
Iterate over the characters in a string
FIXME: A synonym to iter_chars
*/
fn chars_iter(ss: str, it: fn&(char)) {
iter_chars(ss, it)
}
/*
Function: bytes_iter
Iterate over the bytes in a string
FIXME: Should it really include the last byte '\0'?
*/
fn bytes_iter(ss: str, it: fn&(u8)) {
let pos = 0u;
let len = byte_len(ss);
while (pos < len) {
it(ss[pos]);
pos += 1u;
}
}
/*
Function: loop_chars
@ -1116,14 +1143,25 @@ fn escape(s: str) -> str {
/*
Function: all
Return true if a predicate matches all characters
Return true if a predicate matches all characters or
if the string contains no characters
If the string contains no characters
// FIXME: a synonym to loop_chars
*/
fn all(ss: str, ff: fn&(char) -> bool) -> bool {
str::loop_chars(ss, ff)
}
/*
Function: any
Return true if a predicate matches any character
(and false if it matches none or there are no characters)
*/
fn any(ss: str, pred: fn&(char) -> bool) -> bool {
!all(ss, {|cc| !pred(cc)})
}
/*
Function: map
@ -1139,6 +1177,26 @@ fn map(ss: str, ff: fn&(char) -> char) -> str {
ret result;
}
/*
Function: windowed
Create a vector of substrings of size `nn`
*/
fn windowed(nn: uint, ss: str) -> [str] {
let ww = [];
let len = str::char_len(ss);
assert 1u <= nn;
let ii = 0u;
while ii+nn <= len {
let w = char_slice( ss, ii, ii+nn );
vec::push(ww,w);
ii += 1u;
}
ret ww;
}
#[cfg(test)]
mod tests {
@ -1590,6 +1648,39 @@ fn test_iter_chars() {
}
i += 1;
}
iter_chars("") {|ch| fail; } // should not fail
}
#[test]
fn test_chars_iter() {
let i = 0;
chars_iter("x\u03c0y") {|ch|
alt i {
0 { assert ch == 'x'; }
1 { assert ch == '\u03c0'; }
2 { assert ch == 'y'; }
}
i += 1;
}
chars_iter("") {|_ch| fail; } // should not fail
}
#[test]
fn test_bytes_iter() {
let i = 0;
bytes_iter("xyz") {|bb|
alt i {
0 { assert bb == 'x' as u8; }
1 { assert bb == 'y' as u8; }
2 { assert bb == 'z' as u8; }
}
i += 1;
}
bytes_iter("") {|bb| assert bb == 0u8; }
}
#[test]
@ -1601,17 +1692,44 @@ fn test_escape() {
}
#[test]
fn test_map () {
fn test_map() {
assert "" == map("", char::to_upper);
assert "YMCA" == map("ymca", char::to_upper);
}
#[test]
fn test_all () {
fn test_all() {
assert true == all("", char::is_uppercase);
assert false == all("ymca", char::is_uppercase);
assert true == all("YMCA", char::is_uppercase);
assert false == all("yMCA", char::is_uppercase);
assert false == all("YMCy", char::is_uppercase);
}
#[test]
fn test_any() {
assert false == any("", char::is_uppercase);
assert false == any("ymca", char::is_uppercase);
assert true == any("YMCA", char::is_uppercase);
assert true == any("yMCA", char::is_uppercase);
assert true == any("YMCy", char::is_uppercase);
}
#[test]
fn test_windowed() {
let data = "ประเทศไทย中";
assert ["ประ", "ระเ", "ะเท", "เทศ", "ทศไ", "ศไท", "ไทย", "ทย中"]
== windowed(3u, data);
assert [data] == windowed(10u, data);
assert [] == windowed(6u, "abcd");
}
#[test]
#[should_fail]
fn test_windowed_() {
let _x = windowed(0u, "abcd");
}
}

View file

@ -829,6 +829,23 @@ fn permute<T: copy>(v: [const T], put: fn([T])) {
}
}
fn windowed <TT: copy> (nn: uint, xx: [TT]) -> [[TT]] {
let ww = [];
assert 1u <= nn;
vec::iteri (xx, {|ii, _x|
let len = vec::len(xx);
if ii+nn <= len {
let w = vec::slice ( xx, ii, ii+nn );
vec::push (ww, w);
}
});
ret ww;
}
/*
Function: to_ptr
@ -1497,6 +1514,22 @@ fn test_concat() {
assert concat([[1], [2,3]]) == [1, 2, 3];
}
#[test]
fn test_windowed () {
assert [[1u,2u,3u],[2u,3u,4u],[3u,4u,5u],[4u,5u,6u]]
== windowed (3u, [1u,2u,3u,4u,5u,6u]);
assert [[1u,2u,3u,4u],[2u,3u,4u,5u],[3u,4u,5u,6u]]
== windowed (4u, [1u,2u,3u,4u,5u,6u]);
assert [] == windowed (7u, [1u,2u,3u,4u,5u,6u]);
}
#[test]
#[should_fail]
fn test_windowed_() {
let _x = windowed (0u, [1u,2u,3u,4u,5u,6u]);
}
}
// Local Variables: