about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-04-16 06:12:55 -0700
committerbors <bors@rust-lang.org>2013-04-16 06:12:55 -0700
commit7cacd87efd34f8b8c3c0db5e5b2192ddd32a6ec5 (patch)
treec156bc4cedefd1a7e8503fcd87ba6789108f08a1
parent76e77af380e267ecd07c061aca6f428b42f8d35a (diff)
parent21723d5bdc7032d1b541a68aaed4e313b72280ee (diff)
downloadrust-7cacd87efd34f8b8c3c0db5e5b2192ddd32a6ec5.tar.gz
rust-7cacd87efd34f8b8c3c0db5e5b2192ddd32a6ec5.zip
auto merge of #5904 : huonw/rust/core-vec-windowed, r=thestinger
And add some documentation.
-rw-r--r--src/libcore/vec.rs57
1 files changed, 41 insertions, 16 deletions
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 7940502d27e..30201304d61 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -1495,16 +1495,35 @@ pub fn each_permutation<T:Copy>(v: &[T], put: &fn(ts: &[T]) -> bool) {
     }
 }
 
-pub fn windowed<TT:Copy>(nn: uint, xx: &[TT]) -> ~[~[TT]] {
-    let mut ww = ~[];
-    assert!(1u <= nn);
-    for vec::eachi (xx) |ii, _x| {
-        let len = xx.len();
-        if ii+nn <= len {
-            ww.push(slice(xx, ii, ii+nn).to_vec());
-        }
+/**
+ * Iterate over all contiguous windows of length `n` of the vector `v`.
+ *
+ * # Example
+ *
+ * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, `[3,4]`)
+ *
+ * ~~~
+ * for windowed(2, &[1,2,3,4]) |v| {
+ *     io::println(fmt!("%?", v));
+ * }
+ * ~~~
+ *
+ */
+#[cfg(stage0)] // XXX: lifetimes!
+pub fn windowed<T>(n: uint, v: &[T], it: &fn(&[T]) -> bool) {
+    assert!(1u <= n);
+    for uint::range(0, v.len() - n + 1) |i| {
+        if !it(v.slice(i, i+n)) { return }
+    }
+}
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) {
+    assert!(1u <= n);
+    for uint::range(0, v.len() - n + 1) |i| {
+        if !it(v.slice(i, i + n)) { return }
     }
-    ww
 }
 
 /**
@@ -3761,20 +3780,26 @@ mod tests {
 
     #[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]));
+        fn t(n: uint, expected: &[&[int]]) {
+            let mut i = 0;
+            for windowed(n, ~[1,2,3,4,5,6]) |v| {
+                assert_eq!(v, expected[i]);
+                i += 1;
+            }
 
-        assert!(~[] == windowed (7u, ~[1u,2u,3u,4u,5u,6u]));
+            // check that we actually iterated the right number of times
+            assert_eq!(i, expected.len());
+        }
+        t(3, &[&[1,2,3],&[2,3,4],&[3,4,5],&[4,5,6]]);
+        t(4, &[&[1,2,3,4],&[2,3,4,5],&[3,4,5,6]]);
+        t(7, &[]);
     }
 
     #[test]
     #[should_fail]
     #[ignore(cfg(windows))]
     fn test_windowed_() {
-        let _x = windowed (0u, ~[1u,2u,3u,4u,5u,6u]);
+        for windowed (0u, ~[1u,2u,3u,4u,5u,6u]) |_v| {}
     }
 
     #[test]