about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-03 08:16:54 -0700
committerbors <bors@rust-lang.org>2013-07-03 08:16:54 -0700
commit0c6fc46c030ab0515a052fa99c9e10c75cfc8184 (patch)
tree3840f27f53871ed20b17e82beac7ea9a402dce46 /src/libstd
parent1cee9d4c38c628914cc72277854bd97f4f017225 (diff)
parentcdea73cf5b94784fdc910ab23d5d3455c868d247 (diff)
downloadrust-0c6fc46c030ab0515a052fa99c9e10c75cfc8184.tar.gz
rust-0c6fc46c030ab0515a052fa99c9e10c75cfc8184.zip
auto merge of #7566 : huonw/rust/vec-kill, r=cmr
The last remaining internal iterator in `vec` is `each_permutation`.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs14
-rw-r--r--src/libstd/either.rs2
-rw-r--r--src/libstd/hashmap.rs7
-rw-r--r--src/libstd/io.rs6
-rw-r--r--src/libstd/os.rs16
-rw-r--r--src/libstd/prelude.rs2
-rw-r--r--src/libstd/ptr.rs2
-rw-r--r--src/libstd/rand.rs4
-rw-r--r--src/libstd/rt/uv/mod.rs3
-rw-r--r--src/libstd/run.rs8
-rw-r--r--src/libstd/str.rs7
-rw-r--r--src/libstd/vec.rs1439
12 files changed, 605 insertions, 905 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 325ce097cd5..37a32d6b0f0 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -17,8 +17,7 @@ use kinds::Copy;
 use option::Option;
 use sys;
 use uint;
-use vec;
-use vec::ImmutableVector;
+use vec::{ImmutableVector, OwnedVector};
 
 /// Code for dealing with @-vectors. This is pretty incomplete, and
 /// contains a bunch of duplication from the code for ~-vectors.
