about summary refs log tree commit diff
path: root/src/libstd/vec.rs
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-07-08 16:20:38 -0700
committerBrian Anderson <banderson@mozilla.com>2013-07-08 16:29:54 -0700
commitfae33367692c634356d861dc4badb967dc72a573 (patch)
treed73190f2523bed7d010da69442b0c28973631ac1 /src/libstd/vec.rs
parentb227583dadd1500bba7752c7e5d9f2ac931611bc (diff)
parentf503e539bf60416a731f9ecc12b6aab31ef2fe87 (diff)
downloadrust-fae33367692c634356d861dc4badb967dc72a573.tar.gz
rust-fae33367692c634356d861dc4badb967dc72a573.zip
Merge remote-tracking branch 'mozilla/master'
Conflicts:
	src/libextra/test.rs
	src/libstd/rt/global_heap.rs
	src/libstd/unstable/lang.rs
	src/libstd/vec.rs
Diffstat (limited to 'src/libstd/vec.rs')
-rw-r--r--src/libstd/vec.rs1558
1 files changed, 652 insertions, 906 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 1180ac883e7..2c1e913511e 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -16,14 +16,12 @@ 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 iter::FromIter;
 use kinds::Copy;
 use libc::c_void;
 use num::Zero;
-use ops::Add;
 use option::{None, Option, Some};
 use ptr::to_unsafe_ptr;
 use ptr;
@@ -34,9 +32,9 @@ use sys::size_of;
 use uint;
 use unstable::intrinsics;
 #[cfg(stage0)]
-use intrinsic::{get_tydesc};
+use intrinsic::{get_tydesc, TyDesc};
 #[cfg(not(stage0))]
-use unstable::intrinsics::{get_tydesc, contains_managed};
+use unstable::intrinsics::{get_tydesc, contains_managed, TyDesc};
 use vec;
 use util;
 
@@ -56,7 +54,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));
@@ -81,7 +79,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);
@@ -158,165 +156,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);
     }
 }
 
@@ -342,20 +244,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
@@ -366,79 +254,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() }
 
@@ -524,7 +339,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);
@@ -566,16 +381,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`.
  *
@@ -630,251 +435,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)
     }
 }
 
@@ -882,13 +658,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)
     }
 }
 
@@ -915,6 +691,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];
@@ -925,12 +709,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
@@ -940,7 +725,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>()))
@@ -966,6 +751,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 {
@@ -1035,17 +915,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]
@@ -1089,6 +958,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)]
@@ -1102,7 +993,7 @@ impl<'self,T:Eq> ImmutableEqVector<T> for &'self [T] {
     /// Find the first index containing a matching value
     #[inline]
     fn position_elem(&self, x: &T) -> Option<uint> {
-        self.iter().position_(|y| *x == *y)
+        self.iter().position(|y| *x == *y)
     }
 
     /// Find the last index containing a matching value
@@ -1136,7 +1027,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;
 }
@@ -1144,18 +1034,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.
      */
@@ -1184,6 +1062,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;
@@ -1193,21 +1074,46 @@ pub trait OwnedVector<T> {
 
     fn push_all_move(&mut self, rhs: ~[T]);
     fn pop(&mut self) -> T;
+    fn pop_opt(&mut self) -> Option<T>;
     fn shift(&mut self) -> T;
+    fn shift_opt(&mut self) -> Option<T>;
     fn unshift(&mut self, x: T);
     fn insert(&mut self, i: uint, x:T);
     fn remove(&mut self, i: uint) -> 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.
      *
@@ -1351,7 +1257,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());
@@ -1362,35 +1268,49 @@ impl<T> OwnedVector<T> for ~[T] {
         }
     }
 
-    /// Remove the last element from a vector and return it
-    fn pop(&mut self) -> T {
-        let ln = self.len();
-        if ln == 0 {
-            fail!("sorry, cannot pop an empty vector")
-        }
-        let valptr = ptr::to_mut_unsafe_ptr(&mut self[ln - 1u]);
-        unsafe {
-            let val = ptr::replace_ptr(valptr, intrinsics::init());
-            raw::set_len(self, ln - 1u);
-            val
+    /// Remove the last element from a vector and return it, or `None` if it is empty
+    fn pop_opt(&mut self) -> Option<T> {
+        match self.len() {
+            0  => None,
+            ln => {
+                let valptr = ptr::to_mut_unsafe_ptr(&mut self[ln - 1u]);
+                unsafe {
+                    let val = ptr::replace_ptr(valptr, intrinsics::init());
+                    raw::set_len(self, ln - 1u);
+                    Some(val)
+                }
+            }
         }
     }
 
+
+    /// Remove the last element from a vector and return it, failing if it is empty
+    #[inline]
+    fn pop(&mut self) -> T {
+        self.pop_opt().expect("pop: empty vector")
+    }
+
     /// Removes the first element from a vector and return it
+    #[inline]
     fn shift(&mut self) -> T {
-        unsafe {
-            assert!(!self.is_empty());
-
-            if self.len() == 1 { return self.pop() }
+        self.shift_opt().expect("shift: empty vector")
+    }
 
-            if self.len() == 2 {
-                let last = self.pop();
-                let first = self.pop();
-                self.push(last);
-                return first;
-            }
+    /// Removes the first element from a vector and return it, or `None` if it is empty
+    fn shift_opt(&mut self) -> Option<T> {
+        unsafe {
+            let ln = match self.len() {
+                0 => return None,
+                1 => return self.pop_opt(),
+                2 =>  {
+                    let last = self.pop();
+                    let first = self.pop_opt();
+                    self.push(last);
+                    return first;
+                }
+                x => x
+            };
 
-            let ln = self.len();
             let next_ln = self.len() - 1;
 
             // Save the last element. We're going to overwrite its position
@@ -1426,7 +1346,7 @@ impl<T> OwnedVector<T> for ~[T] {
             let vp = raw::to_mut_ptr(*self);
             let vp = ptr::mut_offset(vp, next_ln - 1);
 
-            ptr::replace_ptr(vp, work_elt)
+            Some(ptr::replace_ptr(vp, work_elt))
         }
     }
 
@@ -1483,7 +1403,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.
@@ -1516,21 +1436,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.
@@ -1540,7 +1445,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 {
@@ -1656,7 +1561,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
@@ -1710,6 +1615,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] {
@@ -1718,7 +1625,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>()))
@@ -1791,6 +1698,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
@@ -1840,7 +1758,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
@@ -1928,7 +1846,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))
     }
 
     /**
@@ -1939,7 +1857,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());
@@ -1959,7 +1877,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
     }
 
@@ -1975,8 +1893,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)
             }
         }
@@ -2000,7 +1918,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) };
             }
         }
@@ -2107,16 +2025,21 @@ macro_rules! iterator {
             }
 
             #[inline]
-            fn size_hint(&self) -> (Option<uint>, Option<uint>) {
-                let exact = Some(((self.end as uint) - (self.ptr as uint)) / size_of::<$elem>());
-                (exact, exact)
+            fn size_hint(&self) -> (uint, Option<uint>) {
+                let diff = if $step > 0 {
+                    (self.end as uint) - (self.ptr as uint)
+                } else {
+                    (self.ptr as uint) - (self.end as uint)
+                };
+                let exact = diff / size_of::<$elem>();
+                (exact, Some(exact))
             }
         }
     }
 }
 
 //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,
@@ -2125,7 +2048,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,
@@ -2134,7 +2057,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,
@@ -2143,7 +2066,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,
@@ -2151,12 +2074,40 @@ pub struct VecMutRevIterator<'self, T> {
 }
 iterator!{impl VecMutRevIterator -> &'self mut T, -1}
 
-impl<T> FromIter<T> for ~[T]{
-    #[inline]
-    pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
-        let mut v = ~[];
-        for iter |x| { v.push(x) }
-        v
+/// 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, []
+        let l = self.v.len();
+        if self.idx < l {
+            self.v.swap(self.idx, l - 1);
+            self.idx += 1;
+        }
+
+        self.v.pop_opt()
+    }
+}
+
+/// 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> {
+        self.v.pop_opt()
     }
 }
 
@@ -2176,7 +2127,7 @@ impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
 impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
     pub fn from_iterator(iterator: &mut T) -> ~[A] {
         let (lower, _) = iterator.size_hint();
-        let mut xs = with_capacity(lower.get_or_zero());
+        let mut xs = with_capacity(lower);
         for iterator.advance |x| {
             xs.push(x);
         }
@@ -2459,6 +2410,17 @@ mod tests {
     }
 
     #[test]
+    fn test_pop_opt() {
+        let mut v = ~[5];
+        let e = v.pop_opt();
+        assert_eq!(v.len(), 0);
+        assert_eq!(e, Some(5));
+        let f = v.pop_opt();
+        assert_eq!(f, None);
+        let g = v.pop_opt();
+        assert_eq!(g, None);
+    }
+
     fn test_swap_remove() {
         let mut v = ~[1, 2, 3, 4, 5];
         let mut e = v.swap_remove(0);
@@ -2627,87 +2589,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);
@@ -2821,75 +2702,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]
@@ -2933,28 +2756,24 @@ 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, &[]);
+    fn test_shift() {
+        let mut x = ~[1, 2, 3];
+        assert_eq!(x.shift(), 1);
+        assert_eq!(&x, &~[2, 3]);
+        assert_eq!(x.shift(), 2);
+        assert_eq!(x.shift(), 3);
+        assert_eq!(x.len(), 0);
     }
 
     #[test]
-    #[should_fail]
-    #[ignore(cfg(windows))]
-    fn test_windowed_() {
-        for windowed (0u, [1u,2u,3u,4u,5u,6u]) |_v| {}
+    fn test_shift_opt() {
+        let mut x = ~[1, 2, 3];
+        assert_eq!(x.shift_opt(), Some(1));
+        assert_eq!(&x, &~[2, 3]);
+        assert_eq!(x.shift_opt(), Some(2));
+        assert_eq!(x.shift_opt(), Some(3));
+        assert_eq!(x.shift_opt(), None);
+        assert_eq!(x.len(), 0);
     }
 
     #[test]
@@ -3061,156 +2880,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| {
@@ -3239,21 +2908,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;
@@ -3269,38 +2923,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;
@@ -3333,7 +2955,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!()
         }
     }
@@ -3343,7 +2965,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!()
         }
     }
@@ -3373,21 +2995,31 @@ mod tests {
         use iterator::*;
         let xs = [1, 2, 5, 10, 11];
         let mut it = xs.iter();
-        assert_eq!(it.size_hint(), (Some(5), Some(5)));
+        assert_eq!(it.size_hint(), (5, Some(5)));
         assert_eq!(it.next().unwrap(), &1);
-        assert_eq!(it.size_hint(), (Some(4), Some(4)));
+        assert_eq!(it.size_hint(), (4, Some(4)));
         assert_eq!(it.next().unwrap(), &2);
-        assert_eq!(it.size_hint(), (Some(3), Some(3)));
+        assert_eq!(it.size_hint(), (3, Some(3)));
         assert_eq!(it.next().unwrap(), &5);
-        assert_eq!(it.size_hint(), (Some(2), Some(2)));
+        assert_eq!(it.size_hint(), (2, Some(2)));
         assert_eq!(it.next().unwrap(), &10);
-        assert_eq!(it.size_hint(), (Some(1), Some(1)));
+        assert_eq!(it.size_hint(), (1, Some(1)));
         assert_eq!(it.next().unwrap(), &11);
-        assert_eq!(it.size_hint(), (Some(0), Some(0)));
+        assert_eq!(it.size_hint(), (0, Some(0)));
         assert!(it.next().is_none());
     }
 
     #[test]
+    fn test_iter_size_hints() {
+        use iterator::*;
+        let mut xs = [1, 2, 5, 10, 11];
+        assert_eq!(xs.iter().size_hint(), (5, Some(5)));
+        assert_eq!(xs.rev_iter().size_hint(), (5, Some(5)));
+        assert_eq!(xs.mut_iter().size_hint(), (5, Some(5)));
+        assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5)));
+    }
+
+    #[test]
     fn test_mut_iterator() {
         use iterator::*;
         let mut xs = [1, 2, 3, 4, 5];
@@ -3422,6 +3054,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];