diff options
| author | Kevin Cantu <me@kevincantu.org> | 2012-01-23 02:41:40 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2012-01-23 22:28:25 -0800 |
| commit | d4b287e8525758896e78b39eca6f6e1c0f32cd98 (patch) | |
| tree | ae0138e480b70276f3d53b5175ff51071d58fff2 | |
| parent | 0493a7c87d7769a3b3b819a7b38cd242f95dfad2 (diff) | |
| download | rust-d4b287e8525758896e78b39eca6f6e1c0f32cd98.tar.gz rust-d4b287e8525758896e78b39eca6f6e1c0f32cd98.zip | |
Added str::any, str::bytes_iter, str::windowed, and vec::windowed functions
| -rw-r--r-- | src/libcore/str.rs | 132 | ||||
| -rw-r--r-- | src/libcore/vec.rs | 33 |
2 files changed, 158 insertions, 7 deletions
diff --git a/src/libcore/str.rs b/src/libcore/str.rs index a090d57be45..df564c7bded 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -14,8 +14,8 @@ export eq, lteq, hash, is_empty, is_not_empty, is_whitespace, byte_len, 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 @@ Function: iter_chars 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) { @@ -357,6 +356,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 Loop through a string, char by char @@ -1116,15 +1143,26 @@ 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 Apply a function to each character @@ -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 @@ mod tests { } 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 @@ mod tests { } #[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"); + } } diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 0a1a4012422..8b7ea91becd 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -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 @@ mod tests { 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: |