@@ -159,7 +158,7 @@ pub fn to_managed_consume<T>(v: ~[T]) -> @[T] {
     let mut av = @[];
     unsafe {
         raw::reserve(&mut av, v.len());
-        do vec::consume(v) |_i, x| {
+        for v.consume_iter().advance |x| {
             raw::push(&mut av, x);
         }
         transmute(av)
@@ -177,13 +176,14 @@ pub fn to_managed<T:Copy>(v: &[T]) -> @[T] {
 #[cfg(not(test))]
 pub mod traits {
     use at_vec::append;
+    use vec::Vector;
     use kinds::Copy;
     use ops::Add;
 
-    impl<'self,T:Copy> Add<&'self [T],@[T]> for @[T] {
+    impl<'self,T:Copy, V: Vector<T>> Add<V,@[T]> for @[T] {
         #[inline]
-        fn add(&self, rhs: & &'self [T]) -> @[T] {
-            append(*self, (*rhs))
+        fn add(&self, rhs: &V) -> @[T] {
+            append(*self, rhs.as_slice())
         }
     }
 }
@@ -313,7 +313,7 @@ mod test {
 
     #[test]
     fn append_test() {
-        assert_eq!(@[1,2,3] + [4,5,6], @[1,2,3,4,5,6]);
+        assert_eq!(@[1,2,3] + &[4,5,6], @[1,2,3,4,5,6]);
     }
 
     #[test]
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index b6da93f9d40..8b9b3102831 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -73,7 +73,7 @@ pub fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
 pub fn partition<T, U>(eithers: ~[Either<T, U>]) -> (~[T], ~[U]) {
     let mut lefts: ~[T] = ~[];
     let mut rights: ~[U] = ~[];
-    do vec::consume(eithers) |_i, elt| {
+    for eithers.consume_iter().advance |elt| {
         match elt {
             Left(l) => lefts.push(l),
             Right(r) => rights.push(r)
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index 85dca1154bc..2d80dc2be15 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -24,7 +24,7 @@ use rand::RngUtil;
 use rand;
 use uint;
 use vec;
-use vec::{ImmutableVector, MutableVector};
+use vec::{ImmutableVector, MutableVector, OwnedVector};
 use kinds::Copy;
 use util::{replace, unreachable};
 
@@ -175,7 +175,8 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
                                   vec::from_fn(new_capacity, |_| None));
 
         self.size = 0;
-        do vec::consume(old_buckets) |_, bucket| {
+        // consume_rev_iter is more efficient
+        for old_buckets.consume_rev_iter().advance |bucket| {
             self.insert_opt_bucket(bucket);
         }
     }
@@ -441,7 +442,7 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
                               vec::from_fn(INITIAL_CAPACITY, |_| None));
         self.size = 0;
 
-        do vec::consume(buckets) |_, bucket| {
+        for buckets.consume_iter().advance |bucket| {
             match bucket {
                 None => {},
                 Some(Bucket{key, value, _}) => {
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index bdcad15f45c..38826dd411b 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -917,7 +917,7 @@ fn convert_whence(whence: SeekStyle) -> i32 {
 impl Reader for *libc::FILE {
     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
         unsafe {
-            do vec::as_mut_buf(bytes) |buf_p, buf_len| {
+            do bytes.as_mut_buf |buf_p, buf_len| {
                 assert!(buf_len >= len);
 
                 let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
@@ -1152,7 +1152,7 @@ impl<W:Writer,C> Writer for Wrapper<W, C> {
 impl Writer for *libc::FILE {
     fn write(&self, v: &[u8]) {
         unsafe {
-            do vec::as_imm_buf(v) |vbuf, len| {
+            do v.as_imm_buf |vbuf, len| {
                 let nout = libc::fwrite(vbuf as *c_void,
                                         1,
                                         len as size_t,
@@ -1203,7 +1203,7 @@ impl Writer for fd_t {
     fn write(&self, v: &[u8]) {
         unsafe {
             let mut count = 0u;
-            do vec::as_imm_buf(v) |vbuf, len| {
+            do v.as_imm_buf |vbuf, len| {
                 while count < len {
                     let vb = ptr::offset(vbuf, count) as *c_void;
                     let nout = libc::write(*self, vb, len as size_t);
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 39041b48369..be0c504885b 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -92,7 +92,7 @@ pub fn as_c_charp<T>(s: &str, f: &fn(*c_char) -> T) -> T {
 pub fn fill_charp_buf(f: &fn(*mut c_char, size_t) -> bool)
     -> Option<~str> {
     let mut buf = vec::from_elem(TMPBUF_SZ, 0u8 as c_char);
-    do vec::as_mut_buf(buf) |b, sz| {
+    do buf.as_mut_buf |b, sz| {
         if f(b, sz as size_t) {
             unsafe {
                 Some(str::raw::from_buf(b as *u8))
@@ -122,7 +122,7 @@ pub mod win32 {
             while !done {
                 let mut k: DWORD = 0;
                 let mut buf = vec::from_elem(n as uint, 0u16);
-                do vec::as_mut_buf(buf) |b, _sz| {
+                do buf.as_mut_buf |b, _sz| {
                     k = f(b, TMPBUF_SZ as DWORD);
                     if k == (0 as DWORD) {
                         done = true;
@@ -147,7 +147,7 @@ pub mod win32 {
         let mut t = s.to_utf16();
         // Null terminate before passing on.
         t.push(0u16);
-        vec::as_imm_buf(t, |buf, _len| f(buf))
+        t.as_imm_buf(|buf, _len| f(buf))
     }
 }
 
@@ -777,9 +777,9 @@ pub fn list_dir(p: &Path) -> ~[~str] {
                 strings
             }
         }
-        do get_list(p).filtered |filename| {
-            *filename != ~"." && *filename != ~".."
-        }
+        do get_list(p).consume_iter().filter |filename| {
+            "." != *filename && ".." != *filename
+        }.collect()
     }
 }
 
@@ -937,7 +937,7 @@ pub fn copy_file(from: &Path, to: &Path) -> bool {
             let mut done = false;
             let mut ok = true;
             while !done {
-                do vec::as_mut_buf(buf) |b, _sz| {
+                do buf.as_mut_buf |b, _sz| {
                   let nread = libc::fread(b as *mut c_void, 1u as size_t,
                                           bufsize as size_t,
                                           istream);
@@ -1683,7 +1683,7 @@ mod tests {
           let s = ~"hello";
           let mut buf = s.as_bytes_with_null().to_owned();
           let len = buf.len();
-          do vec::as_mut_buf(buf) |b, _len| {
+          do buf.as_mut_buf |b, _len| {
               assert_eq!(libc::fwrite(b as *c_void, 1u as size_t,
                                       (s.len() + 1u) as size_t, ostream),
                          len as size_t)
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 9d505209960..db534cca971 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -72,7 +72,7 @@ pub use tuple::{CloneableTuple10, CloneableTuple11, CloneableTuple12};
 pub use tuple::{ImmutableTuple2, ImmutableTuple3, ImmutableTuple4, ImmutableTuple5};
 pub use tuple::{ImmutableTuple6, ImmutableTuple7, ImmutableTuple8, ImmutableTuple9};
 pub use tuple::{ImmutableTuple10, ImmutableTuple11, ImmutableTuple12};
-pub use vec::{VectorVector, CopyableVector, ImmutableVector};
+pub use vec::{Vector, VectorVector, CopyableVector, ImmutableVector};
 pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector};
 pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector, MutableVector};
 pub use io::{Reader, ReaderUtil, Writer, WriterUtil};
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index 473f56ddd79..aee6f1bd204 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -406,7 +406,7 @@ pub mod ptr_tests {
             do str::as_c_str(s1) |p1| {
                 do str::as_c_str(s2) |p2| {
                     let v = ~[p0, p1, p2, null()];
-                    do vec::as_imm_buf(v) |vp, len| {
+                    do v.as_imm_buf |vp, len| {
                         assert_eq!(unsafe { buf_len(vp) }, 3u);
                         assert_eq!(len, 4u);
                     }
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
index 5782822bc2b..5054763d742 100644
--- a/src/libstd/rand.rs
+++ b/src/libstd/rand.rs
@@ -830,7 +830,7 @@ pub fn seed() -> ~[u8] {
     unsafe {
         let n = rustrt::rand_seed_size() as uint;
         let mut s = vec::from_elem(n, 0_u8);
-        do vec::as_mut_buf(s) |p, sz| {
+        do s.as_mut_buf |p, sz| {
             rustrt::rand_gen_seed(p, sz as size_t)
         }
         s
@@ -1087,7 +1087,7 @@ mod tests {
         for 10.times {
             unsafe {
                 let seed = super::seed();
-                let rt_rng = do vec::as_imm_buf(seed) |p, sz| {
+                let rt_rng = do seed.as_imm_buf |p, sz| {
                     rustrt::rand_new_seeded(p, sz as size_t)
                 };
                 let mut rng = IsaacRng::new_seeded(seed);
diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs
index f50efc079a7..092d7366202 100644
--- a/src/libstd/rt/uv/mod.rs
+++ b/src/libstd/rt/uv/mod.rs
@@ -40,6 +40,7 @@ use str::raw::from_c_str;
 use to_str::ToStr;
 use ptr::RawPtr;
 use vec;
+use vec::ImmutableVector;
 use ptr;
 use str;
 use libc::{c_void, c_int, size_t, malloc, free};
@@ -300,7 +301,7 @@ pub fn vec_to_uv_buf(v: ~[u8]) -> Buf {
     unsafe {
         let data = malloc(v.len() as size_t) as *u8;
         assert!(data.is_not_null());
-        do vec::as_imm_buf(v) |b, l| {
+        do v.as_imm_buf |b, l| {
             let data = data as *mut u8;
             ptr::copy_memory(data, b, l)
         }
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index 9e5def253c7..df15111a91f 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -24,7 +24,7 @@ use prelude::*;
 use ptr;
 use str;
 use task;
-use vec;
+use vec::ImmutableVector;
 
 /**
  * A value representing a child process.
@@ -703,7 +703,7 @@ fn with_argv<T>(prog: &str, args: &[~str],
         argptrs.push(str::as_c_str(*t, |b| b));
     }
     argptrs.push(ptr::null());
-    vec::as_imm_buf(argptrs, |buf, _len| cb(buf))
+    argptrs.as_imm_buf(|buf, _len| cb(buf))
 }
 
 #[cfg(unix)]
@@ -722,7 +722,7 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T {
         }
 
         ptrs.push(ptr::null());
-        vec::as_imm_buf(ptrs, |p, _len|
+        ptrs.as_imm_buf(|p, _len|
             unsafe { cb(::cast::transmute(p)) }
         )
       }
@@ -743,7 +743,7 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
             blk.push_all(kv.as_bytes_with_null_consume());
         }
         blk.push(0);
-        vec::as_imm_buf(blk, |p, _len|
+        blk.as_imm_buf(|p, _len|
             unsafe { cb(::cast::transmute(p)) }
         )
       }
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 28162cf5117..564c58f7097 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -826,6 +826,7 @@ pub mod raw {
     use str::raw;
     use str::{as_buf, is_utf8};
     use vec;
+    use vec::MutableVector;
 
     /// Create a Rust string from a null-terminated *u8 buffer
     pub unsafe fn from_buf(buf: *u8) -> ~str {
@@ -841,7 +842,7 @@ pub mod raw {
     /// Create a Rust string from a *u8 buffer of the given length
     pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
         let mut v: ~[u8] = vec::with_capacity(len + 1);
-        vec::as_mut_buf(v, |vbuf, _len| {
+        v.as_mut_buf(|vbuf, _len| {
             ptr::copy_memory(vbuf, buf as *u8, len)
         });
         vec::raw::set_len(&mut v, len);
@@ -863,7 +864,7 @@ pub mod raw {
 
     /// Converts a vector of bytes to a new owned string.
     pub unsafe fn from_bytes(v: &[u8]) -> ~str {
-        do vec::as_imm_buf(v) |buf, len| {
+        do v.as_imm_buf |buf, len| {
             from_buf_len(buf, len)
         }
     }
@@ -917,7 +918,7 @@ pub mod raw {
             assert!((end <= n));
 
             let mut v = vec::with_capacity(end - begin + 1u);
-            do vec::as_imm_buf(v) |vbuf, _vlen| {
+            do v.as_imm_buf |vbuf, _vlen| {
                 let vbuf = ::cast::transmute_mut_unsafe(vbuf);
                 let src = ptr::offset(sbuf, begin);
                 ptr::copy_memory(vbuf, src, end - begin);
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 28532bd54e3..fb9c47b4373 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -16,14 +16,13 @@ use cast::transmute;
 use cast;
 use container::{Container, Mutable};
 use cmp;
-use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
+use cmp::{Eq, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
 use clone::Clone;
 use iterator::{FromIterator, Iterator, IteratorUtil};
 use kinds::Copy;
 use libc;
 use libc::c_void;
 use num::Zero;
-use ops::Add;
 use option::{None, Option, Some};
 use ptr::to_unsafe_ptr;
 use ptr;
@@ -40,8 +39,6 @@ use unstable::intrinsics::{get_tydesc, contains_managed};
 use vec;
 use util;
 
-#[cfg(not(test))] use cmp::Equiv;
-
 #[doc(hidden)]
 pub mod rustrt {
     use libc;
@@ -74,7 +71,7 @@ pub fn same_length<T, U>(xs: &[T], ys: &[U]) -> bool {
 pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> ~[T] {
     unsafe {
         let mut v = with_capacity(n_elts);
-        do as_mut_buf(v) |p, _len| {
+        do v.as_mut_buf |p, _len| {
             let mut i: uint = 0u;
             while i < n_elts {
                 intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
@@ -99,7 +96,7 @@ pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] {
     // vec::with_capacity/ptr::set_memory for primitive types.
     unsafe {
         let mut v = with_capacity(n_elts);
-        do as_mut_buf(v) |p, _len| {
+        do v.as_mut_buf |p, _len| {
             let mut i = 0u;
             while i < n_elts {
                 intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), copy t);
@@ -176,165 +173,69 @@ pub fn build_sized_opt<A>(size: Option<uint>,
     build_sized(size.get_or_default(4), builder)
 }
 
-// Accessors
-
-/// Copies
+/// An iterator over the slices of a vector separated by elements that
+/// match a predicate function.
+pub struct VecSplitIterator<'self, T> {
+    priv v: &'self [T],
+    priv n: uint,
+    priv pred: &'self fn(t: &T) -> bool,
+    priv finished: bool
+}
 
-/// Split the vector `v` by applying each element against the predicate `f`.
-pub fn split<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] {
-    let ln = v.len();
-    if (ln == 0u) { return ~[] }
+impl<'self, T> Iterator<&'self [T]> for VecSplitIterator<'self, T> {
+    fn next(&mut self) -> Option<&'self [T]> {
+        if self.finished { return None; }
 
-    let mut start = 0u;
-    let mut result = ~[];
-    while start < ln {
-        match v.slice(start, ln).iter().position_(|t| f(t)) {
-            None => break,
-            Some(i) => {
-                result.push(v.slice(start, start + i).to_owned());
-                start += i + 1u;
-            }
+        if self.n == 0 {
+            self.finished = true;
+            return Some(self.v);
         }
-    }
-    result.push(v.slice(start, ln).to_owned());
-    result
-}
-
-/**
- * Split the vector `v` by applying each element against the predicate `f` up
- * to `n` times.
- */
-pub fn splitn<T:Copy>(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] {
-    let ln = v.len();
-    if (ln == 0u) { return ~[] }
 
-    let mut start = 0u;
-    let mut count = n;
-    let mut result = ~[];
-    while start < ln && count > 0u {
-        match v.slice(start, ln).iter().position_(|t| f(t)) {
-            None => break,
-            Some(i) => {
-                result.push(v.slice(start, start + i).to_owned());
-                // Make sure to skip the separator.
-                start += i + 1u;
-                count -= 1u;
+        match self.v.iter().position_(|x| (self.pred)(x)) {
+            None => {
+                self.finished = true;
+                Some(self.v)
+            }
+            Some(idx) => {
+                let ret = Some(self.v.slice(0, idx));
+                self.v = self.v.slice(idx + 1, self.v.len());
+                self.n -= 1;
+                ret
             }
         }
     }
-    result.push(v.slice(start, ln).to_owned());
-    result
 }
 
-/**
- * Reverse split the vector `v` by applying each element against the predicate
- * `f`.
- */
-pub fn rsplit<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] {
-    let ln = v.len();
-    if (ln == 0) { return ~[] }
-
-    let mut end = ln;
-    let mut result = ~[];
-    while end > 0 {
-        match v.slice(0, end).rposition(|t| f(t)) {
-            None => break,
-            Some(i) => {
-                result.push(v.slice(i + 1, end).to_owned());
-                end = i;
-            }
-        }
-    }
-    result.push(v.slice(0u, end).to_owned());
-    result.reverse();
-    result
+/// An iterator over the slices of a vector separated by elements that
+/// match a predicate function, from back to front.
+pub struct VecRSplitIterator<'self, T> {
+    priv v: &'self [T],
+    priv n: uint,
+    priv pred: &'self fn(t: &T) -> bool,
+    priv finished: bool
 }
 
-/**
- * Reverse split the vector `v` by applying each element against the predicate
- * `f` up to `n times.
- */
-pub fn rsplitn<T:Copy>(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] {
-    let ln = v.len();
-    if (ln == 0u) { return ~[] }
+impl<'self, T> Iterator<&'self [T]> for VecRSplitIterator<'self, T> {
+    fn next(&mut self) -> Option<&'self [T]> {
+        if self.finished { return None; }
 
-    let mut end = ln;
-    let mut count = n;
-    let mut result = ~[];
-    while end > 0u && count > 0u {
-        match v.slice(0, end).rposition(|t| f(t)) {
-            None => break,
-            Some(i) => {
-                result.push(v.slice(i + 1u, end).to_owned());
-                // Make sure to skip the separator.
-                end = i;
-                count -= 1u;
-            }
+        if self.n == 0 {
+            self.finished = true;
+            return Some(self.v);
         }
-    }
-    result.push(v.slice(0u, end).to_owned());
-    result.reverse();
-    result
-}
 
-/// Consumes all elements, in a vector, moving them out into the / closure
-/// provided. The vector is traversed from the start to the end.
-///
-/// This method does not impose any requirements on the type of the vector being
-/// consumed, but it prevents any usage of the vector after this function is
-/// called.
-///
-/// # Examples
-///
-/// ~~~ {.rust}
-/// let v = ~[~"a", ~"b"];
-/// do vec::consume(v) |i, s| {
-///   // s has type ~str, not &~str
-///   io::println(s + fmt!(" %d", i));
-/// }
-/// ~~~
-pub fn consume<T>(mut v: ~[T], f: &fn(uint, v: T)) {
-    unsafe {
-        do as_mut_buf(v) |p, ln| {
-            for uint::range(0, ln) |i| {
-                // NB: This unsafe operation counts on init writing 0s to the
-                // holes we create in the vector. That ensures that, if the
-                // iterator fails then we won't try to clean up the consumed
-                // elements during unwinding
-                let x = intrinsics::init();
-                let p = ptr::mut_offset(p, i);
-                f(i, ptr::replace_ptr(p, x));
+        match self.v.rposition(|x| (self.pred)(x)) {
+            None => {
+                self.finished = true;
+                Some(self.v)
             }
-        }
-
-        raw::set_len(&mut v, 0);
-    }
-}
-
-/// Consumes all elements, in a vector, moving them out into the / closure
-/// provided. The vectors is traversed in reverse order (from end to start).
-///
-/// This method does not impose any requirements on the type of the vector being
-/// consumed, but it prevents any usage of the vector after this function is
-/// called.
-pub fn consume_reverse<T>(mut v: ~[T], f: &fn(uint, v: T)) {
-    unsafe {
-        do as_mut_buf(v) |p, ln| {
-            let mut i = ln;
-            while i > 0 {
-                i -= 1;
-
-                // NB: This unsafe operation counts on init writing 0s to the
-                // holes we create in the vector. That ensures that, if the
-                // iterator fails then we won't try to clean up the consumed
-                // elements during unwinding
-                let x = intrinsics::init();
-                let p = ptr::mut_offset(p, i);
-                f(i, ptr::replace_ptr(p, x));
+            Some(idx) => {
+                let ret = Some(self.v.slice(idx + 1, self.v.len()));
+                self.v = self.v.slice(0, idx);
+                self.n -= 1;
+                ret
             }
         }
-
-        raw::set_len(&mut v, 0);
     }
 }
 
@@ -360,20 +261,6 @@ pub fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
 
 // Functional utilities
 
-/// Consumes a vector, mapping it into a different vector. This function takes
-/// ownership of the supplied vector `v`, moving each element into the closure
-/// provided to generate a new element. The vector of new elements is then
-/// returned.
-///
-/// The original vector `v` cannot be used after this function call (it is moved
-/// inside), but there are no restrictions on the type of the vector.
-pub fn map_consume<T, U>(v: ~[T], f: &fn(v: T) -> U) -> ~[U] {
-    let mut result = ~[];
-    do consume(v) |_i, x| {
-        result.push(f(x));
-    }
-    result
-}
 /**
  * Apply a function to each element of a vector and return a concatenation
  * of each result vector
@@ -384,79 +271,6 @@ pub fn flat_map<T, U>(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] {
     result
 }
 
-pub fn filter_map<T, U>(
-    v: ~[T],
-    f: &fn(t: T) -> Option<U>) -> ~[U]
-{
-    /*!
-     *
-     * Apply a function to each element of a vector and return the results.
-     * Consumes the input vector.  If function `f` returns `None` then that
-     * element is excluded from the resulting vector.
-     */
-
-    let mut result = ~[];
-    do consume(v) |_, elem| {
-        match f(elem) {
-            None => {}
-            Some(result_elem) => { result.push(result_elem); }
-        }
-    }
-    result
-}
-
-pub fn filter_mapped<T, U: Copy>(
-    v: &[T],
-    f: &fn(t: &T) -> Option<U>) -> ~[U]
-{
-    /*!
-     *
-     * Like `filter_map()`, but operates on a borrowed slice
-     * and does not consume the input.
-     */
-
-    let mut result = ~[];
-    for v.iter().advance |elem| {
-        match f(elem) {
-          None => {/* no-op */ }
-          Some(result_elem) => { result.push(result_elem); }
-        }
-    }
-    result
-}
-
-/**
- * Construct a new vector from the elements of a vector for which some
- * predicate holds.
- *
- * Apply function `f` to each element of `v` and return a vector containing
- * only those elements for which `f` returned true.
- */
-pub fn filter<T>(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] {
-    let mut result = ~[];
-    // FIXME (#4355 maybe): using v.consume here crashes
-    // do v.consume |_, elem| {
-    do consume(v) |_, elem| {
-        if f(&elem) { result.push(elem); }
-    }
-    result
-}
-
-/**
- * Construct a new vector from the elements of a vector for which some
- * predicate holds.
- *
- * Apply function `f` to each element of `v` and return a vector containing
- * only those elements for which `f` returned true.
- */
-pub fn filtered<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] {
-    let mut result = ~[];
-    for v.iter().advance |elem| {
-        if f(elem) { result.push(copy *elem); }
-    }
-    result
-}
-
 /// Flattens a vector of vectors of T into a single vector of T.
 pub fn concat<T:Copy>(v: &[~[T]]) -> ~[T] { v.concat_vec() }
 
@@ -542,7 +356,7 @@ pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
 pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
     let mut ts = ~[];
     let mut us = ~[];
-    do consume(v) |_i, p| {
+    for v.consume_iter().advance |p| {
         let (t, u) = p;
         ts.push(t);
         us.push(u);
@@ -584,16 +398,6 @@ pub fn zip<T, U>(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] {
     w
 }
 
-/// Returns a vector with the order of elements reversed
-pub fn reversed<T:Copy>(v: &[T]) -> ~[T] {
-    let mut rs: ~[T] = ~[];
-    let mut i = v.len();
-    if i == 0 { return (rs); } else { i -= 1; }
-    while i != 0 { rs.push(copy v[i]); i -= 1; }
-    rs.push(copy v[0]);
-    rs
-}
-
 /**
  * Iterate over all permutations of vector `v`.
  *
@@ -648,251 +452,222 @@ pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) ->
     }
 }
 
-/**
- * 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]`)
- *
- * ~~~ {.rust}
- * for windowed(2, &[1,2,3,4]) |v| {
- *     io::println(fmt!("%?", v));
- * }
- * ~~~
- *
- */
-pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool {
-    assert!(1u <= n);
-    if n > v.len() { return true; }
-    for uint::range(0, v.len() - n + 1) |i| {
-        if !it(v.slice(i, i + n)) { return false; }
-    }
-    return true;
+/// An iterator over the (overlapping) slices of length `size` within
+/// a vector.
+pub struct VecWindowIter<'self, T> {
+    priv v: &'self [T],
+    priv size: uint
 }
 
-/**
- * Work with the buffer of a vector.
- *
- * Allows for unsafe manipulation of vector contents, which is useful for
- * foreign interop.
- */
-#[inline]
-pub fn as_imm_buf<T,U>(s: &[T],
-                       /* NB---this CANNOT be const, see below */
-                       f: &fn(*T, uint) -> U) -> U {
-
-    // NB---Do not change the type of s to `&const [T]`.  This is
-    // unsound.  The reason is that we are going to create immutable pointers
-    // into `s` and pass them to `f()`, but in fact they are potentially
-    // pointing at *mutable memory*.  Use `as_const_buf` or `as_mut_buf`
-    // instead!
-
-    unsafe {
-        let v : *(*T,uint) = transmute(&s);
-        let (buf,len) = *v;
-        f(buf, len / sys::nonzero_size_of::<T>())
+impl<'self, T> Iterator<&'self [T]> for VecWindowIter<'self, T> {
+    fn next(&mut self) -> Option<&'self [T]> {
+        if self.size > self.v.len() {
+            None
+        } else {
+            let ret = Some(self.v.slice(0, self.size));
+            self.v = self.v.slice(1, self.v.len());
+            ret
+        }
     }
 }
 
-/// Similar to `as_imm_buf` but passing a `*mut T`
-#[inline]
-pub fn as_mut_buf<T,U>(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U {
-    unsafe {
-        let v : *(*mut T,uint) = transmute(&s);
-        let (buf,len) = *v;
-        f(buf, len / sys::nonzero_size_of::<T>())
+/// An iterator over a vector in (non-overlapping) chunks (`size`
+/// elements at a time).
+pub struct VecChunkIter<'self, T> {
+    priv v: &'self [T],
+    priv size: uint
+}
+
+impl<'self, T> Iterator<&'self [T]> for VecChunkIter<'self, T> {
+    fn next(&mut self) -> Option<&'self [T]> {
+        if self.size == 0 {
+            None
+        } else if self.size >= self.v.len() {
+            // finished
+            self.size = 0;
+            Some(self.v)
+        } else {
+            let ret = Some(self.v.slice(0, self.size));
+            self.v = self.v.slice(self.size, self.v.len());
+            ret
+        }
     }
 }
 
 // Equality
 
-/// Tests whether two slices are equal to one another. This is only true if both
-/// slices are of the same length, and each of the corresponding elements return
-/// true when queried via the `eq` function.
-fn eq<T: Eq>(a: &[T], b: &[T]) -> bool {
-    let (a_len, b_len) = (a.len(), b.len());
-    if a_len != b_len { return false; }
+#[cfg(not(test))]
+pub mod traits {
+    use super::Vector;
+    use kinds::Copy;
+    use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equal, Equiv};
+    use ops::Add;
 
-    let mut i = 0;
-    while i < a_len {
-        if a[i] != b[i] { return false; }
-        i += 1;
+    impl<'self,T:Eq> Eq for &'self [T] {
+        fn eq(&self, other: & &'self [T]) -> bool {
+            self.len() == other.len() &&
+                self.iter().zip(other.iter()).all(|(s,o)| *s == *o)
+        }
+        #[inline]
+        fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) }
     }
-    true
-}
-
-/// Similar to the `vec::eq` function, but this is defined for types which
-/// implement `TotalEq` as opposed to types which implement `Eq`. Equality
-/// comparisons are done via the `equals` function instead of `eq`.
-fn equals<T: TotalEq>(a: &[T], b: &[T]) -> bool {
-    let (a_len, b_len) = (a.len(), b.len());
-    if a_len != b_len { return false; }
 
-    let mut i = 0;
-    while i < a_len {
-        if !a[i].equals(&b[i]) { return false; }
-        i += 1;
+    impl<T:Eq> Eq for ~[T] {
+        #[inline]
+        fn eq(&self, other: &~[T]) -> bool { self.as_slice() == *other }
+        #[inline]
+        fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
     }
-    true
-}
-
-#[cfg(not(test))]
-impl<'self,T:Eq> Eq for &'self [T] {
-    #[inline]
-    fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) }
-    #[inline]
-    fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) }
-}
-
-#[cfg(not(test))]
-impl<T:Eq> Eq for ~[T] {
-    #[inline]
-    fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) }
-    #[inline]
-    fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
-}
 
-#[cfg(not(test))]
-impl<T:Eq> Eq for @[T] {
-    #[inline]
-    fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) }
-    #[inline]
-    fn ne(&self, other: &@[T]) -> bool { !self.eq(other) }
-}
+    impl<T:Eq> Eq for @[T] {
+        #[inline]
+        fn eq(&self, other: &@[T]) -> bool { self.as_slice() == *other }
+        #[inline]
+        fn ne(&self, other: &@[T]) -> bool { !self.eq(other) }
+    }
 
-#[cfg(not(test))]
-impl<'self,T:TotalEq> TotalEq for &'self [T] {
-    #[inline]
-    fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) }
-}
+    impl<'self,T:TotalEq> TotalEq for &'self [T] {
+        fn equals(&self, other: & &'self [T]) -> bool {
+            self.len() == other.len() &&
+                self.iter().zip(other.iter()).all(|(s,o)| s.equals(o))
+        }
+    }
 
-#[cfg(not(test))]
-impl<T:TotalEq> TotalEq for ~[T] {
-    #[inline]
-    fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) }
-}
+    impl<T:TotalEq> TotalEq for ~[T] {
+        #[inline]
+        fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) }
+    }
 
-#[cfg(not(test))]
-impl<T:TotalEq> TotalEq for @[T] {
-    #[inline]
-    fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) }
-}
+    impl<T:TotalEq> TotalEq for @[T] {
+        #[inline]
+        fn equals(&self, other: &@[T]) -> bool { self.as_slice().equals(&other.as_slice()) }
+    }
 
-#[cfg(not(test))]
-impl<'self,T:Eq> Equiv<~[T]> for &'self [T] {
-    #[inline]
-    fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) }
-}
+    impl<'self,T:Eq, V: Vector<T>> Equiv<V> for &'self [T] {
+        #[inline]
+        fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
+    }
 
-// Lexicographical comparison
+    impl<'self,T:Eq, V: Vector<T>> Equiv<V> for ~[T] {
+        #[inline]
+        fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
+    }
 
-fn cmp<T: TotalOrd>(a: &[T], b: &[T]) -> Ordering {
-    let low = uint::min(a.len(), b.len());
+    impl<'self,T:Eq, V: Vector<T>> Equiv<V> for @[T] {
+        #[inline]
+        fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
+    }
 
-    for uint::range(0, low) |idx| {
-        match a[idx].cmp(&b[idx]) {
-          Greater => return Greater,
-          Less => return Less,
-          Equal => ()
+    impl<'self,T:TotalOrd> TotalOrd for &'self [T] {
+        fn cmp(&self, other: & &'self [T]) -> Ordering {
+            for self.iter().zip(other.iter()).advance |(s,o)| {
+                match s.cmp(o) {
+                    Equal => {},
+                    non_eq => { return non_eq; }
+                }
+            }
+            self.len().cmp(&other.len())
         }
     }
 
-    a.len().cmp(&b.len())
-}
-
-#[cfg(not(test))]
-impl<'self,T:TotalOrd> TotalOrd for &'self [T] {
-    #[inline]
-    fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) }
-}
+    impl<T: TotalOrd> TotalOrd for ~[T] {
+        #[inline]
+        fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
+    }
 
-#[cfg(not(test))]
-impl<T: TotalOrd> TotalOrd for ~[T] {
-    #[inline]
-    fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) }
-}
+    impl<T: TotalOrd> TotalOrd for @[T] {
+        #[inline]
+        fn cmp(&self, other: &@[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
+    }
 
-#[cfg(not(test))]
-impl<T: TotalOrd> TotalOrd for @[T] {
-    #[inline]
-    fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) }
-}
+    impl<'self,T:Ord> Ord for &'self [T] {
+        fn lt(&self, other: & &'self [T]) -> bool {
+            for self.iter().zip(other.iter()).advance |(s,o)| {
+                if *s < *o { return true; }
+                if *s > *o { return false; }
+            }
+            self.len() < other.len()
+        }
+        #[inline]
+        fn le(&self, other: & &'self [T]) -> bool { !(*other < *self) }
+        #[inline]
+        fn ge(&self, other: & &'self [T]) -> bool { !(*self < *other) }
+        #[inline]
+        fn gt(&self, other: & &'self [T]) -> bool { *other < *self }
+    }
 
-fn lt<T:Ord>(a: &[T], b: &[T]) -> bool {
-    let (a_len, b_len) = (a.len(), b.len());
-    let end = uint::min(a_len, b_len);
+    impl<T:Ord> Ord for ~[T] {
+        #[inline]
+        fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() }
+        #[inline]
+        fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() }
+        #[inline]
+        fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() }
+        #[inline]
+        fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() }
+    }
 
-    let mut i = 0;
-    while i < end {
-        let (c_a, c_b) = (&a[i], &b[i]);
-        if *c_a < *c_b { return true; }
-        if *c_a > *c_b { return false; }
-        i += 1;
+    impl<T:Ord> Ord for @[T] {
+        #[inline]
+        fn lt(&self, other: &@[T]) -> bool { self.as_slice() < other.as_slice() }
+        #[inline]
+        fn le(&self, other: &@[T]) -> bool { self.as_slice() <= other.as_slice() }
+        #[inline]
+        fn ge(&self, other: &@[T]) -> bool { self.as_slice() >= other.as_slice() }
+        #[inline]
+        fn gt(&self, other: &@[T]) -> bool { self.as_slice() > other.as_slice() }
     }
 
-    a_len < b_len
+    impl<'self,T:Copy, V: Vector<T>> Add<V, ~[T]> for &'self [T] {
+        #[inline]
+        fn add(&self, rhs: &V) -> ~[T] {
+            let mut res = self.to_owned();
+            res.push_all(rhs.as_slice());
+            res
+        }
+    }
+    impl<T:Copy, V: Vector<T>> Add<V, ~[T]> for ~[T] {
+        #[inline]
+        fn add(&self, rhs: &V) -> ~[T] {
+            let mut res = self.to_owned();
+            res.push_all(rhs.as_slice());
+            res
+        }
+    }
 }
 
-fn le<T:Ord>(a: &[T], b: &[T]) -> bool { !lt(b, a) }
-fn ge<T:Ord>(a: &[T], b: &[T]) -> bool { !lt(a, b) }
-fn gt<T:Ord>(a: &[T], b: &[T]) -> bool { lt(b, a)  }
+#[cfg(test)]
+pub mod traits {}
 
-#[cfg(not(test))]
-impl<'self,T:Ord> Ord for &'self [T] {
-    #[inline]
-    fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) }
-    #[inline]
-    fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) }
-    #[inline]
-    fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) }
-    #[inline]
-    fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) }
+/// Any vector that can be represented as a slice.
+pub trait Vector<T> {
+    /// Work with `self` as a slice.
+    fn as_slice<'a>(&'a self) -> &'a [T];
 }
-
-#[cfg(not(test))]
-impl<T:Ord> Ord for ~[T] {
-    #[inline]
-    fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) }
-    #[inline]
-    fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) }
-    #[inline]
-    fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) }
-    #[inline]
-    fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) }
+impl<'self,T> Vector<T> for &'self [T] {
+    #[inline(always)]
+    fn as_slice<'a>(&'a self) -> &'a [T] { *self }
 }
-
-#[cfg(not(test))]
-impl<T:Ord> Ord for @[T] {
-    #[inline]
-    fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) }
-    #[inline]
-    fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) }
-    #[inline]
-    fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) }
-    #[inline]
-    fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) }
+impl<T> Vector<T> for ~[T] {
+    #[inline(always)]
+    fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
 }
-
-#[cfg(not(test))]
-impl<'self,T:Copy> Add<&'self [T], ~[T]> for ~[T] {
-    #[inline]
-    fn add(&self, rhs: & &'self [T]) -> ~[T] {
-        append(copy *self, (*rhs))
-    }
+impl<T> Vector<T> for @[T] {
+    #[inline(always)]
+    fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
 }
 
 impl<'self, T> Container for &'self [T] {
     /// Returns true if a vector contains no elements
     #[inline]
     fn is_empty(&self) -> bool {
-        as_imm_buf(*self, |_p, len| len == 0u)
+        self.as_imm_buf(|_p, len| len == 0u)
     }
 
     /// Returns the length of a vector
     #[inline]
     fn len(&self) -> uint {
-        as_imm_buf(*self, |_p, len| len)
+        self.as_imm_buf(|_p, len| len)
     }
 }
 
@@ -900,13 +675,13 @@ impl<T> Container for ~[T] {
     /// Returns true if a vector contains no elements
     #[inline]
     fn is_empty(&self) -> bool {
-        as_imm_buf(*self, |_p, len| len == 0u)
+        self.as_imm_buf(|_p, len| len == 0u)
     }
 
     /// Returns the length of a vector
     #[inline]
     fn len(&self) -> uint {
-        as_imm_buf(*self, |_p, len| len)
+        self.as_imm_buf(|_p, len| len)
     }
 }
 
@@ -933,6 +708,14 @@ pub trait ImmutableVector<'self, T> {
     fn slice(&self, start: uint, end: uint) -> &'self [T];
     fn iter(self) -> VecIterator<'self, T>;
     fn rev_iter(self) -> VecRevIterator<'self, T>;
+    fn split_iter(self, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T>;
+    fn splitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T>;
+    fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>;
+    fn rsplitn_iter(self,  n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>;
+
+    fn window_iter(self, size: uint) -> VecWindowIter<'self, T>;
+    fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T>;
+
     fn head(&self) -> &'self T;
     fn head_opt(&self) -> Option<&'self T>;
     fn tail(&self) -> &'self [T];
@@ -943,12 +726,13 @@ pub trait ImmutableVector<'self, T> {
     fn last_opt(&self) -> Option<&'self T>;
     fn rposition(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
     fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U];
-    fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U];
     unsafe fn unsafe_ref(&self, index: uint) -> *T;
 
     fn bsearch(&self, f: &fn(&T) -> Ordering) -> Option<uint>;
 
     fn map<U>(&self, &fn(t: &T) -> U) -> ~[U];
+
+    fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U;
 }
 
 /// Extension methods for vectors
@@ -958,7 +742,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     fn slice(&self, start: uint, end: uint) -> &'self [T] {
     assert!(start <= end);
     assert!(end <= self.len());
-        do as_imm_buf(*self) |p, _len| {
+        do self.as_imm_buf |p, _len| {
             unsafe {
                 transmute((ptr::offset(p, start),
                            (end - start) * sys::nonzero_size_of::<T>()))
@@ -984,6 +768,101 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
         }
     }
 
+    /// Returns an iterator over the subslices of the vector which are
+    /// separated by elements that match `pred`.
+    #[inline]
+    fn split_iter(self, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T> {
+        self.splitn_iter(uint::max_value, pred)
+    }
+    /// Returns an iterator over the subslices of the vector which are
+    /// separated by elements that match `pred`, limited to splitting
+    /// at most `n` times.
+    #[inline]
+    fn splitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T> {
+        VecSplitIterator {
+            v: self,
+            n: n,
+            pred: pred,
+            finished: false
+        }
+    }
+    /// Returns an iterator over the subslices of the vector which are
+    /// separated by elements that match `pred`. This starts at the
+    /// end of the vector and works backwards.
+    #[inline]
+    fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T> {
+        self.rsplitn_iter(uint::max_value, pred)
+    }
+    /// Returns an iterator over the subslices of the vector which are
+    /// separated by elements that match `pred` limited to splitting
+    /// at most `n` times. This starts at the end of the vector and
+    /// works backwards.
+    #[inline]
+    fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T> {
+        VecRSplitIterator {
+            v: self,
+            n: n,
+            pred: pred,
+            finished: false
+        }
+    }
+
+    /**
+     * Returns an iterator over all contiguous windows of length
+     * `size`. The windows overlap. If the vector is shorter than
+     * `size`, the iterator returns no values.
+     *
+     * # Failure
+     *
+     * Fails if `size` is 0.
+     *
+     * # Example
+     *
+     * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`,
+     * `[3,4]`):
+     *
+     * ~~~ {.rust}
+     * let v = &[1,2,3,4];
+     * for v.window_iter().advance |win| {
+     *     io::println(fmt!("%?", win));
+     * }
+     * ~~~
+     *
+     */
+    fn window_iter(self, size: uint) -> VecWindowIter<'self, T> {
+        assert!(size != 0);
+        VecWindowIter { v: self, size: size }
+    }
+
+    /**
+     *
+     * Returns an iterator over `size` elements of the vector at a
+     * time. The chunks do not overlap. If `size` does not divide the
+     * length of the vector, then the last chunk will not have length
+     * `size`.
+     *
+     * # Failure
+     *
+     * Fails if `size` is 0.
+     *
+     * # Example
+     *
+     * Print the vector two elements at a time (i.e. `[1,2]`,
+     * `[3,4]`, `[5]`):
+     *
+     * ~~~ {.rust}
+     * let v = &[1,2,3,4,5];
+     * for v.chunk_iter().advance |win| {
+     *     io::println(fmt!("%?", win));
+     * }
+     * ~~~
+     *
+     */
+    fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T> {
+        assert!(size != 0);
+        VecChunkIter { v: self, size: size }
+    }
+
     /// Returns the first element of a vector, failing if the vector is empty.
     #[inline]
     fn head(&self) -> &'self T {
@@ -1053,17 +932,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] {
         flat_map(*self, f)
     }
-    /**
-     * Apply a function to each element of a vector and return the results
-     *
-     * If function `f` returns `none` then that element is excluded from
-     * the resulting vector.
-     */
-    #[inline]
-    fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U] {
-        filter_mapped(*self, f)
-    }
-
     /// Returns a pointer to the element at the given index, without doing
     /// bounds checking.
     #[inline]
@@ -1107,6 +975,28 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] {
         self.iter().transform(f).collect()
     }
+
+    /**
+     * Work with the buffer of a vector.
+     *
+     * Allows for unsafe manipulation of vector contents, which is useful for
+     * foreign interop.
+     */
+    #[inline]
+    fn as_imm_buf<U>(&self,
+                     /* NB---this CANNOT be const, see below */
+                     f: &fn(*T, uint) -> U) -> U {
+        // NB---Do not change the type of s to `&const [T]`.  This is
+        // unsound.  The reason is that we are going to create immutable pointers
+        // into `s` and pass them to `f()`, but in fact they are potentially
+        // pointing at *mutable memory*.  Use `as_mut_buf` instead!
+
+        unsafe {
+            let v : *(*T,uint) = transmute(self);
+            let (buf,len) = *v;
+            f(buf, len / sys::nonzero_size_of::<T>())
+        }
+    }
 }
 
 #[allow(missing_doc)]
@@ -1154,7 +1044,6 @@ impl<'self, T: TotalOrd> ImmutableTotalOrdVector<T> for &'self [T] {
 
 #[allow(missing_doc)]
 pub trait ImmutableCopyableVector<T> {
-    fn filtered(&self, f: &fn(&T) -> bool) -> ~[T];
     fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]);
     unsafe fn unsafe_get(&self, elem: uint) -> T;
 }
@@ -1162,18 +1051,6 @@ pub trait ImmutableCopyableVector<T> {
 /// Extension methods for vectors
 impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
     /**
-     * Construct a new vector from the elements of a vector for which some
-     * predicate holds.
-     *
-     * Apply function `f` to each element of `v` and return a vector
-     * containing only those elements for which `f` returned true.
-     */
-    #[inline]
-    fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] {
-        filtered(*self, f)
-    }
-
-    /**
      * Partitions the vector into those that satisfies the predicate, and
      * those that do not.
      */
@@ -1202,6 +1079,9 @@ impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
 
 #[allow(missing_doc)]
 pub trait OwnedVector<T> {
+    fn consume_iter(self) -> VecConsumeIterator<T>;
+    fn consume_rev_iter(self) -> VecConsumeRevIterator<T>;
+
     fn reserve(&mut self, n: uint);
     fn reserve_at_least(&mut self, n: uint);
     fn capacity(&self) -> uint;
@@ -1218,14 +1098,37 @@ pub trait OwnedVector<T> {
     fn swap_remove(&mut self, index: uint) -> T;
     fn truncate(&mut self, newlen: uint);
     fn retain(&mut self, f: &fn(t: &T) -> bool);
-    fn consume(self, f: &fn(uint, v: T));
-    fn consume_reverse(self, f: &fn(uint, v: T));
-    fn filter(self, f: &fn(t: &T) -> bool) -> ~[T];
     fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]);
     fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T);
 }
 
 impl<T> OwnedVector<T> for ~[T] {
+    /// Creates a consuming iterator, that is, one that moves each
+    /// value out of the vector (from start to end). The vector cannot
+    /// be used after calling this.
+    ///
+    /// Note that this performs O(n) swaps, and so `consume_rev_iter`
+    /// (which just calls `pop` repeatedly) is more efficient.
+    ///
+    /// # Examples
+    ///
+    /// ~~~ {.rust}
+    /// let v = ~[~"a", ~"b"];
+    /// for v.consume_iter().advance |s| {
+    ///   // s has type ~str, not &~str
+    ///   println(s);
+    /// }
+    /// ~~~
+    fn consume_iter(self) -> VecConsumeIterator<T> {
+        VecConsumeIterator { v: self, idx: 0 }
+    }
+    /// Creates a consuming iterator that moves out of the vector in
+    /// reverse order. Also see `consume_iter`, however note that this
+    /// is more efficient.
+    fn consume_rev_iter(self) -> VecConsumeRevIterator<T> {
+        VecConsumeRevIterator { v: self }
+    }
+
     /**
      * Reserves capacity for exactly `n` elements in the given vector.
      *
@@ -1367,7 +1270,7 @@ impl<T> OwnedVector<T> for ~[T] {
         let new_len = self.len() + rhs.len();
         self.reserve(new_len);
         unsafe {
-            do as_mut_buf(rhs) |p, len| {
+            do rhs.as_mut_buf |p, len| {
                 for uint::range(0, len) |i| {
                     let x = ptr::replace_ptr(ptr::mut_offset(p, i),
                                              intrinsics::uninit());
@@ -1499,7 +1402,7 @@ impl<T> OwnedVector<T> for ~[T] {
 
     /// Shorten a vector, dropping excess elements.
     fn truncate(&mut self, newlen: uint) {
-        do as_mut_buf(*self) |p, oldlen| {
+        do self.as_mut_buf |p, oldlen| {
             assert!(newlen <= oldlen);
             unsafe {
                 // This loop is optimized out for non-drop types.
@@ -1532,21 +1435,6 @@ impl<T> OwnedVector<T> for ~[T] {
         }
     }
 
-    #[inline]
-    fn consume(self, f: &fn(uint, v: T)) {
-        consume(self, f)
-    }
-
-    #[inline]
-    fn consume_reverse(self, f: &fn(uint, v: T)) {
-        consume_reverse(self, f)
-    }
-
-    #[inline]
-    fn filter(self, f: &fn(&T) -> bool) -> ~[T] {
-        filter(self, f)
-    }
-
     /**
      * Partitions the vector into those that satisfies the predicate, and
      * those that do not.
@@ -1556,7 +1444,7 @@ impl<T> OwnedVector<T> for ~[T] {
         let mut lefts  = ~[];
         let mut rights = ~[];
 
-        do self.consume |_, elt| {
+        for self.consume_iter().advance |elt| {
             if f(&elt) {
                 lefts.push(elt);
             } else {
@@ -1672,7 +1560,7 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
             if self.len() == 0 { return; }
             let mut last_written = 0;
             let mut next_to_read = 1;
-            do as_mut_buf(*self) |p, ln| {
+            do self.as_mut_buf |p, ln| {
                 // last_written < next_to_read <= ln
                 while next_to_read < ln {
                     // last_written < next_to_read < ln
@@ -1726,6 +1614,8 @@ pub trait MutableVector<'self, T> {
 
     unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T;
     unsafe fn unsafe_set(&self, index: uint, val: T);
+
+    fn as_mut_buf<U>(&self, f: &fn(*mut T, uint) -> U) -> U;
 }
 
 impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
@@ -1734,7 +1624,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
     fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
         assert!(start <= end);
         assert!(end <= self.len());
-        do as_mut_buf(self) |p, _len| {
+        do self.as_mut_buf |p, _len| {
             unsafe {
                 transmute((ptr::mut_offset(p, start),
                            (end - start) * sys::nonzero_size_of::<T>()))
@@ -1807,6 +1697,17 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
     unsafe fn unsafe_set(&self, index: uint, val: T) {
         *self.unsafe_mut_ref(index) = val;
     }
+
+    /// Similar to `as_imm_buf` but passing a `*mut T`
+    #[inline]
+    fn as_mut_buf<U>(&self, f: &fn(*mut T, uint) -> U) -> U {
+        unsafe {
+            let v : *(*mut T,uint) = transmute(self);
+            let (buf,len) = *v;
+            f(buf, len / sys::nonzero_size_of::<T>())
+        }
+    }
+
 }
 
 /// Trait for ~[T] where T is Cloneable
@@ -1856,7 +1757,7 @@ pub mod raw {
     use ptr;
     use sys;
     use unstable::intrinsics;
-    use vec::{UnboxedVecRepr, as_imm_buf, as_mut_buf, with_capacity};
+    use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector};
     use util;
 
     /// The internal representation of a (boxed) vector
@@ -1944,7 +1845,7 @@ pub mod raw {
      */
     #[inline]
     pub unsafe fn get<T:Copy>(v: &[T], i: uint) -> T {
-        as_imm_buf(v, |p, _len| copy *ptr::offset(p, i))
+        v.as_imm_buf(|p, _len| copy *ptr::offset(p, i))
     }
 
     /**
@@ -1955,7 +1856,7 @@ pub mod raw {
     #[inline]
     pub unsafe fn init_elem<T>(v: &mut [T], i: uint, val: T) {
         let mut box = Some(val);
-        do as_mut_buf(v) |p, _len| {
+        do v.as_mut_buf |p, _len| {
             let box2 = util::replace(&mut box, None);
             intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)),
                                       box2.unwrap());
@@ -1975,7 +1876,7 @@ pub mod raw {
     pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
         let mut dst = with_capacity(elts);
         set_len(&mut dst, elts);
-        as_mut_buf(dst, |p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts));
+        dst.as_mut_buf(|p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts));
         dst
     }
 
@@ -1991,8 +1892,8 @@ pub mod raw {
         assert!(dst.len() >= count);
         assert!(src.len() >= count);
 
-        do as_mut_buf(dst) |p_dst, _len_dst| {
-            do as_imm_buf(src) |p_src, _len_src| {
+        do dst.as_mut_buf |p_dst, _len_dst| {
+            do src.as_imm_buf |p_src, _len_src| {
                 ptr::copy_memory(p_dst, p_src, count)
             }
         }
@@ -2016,7 +1917,7 @@ pub mod bytes {
     impl<'self> MutableByteVector for &'self mut [u8] {
         #[inline]
         fn set_memory(self, value: u8) {
-            do vec::as_mut_buf(self) |p, len| {
+            do self.as_mut_buf |p, len| {
                 unsafe { ptr::set_memory(p, value, len) };
             }
         }
@@ -2132,7 +2033,7 @@ macro_rules! iterator {
 }
 
 //iterator!{struct VecIterator -> *T, &'self T}
-/// An iterator for iterating over a vector
+/// An iterator for iterating over a vector.
 pub struct VecIterator<'self, T> {
     priv ptr: *T,
     priv end: *T,
@@ -2141,7 +2042,7 @@ pub struct VecIterator<'self, T> {
 iterator!{impl VecIterator -> &'self T, 1}
 
 //iterator!{struct VecRevIterator -> *T, &'self T}
-/// An iterator for iterating over a vector in reverse
+/// An iterator for iterating over a vector in reverse.
 pub struct VecRevIterator<'self, T> {
     priv ptr: *T,
     priv end: *T,
@@ -2150,7 +2051,7 @@ pub struct VecRevIterator<'self, T> {
 iterator!{impl VecRevIterator -> &'self T, -1}
 
 //iterator!{struct VecMutIterator -> *mut T, &'self mut T}
-/// An iterator for mutating the elements of a vector
+/// An iterator for mutating the elements of a vector.
 pub struct VecMutIterator<'self, T> {
     priv ptr: *mut T,
     priv end: *mut T,
@@ -2159,7 +2060,7 @@ pub struct VecMutIterator<'self, T> {
 iterator!{impl VecMutIterator -> &'self mut T, 1}
 
 //iterator!{struct VecMutRevIterator -> *mut T, &'self mut T}
-/// An iterator for mutating the elements of a vector in reverse
+/// An iterator for mutating the elements of a vector in reverse.
 pub struct VecMutRevIterator<'self, T> {
     priv ptr: *mut T,
     priv end: *mut T,
@@ -2167,6 +2068,49 @@ pub struct VecMutRevIterator<'self, T> {
 }
 iterator!{impl VecMutRevIterator -> &'self mut T, -1}
 
+/// An iterator that moves out of a vector.
+pub struct VecConsumeIterator<T> {
+    priv v: ~[T],
+    priv idx: uint,
+}
+
+impl<T> Iterator<T> for VecConsumeIterator<T> {
+    fn next(&mut self) -> Option<T> {
+        // this is peculiar, but is required for safety with respect
+        // to dtors. It traverses the first half of the vec, and
+        // removes them by swapping them with the last element (and
+        // popping), which results in the second half in reverse
+        // order, and so these can just be pop'd off. That is,
+        //
+        // [1,2,3,4,5] => 1, [5,2,3,4] => 2, [5,4,3] => 3, [5,4] => 4,
+        // [5] -> 5, []
+
+        if self.v.is_empty() {
+            None
+        } else {
+            let l = self.v.len();
+            if self.idx < l {
+                self.v.swap(self.idx, l - 1);
+                self.idx += 1;
+            }
+
+            Some(self.v.pop())
+        }
+    }
+}
+
+/// An iterator that moves out of a vector in reverse order.
+pub struct VecConsumeRevIterator<T> {
+    priv v: ~[T]
+}
+
+impl<T> Iterator<T> for VecConsumeRevIterator<T> {
+    fn next(&mut self) -> Option<T> {
+        if self.v.is_empty() { None }
+        else { Some(self.v.pop()) }
+    }
+}
+
 #[cfg(stage0)]
 impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
     pub fn from_iterator(iterator: &mut T) -> ~[A] {
@@ -2634,87 +2578,6 @@ mod tests {
     }
 
     #[test]
-    fn test_filter_mapped() {
-        // Test on-stack filter-map.
-        let mut v = ~[1u, 2u, 3u];
-        let mut w = filter_mapped(v, square_if_odd_r);
-        assert_eq!(w.len(), 2u);
-        assert_eq!(w[0], 1u);
-        assert_eq!(w[1], 9u);
-
-        // Test on-heap filter-map.
-        v = ~[1u, 2u, 3u, 4u, 5u];
-        w = filter_mapped(v, square_if_odd_r);
-        assert_eq!(w.len(), 3u);
-        assert_eq!(w[0], 1u);
-        assert_eq!(w[1], 9u);
-        assert_eq!(w[2], 25u);
-
-        fn halve(i: &int) -> Option<int> {
-            if *i % 2 == 0 {
-                Some::<int>(*i / 2)
-            } else {
-                None::<int>
-            }
-        }
-        fn halve_for_sure(i: &int) -> int { *i / 2 }
-        let all_even: ~[int] = ~[0, 2, 8, 6];
-        let all_odd1: ~[int] = ~[1, 7, 3];
-        let all_odd2: ~[int] = ~[];
-        let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3];
-        let mix_dest: ~[int] = ~[1, 3, 0, 0];
-        assert!(filter_mapped(all_even, halve) ==
-                     all_even.map(halve_for_sure));
-        assert_eq!(filter_mapped(all_odd1, halve), ~[]);
-        assert_eq!(filter_mapped(all_odd2, halve), ~[]);
-        assert_eq!(filter_mapped(mix, halve), mix_dest);
-    }
-
-    #[test]
-    fn test_filter_map() {
-        // Test on-stack filter-map.
-        let mut v = ~[1u, 2u, 3u];
-        let mut w = filter_map(v, square_if_odd_v);
-        assert_eq!(w.len(), 2u);
-        assert_eq!(w[0], 1u);
-        assert_eq!(w[1], 9u);
-
-        // Test on-heap filter-map.
-        v = ~[1u, 2u, 3u, 4u, 5u];
-        w = filter_map(v, square_if_odd_v);
-        assert_eq!(w.len(), 3u);
-        assert_eq!(w[0], 1u);
-        assert_eq!(w[1], 9u);
-        assert_eq!(w[2], 25u);
-
-        fn halve(i: int) -> Option<int> {
-            if i % 2 == 0 {
-                Some::<int>(i / 2)
-            } else {
-                None::<int>
-            }
-        }
-        fn halve_for_sure(i: &int) -> int { *i / 2 }
-        let all_even: ~[int] = ~[0, 2, 8, 6];
-        let all_even0: ~[int] = copy all_even;
-        let all_odd1: ~[int] = ~[1, 7, 3];
-        let all_odd2: ~[int] = ~[];
-        let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3];
-        let mix_dest: ~[int] = ~[1, 3, 0, 0];
-        assert!(filter_map(all_even, halve) ==
-                     all_even0.map(halve_for_sure));
-        assert_eq!(filter_map(all_odd1, halve), ~[]);
-        assert_eq!(filter_map(all_odd2, halve), ~[]);
-        assert_eq!(filter_map(mix, halve), mix_dest);
-    }
-
-    #[test]
-    fn test_filter() {
-        assert_eq!(filter(~[1u, 2u, 3u], is_odd), ~[1u, 3u]);
-        assert_eq!(filter(~[1u, 2u, 4u, 8u, 16u], is_three), ~[]);
-    }
-
-    #[test]
     fn test_retain() {
         let mut v = ~[1, 2, 3, 4, 5];
         v.retain(is_odd);
@@ -2828,75 +2691,17 @@ mod tests {
     }
 
     #[test]
-    fn reverse_and_reversed() {
+    fn test_reverse() {
         let mut v: ~[int] = ~[10, 20];
         assert_eq!(v[0], 10);
         assert_eq!(v[1], 20);
         v.reverse();
         assert_eq!(v[0], 20);
         assert_eq!(v[1], 10);
-        let v2 = reversed::<int>([10, 20]);
-        assert_eq!(v2[0], 20);
-        assert_eq!(v2[1], 10);
-        v[0] = 30;
-        assert_eq!(v2[0], 20);
-        // Make sure they work with 0-length vectors too.
-
-        let v4 = reversed::<int>([]);
-        assert_eq!(v4, ~[]);
+
         let mut v3: ~[int] = ~[];
         v3.reverse();
-    }
-
-    #[test]
-    fn reversed_mut() {
-        let v2 = reversed::<int>([10, 20]);
-        assert_eq!(v2[0], 20);
-        assert_eq!(v2[1], 10);
-    }
-
-    #[test]
-    fn test_split() {
-        fn f(x: &int) -> bool { *x == 3 }
-
-        assert_eq!(split([], f), ~[]);
-        assert_eq!(split([1, 2], f), ~[~[1, 2]]);
-        assert_eq!(split([3, 1, 2], f), ~[~[], ~[1, 2]]);
-        assert_eq!(split([1, 2, 3], f), ~[~[1, 2], ~[]]);
-        assert_eq!(split([1, 2, 3, 4, 3, 5], f), ~[~[1, 2], ~[4], ~[5]]);
-    }
-
-    #[test]
-    fn test_splitn() {
-        fn f(x: &int) -> bool { *x == 3 }
-
-        assert_eq!(splitn([], 1u, f), ~[]);
-        assert_eq!(splitn([1, 2], 1u, f), ~[~[1, 2]]);
-        assert_eq!(splitn([3, 1, 2], 1u, f), ~[~[], ~[1, 2]]);
-        assert_eq!(splitn([1, 2, 3], 1u, f), ~[~[1, 2], ~[]]);
-        assert!(splitn([1, 2, 3, 4, 3, 5], 1u, f) ==
-                      ~[~[1, 2], ~[4, 3, 5]]);
-    }
-
-    #[test]
-    fn test_rsplit() {
-        fn f(x: &int) -> bool { *x == 3 }
-
-        assert_eq!(rsplit([], f), ~[]);
-        assert_eq!(rsplit([1, 2], f), ~[~[1, 2]]);
-        assert_eq!(rsplit([1, 2, 3], f), ~[~[1, 2], ~[]]);
-        assert!(rsplit([1, 2, 3, 4, 3, 5], f) ==
-            ~[~[1, 2], ~[4], ~[5]]);
-    }
-
-    #[test]
-    fn test_rsplitn() {
-        fn f(x: &int) -> bool { *x == 3 }
-
-        assert_eq!(rsplitn([], 1u, f), ~[]);
-        assert_eq!(rsplitn([1, 2], 1u, f), ~[~[1, 2]]);
-        assert_eq!(rsplitn([1, 2, 3], 1u, f), ~[~[1, 2], ~[]]);
-        assert_eq!(rsplitn([1, 2, 3, 4, 3, 5], 1u, f), ~[~[1, 2, 3, 4], ~[5]]);
+        assert!(v3.is_empty());
     }
 
     #[test]
@@ -2940,31 +2745,6 @@ mod tests {
     }
 
     #[test]
-    fn test_windowed () {
-        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;
-            }
-
-            // 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, &[]);
-        t(8, &[]);
-    }
-
-    #[test]
-    #[should_fail]
-    #[ignore(cfg(windows))]
-    fn test_windowed_() {
-        for windowed (0u, [1u,2u,3u,4u,5u,6u]) |_v| {}
-    }
-
-    #[test]
     fn test_unshift() {
         let mut x = ~[1, 2, 3];
         x.unshift(0);
@@ -3068,156 +2848,6 @@ mod tests {
     #[ignore(windows)]
     #[should_fail]
     #[allow(non_implicitly_copyable_typarams)]
-    fn test_split_fail_ret_true() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do split(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_split_fail_ret_false() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do split(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-
-            false
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_splitn_fail_ret_true() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do splitn(v, 100) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_splitn_fail_ret_false() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do split(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-
-            false
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_rsplit_fail_ret_true() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do rsplit(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_rsplit_fail_ret_false() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do rsplit(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-
-            false
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_rsplitn_fail_ret_true() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do rsplitn(v, 100) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_rsplitn_fail_ret_false() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do rsplitn(v, 100) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-
-            false
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    fn test_consume_fail() {
-        let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do consume(v) |_i, _elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
     fn test_grow_fn_fail() {
         let mut v = ~[];
         do v.grow_fn(100) |i| {
@@ -3246,21 +2876,6 @@ mod tests {
     #[test]
     #[ignore(windows)]
     #[should_fail]
-    fn test_map_consume_fail() {
-        let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do map_consume(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            ~[(~0, @0)]
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
     fn test_flat_map_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
         let mut i = 0;
@@ -3276,38 +2891,6 @@ mod tests {
     #[test]
     #[ignore(windows)]
     #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_filter_mapped_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do filter_mapped(v) |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            Some((~0, @0))
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
-    #[allow(non_implicitly_copyable_typarams)]
-    fn test_filter_fail() {
-        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        let mut i = 0;
-        do v.filtered |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 0;
-            true
-        };
-    }
-
-    #[test]
-    #[ignore(windows)]
-    #[should_fail]
     fn test_rposition_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
         let mut i = 0;
@@ -3340,7 +2923,7 @@ mod tests {
     #[should_fail]
     fn test_as_imm_buf_fail() {
         let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        do as_imm_buf(v) |_buf, _i| {
+        do v.as_imm_buf |_buf, _i| {
             fail!()
         }
     }
@@ -3350,7 +2933,7 @@ mod tests {
     #[should_fail]
     fn test_as_mut_buf_fail() {
         let mut v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
-        do as_mut_buf(v) |_buf, _i| {
+        do v.as_mut_buf |_buf, _i| {
             fail!()
         }
     }
@@ -3429,6 +3012,120 @@ mod tests {
     }
 
     #[test]
+    fn test_consume_iterator() {
+        use iterator::*;
+        let xs = ~[1u,2,3,4,5];
+        assert_eq!(xs.consume_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345);
+    }
+
+    #[test]
+    fn test_consume_rev_iterator() {
+        use iterator::*;
+        let xs = ~[1u,2,3,4,5];
+        assert_eq!(xs.consume_rev_iter().fold(0, |a: uint, b: uint| 10*a + b), 54321);
+    }
+
+    #[test]
+    fn test_split_iterator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.split_iter(|x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[1], &[3], &[5]]);
+        assert_eq!(xs.split_iter(|x| *x == 1).collect::<~[&[int]]>(),
+                   ~[&[], &[2,3,4,5]]);
+        assert_eq!(xs.split_iter(|x| *x == 5).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4], &[]]);
+        assert_eq!(xs.split_iter(|x| *x == 10).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4,5]]);
+        assert_eq!(xs.split_iter(|_| true).collect::<~[&[int]]>(),
+                   ~[&[], &[], &[], &[], &[], &[]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.split_iter(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
+    }
+
+    #[test]
+    fn test_splitn_iterator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.splitn_iter(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4,5]]);
+        assert_eq!(xs.splitn_iter(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[1], &[3,4,5]]);
+        assert_eq!(xs.splitn_iter(3, |_| true).collect::<~[&[int]]>(),
+                   ~[&[], &[], &[], &[4,5]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.splitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
+    }
+
+    #[test]
+    fn test_rsplit_iterator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.rsplit_iter(|x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[5], &[3], &[1]]);
+        assert_eq!(xs.rsplit_iter(|x| *x == 1).collect::<~[&[int]]>(),
+                   ~[&[2,3,4,5], &[]]);
+        assert_eq!(xs.rsplit_iter(|x| *x == 5).collect::<~[&[int]]>(),
+                   ~[&[], &[1,2,3,4]]);
+        assert_eq!(xs.rsplit_iter(|x| *x == 10).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4,5]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.rsplit_iter(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
+    }
+
+    #[test]
+    fn test_rsplitn_iterator() {
+        let xs = &[1,2,3,4,5];
+
+        assert_eq!(xs.rsplitn_iter(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4,5]]);
+        assert_eq!(xs.rsplitn_iter(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[5], &[1,2,3]]);
+        assert_eq!(xs.rsplitn_iter(3, |_| true).collect::<~[&[int]]>(),
+                   ~[&[], &[], &[], &[1,2]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.rsplitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
+    }
+
+    #[test]
+    fn test_window_iterator() {
+        let v = &[1i,2,3,4];
+
+        assert_eq!(v.window_iter(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]);
+        assert_eq!(v.window_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]);
+        assert!(v.window_iter(6).next().is_none());
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_window_iterator_0() {
+        let v = &[1i,2,3,4];
+        let _it = v.window_iter(0);
+    }
+
+    #[test]
+    fn test_chunk_iterator() {
+        let v = &[1i,2,3,4,5];
+
+        assert_eq!(v.chunk_iter(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
+        assert_eq!(v.chunk_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
+        assert_eq!(v.chunk_iter(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_chunk_iterator_0() {
+        let v = &[1i,2,3,4];
+        let _it = v.chunk_iter(0);
+    }
+
+    #[test]
     fn test_move_from() {
         let mut a = [1,2,3,4,5];
         let b = ~[6,7,8];