about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKevin Cantu <me@kevincantu.org>2012-01-23 02:41:40 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-01-23 22:28:25 -0800
commitd4b287e8525758896e78b39eca6f6e1c0f32cd98 (patch)
treeae0138e480b70276f3d53b5175ff51071d58fff2
parent0493a7c87d7769a3b3b819a7b38cd242f95dfad2 (diff)
downloadrust-d4b287e8525758896e78b39eca6f6e1c0f32cd98.tar.gz
rust-d4b287e8525758896e78b39eca6f6e1c0f32cd98.zip
Added str::any, str::bytes_iter, str::windowed, and vec::windowed functions
-rw-r--r--src/libcore/str.rs132
-rw-r--r--src/libcore/vec.rs33
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: