//! Vectors

#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
#[warn(non_camel_case_types)];

use cmp::{Eq, Ord};
use option::{Some, None};
use ptr::addr_of;
use libc::size_t;

#[abi = "cdecl"]
extern mod rustrt {
    fn vec_reserve_shared(++t: *sys::TypeDesc,
                          ++v: **raw::VecRepr,
                          ++n: libc::size_t);
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn move_val_init<T>(dst: &mut T, -src: T);
}


/// Returns true if a vector contains no elements
pub pure fn is_empty<T>(v: &[const T]) -> bool {
    as_const_buf(v, |_p, len| len == 0u)
}

/// Returns true if a vector contains some elements
pub pure fn is_not_empty<T>(v: &[const T]) -> bool {
    as_const_buf(v, |_p, len| len > 0u)
}

/// Returns true if two vectors have the same length
pub pure fn same_length<T, U>(xs: &[const T], ys: &[const U]) -> bool {
    len(xs) == len(ys)
}

/**
 * Reserves capacity for exactly `n` elements in the given vector.
 *
 * If the capacity for `v` is already equal to or greater than the requested
 * capacity, then no action is taken.
 *
 * # Arguments
 *
 * * v - A vector
 * * n - The number of elements to reserve space for
 */
pub fn reserve<T>(v: &mut ~[T], n: uint) {
    // Only make the (slow) call into the runtime if we have to
    if capacity(v) < n {
        unsafe {
            let ptr: **raw::VecRepr = cast::transmute(v);
            rustrt::vec_reserve_shared(sys::get_type_desc::<T>(),
                                       ptr, n as size_t);
        }
    }
}

/**
 * Reserves capacity for at least `n` elements in the given vector.
 *
 * This function will over-allocate in order to amortize the allocation costs
 * in scenarios where the caller may need to repeatedly reserve additional
 * space.
 *
 * If the capacity for `v` is already equal to or greater than the requested
 * capacity, then no action is taken.
 *
 * # Arguments
 *
 * * v - A vector
 * * n - The number of elements to reserve space for
 */
pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) {
    reserve(v, uint::next_power_of_two(n));
}

/// Returns the number of elements the vector can hold without reallocating
#[inline(always)]
pub pure fn capacity<T>(v: &const ~[T]) -> uint {
    unsafe {
        let repr: **raw::VecRepr = ::cast::transmute(v);
        (**repr).unboxed.alloc / sys::size_of::<T>()
    }
}

/// Returns the length of a vector
#[inline(always)]
pub pure fn len<T>(v: &[const T]) -> uint {
    as_const_buf(v, |_p, len| len)
}

/**
 * Creates and initializes an immutable vector.
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value returned by the function `op`.
 */
pub pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> ~[T] {
    unsafe {
        let mut v = with_capacity(n_elts);
        do as_mut_buf(v) |p, _len| {
            let mut i: uint = 0u;
            while i < n_elts {
                rusti::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
                i += 1u;
            }
        }
        raw::set_len(&mut v, n_elts);
        return move v;
    }
}

/**
 * Creates and initializes an immutable vector.
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value `t`.
 */
pub pure fn from_elem<T: Copy>(n_elts: uint, t: T) -> ~[T] {
    from_fn(n_elts, |_i| copy t)
}

/// Creates a new unique vector with the same contents as the slice
pub pure fn from_slice<T: Copy>(t: &[T]) -> ~[T] {
    from_fn(t.len(), |i| t[i])
}

pub pure fn with_capacity<T>(capacity: uint) -> ~[T] {
    let mut vec = ~[];
    unsafe { reserve(&mut vec, capacity); }
    return move vec;
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 * This version takes an initial size for the vector.
 *
 * # Arguments
 *
 * * size - An initial size of the vector to reserve
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pub pure fn build_sized<A>(size: uint,
                       builder: fn(push: pure fn(v: A))) -> ~[A] {
    let mut vec = with_capacity(size);
    builder(|x| unsafe { vec.push(move x) });
    move vec
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 *
 * # Arguments
 *
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pub pure fn build<A>(builder: fn(push: pure fn(v: A))) -> ~[A] {
    build_sized(4, builder)
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 * This version takes an initial size for the vector.
 *
 * # Arguments
 *
 * * size - An option, maybe containing initial size of the vector to reserve
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pub pure fn build_sized_opt<A>(size: Option<uint>,
                           builder: fn(push: pure fn(v: A))) -> ~[A] {
    build_sized(size.get_default(4), builder)
}

/// Produces a mut vector from an immutable vector.
pub pure fn to_mut<T>(v: ~[T]) -> ~[mut T] {
    unsafe { ::cast::transmute(move v) }
}

/// Produces an immutable vector from a mut vector.
pub pure fn from_mut<T>(v: ~[mut T]) -> ~[T] {
    unsafe { ::cast::transmute(move v) }
}

// Accessors

/// Returns the first element of a vector
pub pure fn head<T: Copy>(v: &[const T]) -> T { v[0] }

/// Returns a vector containing all but the first element of a slice
pub pure fn tail<T: Copy>(v: &[const T]) -> ~[T] {
    return slice(v, 1u, len(v));
}

/**
 * Returns a vector containing all but the first `n` \
 * elements of a slice
 */
pub pure fn tailn<T: Copy>(v: &[const T], n: uint) -> ~[T] {
    slice(v, n, len(v))
}

/// Returns a vector containing all but the last element of a slice
pub pure fn init<T: Copy>(v: &[const T]) -> ~[T] {
    assert len(v) != 0u;
    slice(v, 0u, len(v) - 1u)
}

/// Returns the last element of the slice `v`, failing if the slice is empty.
pub pure fn last<T: Copy>(v: &[const T]) -> T {
    if len(v) == 0u { fail ~"last_unsafe: empty vector" }
    v[len(v) - 1u]
}

/**
 * Returns `Some(x)` where `x` is the last element of the slice `v`,
 * or `none` if the vector is empty.
 */
pub pure fn last_opt<T: Copy>(v: &[const T]) -> Option<T> {
    if len(v) == 0u { return None; }
    Some(v[len(v) - 1u])
}

/// Returns a copy of the elements from [`start`..`end`) from `v`.
pub pure fn slice<T: Copy>(v: &[const T], start: uint, end: uint) -> ~[T] {
    assert (start <= end);
    assert (end <= len(v));
    let mut result = ~[];
    unsafe {
        for uint::range(start, end) |i| { result.push(v[i]) }
    }
    move result
}

/// Return a slice that points into another slice.
pub pure fn view<T>(v: &r/[T], start: uint, end: uint) -> &r/[T] {
    assert (start <= end);
    assert (end <= len(v));
    do as_imm_buf(v) |p, _len| {
        unsafe {
            ::cast::reinterpret_cast(
                &(ptr::offset(p, start),
                  (end - start) * sys::size_of::<T>()))
        }
    }
}

/// Return a slice that points into another slice.
pub pure fn mut_view<T>(v: &r/[mut T], start: uint, end: uint) -> &r/[mut T] {
    assert (start <= end);
    assert (end <= len(v));
    do as_mut_buf(v) |p, _len| {
        unsafe {
            ::cast::reinterpret_cast(
                &(ptr::mut_offset(p, start),
                  (end - start) * sys::size_of::<T>()))
        }
    }
}

/// Return a slice that points into another slice.
pub pure fn const_view<T>(v: &r/[const T], start: uint,
                      end: uint) -> &r/[const T] {
    assert (start <= end);
    assert (end <= len(v));
    do as_const_buf(v) |p, _len| {
        unsafe {
            ::cast::reinterpret_cast(
                &(ptr::const_offset(p, start),
                  (end - start) * sys::size_of::<T>()))
        }
    }
}

/// 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 = len(v);
    if (ln == 0u) { return ~[] }

    let mut start = 0u;
    let mut result = ~[];
    while start < ln {
        match position_between(v, start, ln, f) {
            None => break,
            Some(i) => {
                result.push(slice(v, start, i));
                start = i + 1u;
            }
        }
    }
    result.push(slice(v, start, ln));
    move 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 = len(v);
    if (ln == 0u) { return ~[] }

    let mut start = 0u;
    let mut count = n;
    let mut result = ~[];
    while start < ln && count > 0u {
        match position_between(v, start, ln, f) {
            None => break,
            Some(i) => {
                result.push(slice(v, start, i));
                // Make sure to skip the separator.
                start = i + 1u;
                count -= 1u;
            }
        }
    }
    result.push(slice(v, start, ln));
    move 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 = len(v);
    if (ln == 0u) { return ~[] }

    let mut end = ln;
    let mut result = ~[];
    while end > 0u {
        match rposition_between(v, 0u, end, f) {
            None => break,
            Some(i) => {
                result.push(slice(v, i + 1u, end));
                end = i;
            }
        }
    }
    result.push(slice(v, 0u, end));
    reverse(result);
    return move result;
}

/**
 * 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 = len(v);
    if (ln == 0u) { return ~[] }

    let mut end = ln;
    let mut count = n;
    let mut result = ~[];
    while end > 0u && count > 0u {
        match rposition_between(v, 0u, end, f) {
            None => break,
            Some(i) => {
                result.push(slice(v, i + 1u, end));
                // Make sure to skip the separator.
                end = i;
                count -= 1u;
            }
        }
    }
    result.push(slice(v, 0u, end));
    reverse(result);
    move result
}

// Mutators

/// Removes the first element from a vector and return it
pub fn shift<T>(v: &mut ~[T]) -> T {
    let ln = v.len();
    assert (ln > 0);

    let mut vv = ~[];
    *v <-> vv;

    unsafe {
        let mut rr;
        {
            let vv = raw::to_ptr(vv);
            rr <- *vv;

            for uint::range(1, ln) |i| {
                let r <- *ptr::offset(vv, i);
                v.push(move r);
            }
        }
        raw::set_len(&mut vv, 0);

        move rr
    }
}

/// Prepend an element to the vector
pub fn unshift<T>(v: &mut ~[T], x: T) {
    let mut vv = ~[move x];
    *v <-> vv;
    v.push_all_move(vv);
}

pub fn consume<T>(v: ~[T], f: fn(uint, v: T)) unsafe {
    let mut v = move v; // FIXME(#3488)

    do as_imm_buf(v) |p, ln| {
        for uint::range(0, ln) |i| {
            let x <- *ptr::offset(p, i);
            f(i, move x);
        }
    }

    raw::set_len(&mut v, 0);
}

pub fn consume_mut<T>(v: ~[mut T], f: fn(uint, v: T)) {
    consume(vec::from_mut(v), f)
}

/// Remove the last element from a vector and return it
pub fn pop<T>(v: &mut ~[T]) -> T {
    let ln = v.len();
    if ln == 0 {
        fail ~"sorry, cannot vec::pop an empty vector"
    }
    let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]);
    unsafe {
        let val = move *valptr;
        raw::set_len(v, ln - 1u);
        move val
    }
}

/**
 * Remove an element from anywhere in the vector and return it, replacing it
 * with the last element. This does not preserve ordering, but is O(1).
 *
 * Fails if index >= length.
 */
pub fn swap_remove<T>(v: &mut ~[T], index: uint) -> T {
    let ln = v.len();
    if index >= ln {
        fail fmt!("vec::swap_remove - index %u >= length %u", index, ln);
    }
    if index < ln - 1 {
        v[index] <-> v[ln - 1];
    }
    vec::pop(v)
}

/// Append an element to a vector
#[inline(always)]
pub fn push<T>(v: &mut ~[T], initval: T) {
    unsafe {
        let repr: **raw::VecRepr = ::cast::transmute(copy v);
        let fill = (**repr).unboxed.fill;
        if (**repr).unboxed.alloc > fill {
            push_fast(v, move initval);
        }
        else {
            push_slow(v, move initval);
        }
    }
}

// This doesn't bother to make sure we have space.
#[inline(always)] // really pretty please
unsafe fn push_fast<T>(v: &mut ~[T], initval: T) {
    let repr: **raw::VecRepr = ::cast::transmute(v);
    let fill = (**repr).unboxed.fill;
    (**repr).unboxed.fill += sys::size_of::<T>();
    let p = addr_of(&((**repr).unboxed.data));
    let p = ptr::offset(p, fill) as *mut T;
    rusti::move_val_init(&mut(*p), move initval);
}

#[inline(never)]
fn push_slow<T>(v: &mut ~[T], initval: T) {
    reserve_at_least(v, v.len() + 1u);
    unsafe { push_fast(v, move initval) }
}

#[inline(always)]
pub fn push_all<T: Copy>(v: &mut ~[T], rhs: &[const T]) {
    reserve(v, v.len() + rhs.len());

    for uint::range(0u, rhs.len()) |i| {
        push(v, unsafe { raw::get(rhs, i) })
    }
}

#[inline(always)]
pub fn push_all_move<T>(v: &mut ~[T], rhs: ~[T]) {
    let mut rhs = move rhs; // FIXME(#3488)
    reserve(v, v.len() + rhs.len());
    unsafe {
        do as_imm_buf(rhs) |p, len| {
            for uint::range(0, len) |i| {
                let x <- *ptr::offset(p, i);
                push(v, move x);
            }
        }
        raw::set_len(&mut rhs, 0);
    }
}

/// Shorten a vector, dropping excess elements.
pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
    do as_imm_buf(*v) |p, oldlen| {
        assert(newlen <= oldlen);
        unsafe {
            // This loop is optimized out for non-drop types.
            for uint::range(newlen, oldlen) |i| {
                let _dropped <- *ptr::offset(p, i);
            }
            raw::set_len(v, newlen);
        }
    }
}

/**
 * Remove consecutive repeated elements from a vector; if the vector is
 * sorted, this removes all duplicates.
 */
pub fn dedup<T: Eq>(v: &mut ~[T]) unsafe {
    if v.len() < 1 { return; }
    let mut last_written = 0, next_to_read = 1;
    do as_const_buf(*v) |p, ln| {
        // We have a mutable reference to v, so we can make arbitrary changes.
        // (cf. push and pop)
        let p = p as *mut T;
        // last_written < next_to_read <= ln
        while next_to_read < ln {
            // last_written < next_to_read < ln
            if *ptr::mut_offset(p, next_to_read) ==
                *ptr::mut_offset(p, last_written) {
                let _dropped <- *ptr::mut_offset(p, next_to_read);
            } else {
                last_written += 1;
                // last_written <= next_to_read < ln
                if next_to_read != last_written {
                    *ptr::mut_offset(p, last_written) <-
                        *ptr::mut_offset(p, next_to_read);
                }
            }
            // last_written <= next_to_read < ln
            next_to_read += 1;
            // last_written < next_to_read <= ln
        }
    }
    // last_written < next_to_read == ln
    raw::set_len(v, last_written + 1);
}


// Appending
#[inline(always)]
pub pure fn append<T: Copy>(lhs: ~[T], rhs: &[const T]) -> ~[T] {
    let mut v <- lhs;
    unsafe {
        v.push_all(rhs);
    }
    move v
}

#[inline(always)]
pub pure fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
    let mut v <- lhs;
    unsafe { v.push(move x); }
    move v
}

#[inline(always)]
pure fn append_mut<T: Copy>(lhs: ~[mut T], rhs: &[const T]) -> ~[mut T] {
    to_mut(append(from_mut(lhs), rhs))
}

/**
 * Expands a vector in place, initializing the new elements to a given value
 *
 * # Arguments
 *
 * * v - The vector to grow
 * * n - The number of elements to add
 * * initval - The value for the new elements
 */
pub fn grow<T: Copy>(v: &mut ~[T], n: uint, initval: &T) {
    reserve_at_least(v, v.len() + n);
    let mut i: uint = 0u;

    while i < n {
        v.push(*initval);
        i += 1u;
    }
}

/**
 * Expands a vector in place, initializing the new elements to the result of
 * a function
 *
 * Function `init_op` is called `n` times with the values [0..`n`)
 *
 * # Arguments
 *
 * * v - The vector to grow
 * * n - The number of elements to add
 * * init_op - A function to call to retreive each appended element's
 *             value
 */
pub fn grow_fn<T>(v: &mut ~[T], n: uint, op: iter::InitOp<T>) {
    reserve_at_least(v, v.len() + n);
    let mut i: uint = 0u;
    while i < n {
        v.push(op(i));
        i += 1u;
    }
}

/**
 * Sets the value of a vector element at a given index, growing the vector as
 * needed
 *
 * Sets the element at position `index` to `val`. If `index` is past the end
 * of the vector, expands the vector by replicating `initval` to fill the
 * intervening space.
 */
pub fn grow_set<T: Copy>(v: &mut ~[T], index: uint, initval: &T, val: T) {
    let l = v.len();
    if index >= l { grow(v, index - l + 1u, initval); }
    v[index] = move val;
}

// Functional utilities

/// Apply a function to each element of a vector and return the results
pub pure fn map<T, U>(v: &[T], f: fn(t: &T) -> U) -> ~[U] {
    let mut result = with_capacity(len(v));
    for each(v) |elem| {
        unsafe {
            result.push(f(elem));
        }
    }
    move result
}

pub fn map_consume<T, U>(v: ~[T], f: fn(v: T) -> U) -> ~[U] {
    let mut result = ~[];
    do consume(move v) |_i, x| {
        result.push(f(move x));
    }
    move result
}

/// Apply a function to each element of a vector and return the results
pub pure fn mapi<T, U>(v: &[T], f: fn(uint, t: &T) -> U) -> ~[U] {
    let mut i = 0;
    do map(v) |e| {
        i += 1;
        f(i - 1, e)
    }
}

/**
 * Apply a function to each element of a vector and return a concatenation
 * of each result vector
 */
pub pure fn flat_map<T, U>(v: &[T], f: fn(t: &T) -> ~[U]) -> ~[U] {
    let mut result = ~[];
    for each(v) |elem| { unsafe{ result.push_all_move(f(elem)); } }
    move result
}

/// Apply a function to each pair of elements and return the results
pub pure fn map2<T: Copy, U: Copy, V>(v0: &[T], v1: &[U],
                                  f: fn(t: &T, v: &U) -> V) -> ~[V] {
    let v0_len = len(v0);
    if v0_len != len(v1) { fail; }
    let mut u: ~[V] = ~[];
    let mut i = 0u;
    while i < v0_len {
        unsafe { u.push(f(&v0[i], &v1[i])) };
        i += 1u;
    }
    move u
}

/**
 * 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.
 */
pub pure fn filter_map<T, U: Copy>(v: &[T], f: fn(t: &T) -> Option<U>)
    -> ~[U] {
    let mut result = ~[];
    for each(v) |elem| {
        match f(elem) {
          None => {/* no-op */ }
          Some(move result_elem) => unsafe { result.push(result_elem); }
        }
    }
    move 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 pure fn filter<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> ~[T] {
    let mut result = ~[];
    for each(v) |elem| {
        if f(elem) { unsafe { result.push(*elem); } }
    }
    move result
}

/**
 * Concatenate a vector of vectors.
 *
 * Flattens a vector of vectors of T into a single vector of T.
 */
pub pure fn concat<T: Copy>(v: &[~[T]]) -> ~[T] {
    let mut r = ~[];
    for each(v) |inner| { unsafe { r.push_all(*inner); } }
    move r
}

/// Concatenate a vector of vectors, placing a given separator between each
pub pure fn connect<T: Copy>(v: &[~[T]], sep: &T) -> ~[T] {
    let mut r: ~[T] = ~[];
    let mut first = true;
    for each(v) |inner| {
        if first { first = false; } else { unsafe { r.push(*sep); } }
        unsafe { r.push_all(*inner) };
    }
    move r
}

/// Reduce a vector from left to right
pub pure fn foldl<T: Copy, U>(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T {
    let mut accum = z;
    for each(v) |elt| {
        // it should be possible to move accum in, but the liveness analysis
        // is not smart enough.
        accum = p(accum, elt);
    }
    return accum;
}

/// Reduce a vector from right to left
pub pure fn foldr<T, U: Copy>(v: &[T], z: U, p: fn(t: &T, u: U) -> U) -> U {
    let mut accum = z;
    for rev_each(v) |elt| {
        accum = p(elt, accum);
    }
    return accum;
}

/**
 * Return true if a predicate matches any elements
 *
 * If the vector contains no elements then false is returned.
 */
pub pure fn any<T>(v: &[T], f: fn(t: &T) -> bool) -> bool {
    for each(v) |elem| { if f(elem) { return true; } }
    return false;
}

/**
 * Return true if a predicate matches any elements in both vectors.
 *
 * If the vectors contains no elements then false is returned.
 */
pub pure fn any2<T, U>(v0: &[T], v1: &[U],
                   f: fn(a: &T, b: &U) -> bool) -> bool {
    let v0_len = len(v0);
    let v1_len = len(v1);
    let mut i = 0u;
    while i < v0_len && i < v1_len {
        if f(&v0[i], &v1[i]) { return true; };
        i += 1u;
    }
    return false;
}

/**
 * Return true if a predicate matches all elements
 *
 * If the vector contains no elements then true is returned.
 */
pub pure fn all<T>(v: &[T], f: fn(t: &T) -> bool) -> bool {
    for each(v) |elem| { if !f(elem) { return false; } }
    return true;
}

/**
 * Return true if a predicate matches all elements
 *
 * If the vector contains no elements then true is returned.
 */
pub pure fn alli<T>(v: &[T], f: fn(uint, t: &T) -> bool) -> bool {
    for eachi(v) |i, elem| { if !f(i, elem) { return false; } }
    return true;
}

/**
 * Return true if a predicate matches all elements in both vectors.
 *
 * If the vectors are not the same size then false is returned.
 */
pub pure fn all2<T, U>(v0: &[T], v1: &[U],
                   f: fn(t: &T, u: &U) -> bool) -> bool {
    let v0_len = len(v0);
    if v0_len != len(v1) { return false; }
    let mut i = 0u;
    while i < v0_len { if !f(&v0[i], &v1[i]) { return false; }; i += 1u; }
    return true;
}

/// Return true if a vector contains an element with the given value
pub pure fn contains<T: Eq>(v: &[T], x: &T) -> bool {
    for each(v) |elt| { if *x == *elt { return true; } }
    return false;
}

/// Returns the number of elements that are equal to a given value
pub pure fn count<T: Eq>(v: &[T], x: &T) -> uint {
    let mut cnt = 0u;
    for each(v) |elt| { if *x == *elt { cnt += 1u; } }
    return cnt;
}

/**
 * Search for the first element that matches a given predicate
 *
 * Apply function `f` to each element of `v`, starting from the first.
 * When function `f` returns true then an option containing the element
 * is returned. If `f` matches no elements then none is returned.
 */
pub pure fn find<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> Option<T> {
    find_between(v, 0u, len(v), f)
}

/**
 * Search for the first element that matches a given predicate within a range
 *
 * Apply function `f` to each element of `v` within the range
 * [`start`, `end`). When function `f` returns true then an option containing
 * the element is returned. If `f` matches no elements then none is returned.
 */
pub pure fn find_between<T: Copy>(v: &[T], start: uint, end: uint,
                      f: fn(t: &T) -> bool) -> Option<T> {
    position_between(v, start, end, f).map(|i| v[*i])
}

/**
 * Search for the last element that matches a given predicate
 *
 * Apply function `f` to each element of `v` in reverse order. When function
 * `f` returns true then an option containing the element is returned. If `f`
 * matches no elements then none is returned.
 */
pub pure fn rfind<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> Option<T> {
    rfind_between(v, 0u, len(v), f)
}

/**
 * Search for the last element that matches a given predicate within a range
 *
 * Apply function `f` to each element of `v` in reverse order within the range
 * [`start`, `end`). When function `f` returns true then an option containing
 * the element is returned. If `f` matches no elements then none is return.
 */
pub pure fn rfind_between<T: Copy>(v: &[T], start: uint, end: uint,
                               f: fn(t: &T) -> bool) -> Option<T> {
    rposition_between(v, start, end, f).map(|i| v[*i])
}

/// Find the first index containing a matching value
pub pure fn position_elem<T: Eq>(v: &[T], x: &T) -> Option<uint> {
    position(v, |y| *x == *y)
}

/**
 * Find the first index matching some predicate
 *
 * Apply function `f` to each element of `v`.  When function `f` returns true
 * then an option containing the index is returned. If `f` matches no elements
 * then none is returned.
 */
pub pure fn position<T>(v: &[T], f: fn(t: &T) -> bool) -> Option<uint> {
    position_between(v, 0u, len(v), f)
}

/**
 * Find the first index matching some predicate within a range
 *
 * Apply function `f` to each element of `v` between the range
 * [`start`, `end`). When function `f` returns true then an option containing
 * the index is returned. If `f` matches no elements then none is returned.
 */
pub pure fn position_between<T>(v: &[T], start: uint, end: uint,
                            f: fn(t: &T) -> bool) -> Option<uint> {
    assert start <= end;
    assert end <= len(v);
    let mut i = start;
    while i < end { if f(&v[i]) { return Some::<uint>(i); } i += 1u; }
    return None;
}

/// Find the last index containing a matching value
pure fn rposition_elem<T: Eq>(v: &[T], x: &T) -> Option<uint> {
    rposition(v, |y| *x == *y)
}

/**
 * Find the last index matching some predicate
 *
 * Apply function `f` to each element of `v` in reverse order.  When function
 * `f` returns true then an option containing the index is returned. If `f`
 * matches no elements then none is returned.
 */
pub pure fn rposition<T>(v: &[T], f: fn(t: &T) -> bool) -> Option<uint> {
    rposition_between(v, 0u, len(v), f)
}

/**
 * Find the last index matching some predicate within a range
 *
 * Apply function `f` to each element of `v` in reverse order between the
 * range [`start`, `end`). When function `f` returns true then an option
 * containing the index is returned. If `f` matches no elements then none is
 * returned.
 */
pub pure fn rposition_between<T>(v: &[T], start: uint, end: uint,
                             f: fn(t: &T) -> bool) -> Option<uint> {
    assert start <= end;
    assert end <= len(v);
    let mut i = end;
    while i > start {
        if f(&v[i - 1u]) { return Some::<uint>(i - 1u); }
        i -= 1u;
    }
    return None;
}

// FIXME: if issue #586 gets implemented, could have a postcondition
// saying the two result lists have the same length -- or, could
// return a nominal record with a constraint saying that, instead of
// returning a tuple (contingent on issue #869)
/**
 * Convert a vector of pairs into a pair of vectors, by reference. As unzip().
 */
pure fn unzip_slice<T: Copy, U: Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
    let mut ts = ~[], us = ~[];
    for each(v) |p| {
        let (t, u) = *p;
        unsafe {
            ts.push(t);
            us.push(u);
        }
    }
    return (move ts, move us);
}

/**
 * Convert a vector of pairs into a pair of vectors.
 *
 * Returns a tuple containing two vectors where the i-th element of the first
 * vector contains the first element of the i-th tuple of the input vector,
 * and the i-th element of the second vector contains the second element
 * of the i-th tuple of the input vector.
 */
pub pure fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
    let mut ts = ~[], us = ~[];
    unsafe {
        do consume(move v) |_i, p| {
            let (t, u) = move p;
            ts.push(move t);
            us.push(move u);
        }
    }
    (move ts, move us)
}

/**
 * Convert two vectors to a vector of pairs, by reference. As zip().
 */
pub pure fn zip_slice<T: Copy, U: Copy>(v: &[const T], u: &[const U])
        -> ~[(T, U)] {
    let mut zipped = ~[];
    let sz = len(v);
    let mut i = 0u;
    assert sz == len(u);
    while i < sz unsafe { zipped.push((v[i], u[i])); i += 1u; }
    move zipped
}

/**
 * Convert two vectors to a vector of pairs.
 *
 * Returns a vector of tuples, where the i-th tuple contains contains the
 * i-th elements from each of the input vectors.
 */
pub pure fn zip<T, U>(v: ~[T], u: ~[U]) -> ~[(T, U)] {
    let mut v = move v, u = move u; // FIXME(#3488)
    let mut i = len(v);
    assert i == len(u);
    let mut w = with_capacity(i);
    while i > 0 {
        unsafe { w.push((v.pop(),u.pop())); }
        i -= 1;
    }
    unsafe { reverse(w); }
    move w
}

/**
 * Swaps two elements in a vector
 *
 * # Arguments
 *
 * * v  The input vector
 * * a - The index of the first element
 * * b - The index of the second element
 */
pub fn swap<T>(v: &[mut T], a: uint, b: uint) {
    v[a] <-> v[b];
}

/// Reverse the order of elements in a vector, in place
pub fn reverse<T>(v: &[mut T]) {
    let mut i: uint = 0u;
    let ln = len::<T>(v);
    while i < ln / 2u { v[i] <-> v[ln - i - 1u]; i += 1u; }
}

/// Returns a vector with the order of elements reversed
pub pure fn reversed<T: Copy>(v: &[const T]) -> ~[T] {
    let mut rs: ~[T] = ~[];
    let mut i = len::<T>(v);
    if i == 0 { return (move rs); } else { i -= 1; }
    unsafe {
        while i != 0 { rs.push(v[i]); i -= 1; }
        rs.push(v[0]);
    }
    move rs
}

/**
 * Iterates over a vector, with option to break
 *
 * Return true to continue, false to break.
 */
#[inline(always)]
pub pure fn each<T>(v: &r/[T], f: fn((&r/T)) -> bool) {
    //             ^^^^
    // NB---this CANNOT be &[const T]!  The reason
    // is that you are passing it to `f()` using
    // an immutable.

    do vec::as_imm_buf(v) |p, n| {
        let mut n = n;
        let mut p = p;
        while n > 0u {
            unsafe {
                let q = cast::copy_lifetime_vec(v, &*p);
                if !f(q) { break; }
                p = ptr::offset(p, 1u);
            }
            n -= 1u;
        }
    }
}

/// Like `each()`, but for the case where you have
/// a vector with mutable contents and you would like
/// to mutate the contents as you iterate.
#[inline(always)]
pub fn each_mut<T>(v: &[mut T], f: fn(elem: &mut T) -> bool) {
    let mut i = 0;
    let n = v.len();
    while i < n {
        if !f(&mut v[i]) {
            return;
        }
        i += 1;
    }
}

/// Like `each()`, but for the case where you have a vector that *may or may
/// not* have mutable contents.
#[inline(always)]
pub pure fn each_const<T>(v: &[const T], f: fn(elem: &const T) -> bool) {
    let mut i = 0;
    let n = v.len();
    while i < n {
        if !f(&const v[i]) {
            return;
        }
        i += 1;
    }
}

/**
 * Iterates over a vector's elements and indices
 *
 * Return true to continue, false to break.
 */
#[inline(always)]
pub pure fn eachi<T>(v: &r/[T], f: fn(uint, v: &r/T) -> bool) {
    let mut i = 0;
    for each(v) |p| {
        if !f(i, p) { return; }
        i += 1;
    }
}

/**
 * Iterates over a vector's elements in reverse
 *
 * Return true to continue, false to break.
 */
#[inline(always)]
pub pure fn rev_each<T>(v: &r/[T], blk: fn(v: &r/T) -> bool) {
    rev_eachi(v, |_i, v| blk(v))
}

/**
 * Iterates over a vector's elements and indices in reverse
 *
 * Return true to continue, false to break.
 */
#[inline(always)]
pub pure fn rev_eachi<T>(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) {
    let mut i = v.len();
    while i > 0 {
        i -= 1;
        if !blk(i, &v[i]) {
            return;
        }
    }
}

/**
 * Iterates over two vectors simultaneously
 *
 * # Failure
 *
 * Both vectors must have the same length
 */
#[inline]
pub fn each2<U, T>(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) {
    assert len(v1) == len(v2);
    for uint::range(0u, len(v1)) |i| {
        if !f(&v1[i], &v2[i]) {
            return;
        }
    }
}

/**
 * Iterate over all permutations of vector `v`.
 *
 * Permutations are produced in lexicographic order with respect to the order
 * of elements in `v` (so if `v` is sorted then the permutations are
 * lexicographically sorted).
 *
 * The total number of permutations produced is `len(v)!`.  If `v` contains
 * repeated elements, then some permutations are repeated.
 */
pure fn each_permutation<T: Copy>(v: &[T], put: fn(ts: &[T]) -> bool) {
    let ln = len(v);
    if ln <= 1 {
        put(v);
    } else {
        // This does not seem like the most efficient implementation.  You
        // could make far fewer copies if you put your mind to it.
        let mut i = 0u;
        while i < ln {
            let elt = v[i];
            let mut rest = slice(v, 0u, i);
            unsafe {
                rest.push_all(const_view(v, i+1u, ln));
                for each_permutation(rest) |permutation| {
                    if !put(append(~[elt], permutation)) {
                        return;
                    }
                }
            }
            i += 1u;
        }
    }
}

pub pure fn windowed<TT: Copy>(nn: uint, xx: &[TT]) -> ~[~[TT]] {
    let mut ww = ~[];
    assert 1u <= nn;
    for vec::eachi (xx) |ii, _x| {
        let len = vec::len(xx);
        if ii+nn <= len unsafe {
            ww.push(vec::slice(xx, ii, ii+nn));
        }
    }
    move ww
}

/**
 * Work with the buffer of a vector.
 *
 * Allows for unsafe manipulation of vector contents, which is useful for
 * foreign interop.
 */
#[inline(always)]
pub pure 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) =
            ::cast::reinterpret_cast(&addr_of(&s));
        let (buf,len) = *v;
        f(buf, len / sys::size_of::<T>())
    }
}

/// Similar to `as_imm_buf` but passing a `*const T`
#[inline(always)]
pub pure fn as_const_buf<T,U>(s: &[const T],
                          f: fn(*const T, uint) -> U) -> U {

    unsafe {
        let v : *(*const T,uint) =
            ::cast::reinterpret_cast(&addr_of(&s));
        let (buf,len) = *v;
        f(buf, len / sys::size_of::<T>())
    }
}

/// Similar to `as_imm_buf` but passing a `*mut T`
#[inline(always)]
pub pure fn as_mut_buf<T,U>(s: &[mut T],
                        f: fn(*mut T, uint) -> U) -> U {

    unsafe {
        let v : *(*mut T,uint) =
            ::cast::reinterpret_cast(&addr_of(&s));
        let (buf,len) = *v;
        f(buf, len / sys::size_of::<T>())
    }
}

// Equality

pure 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; }

    let mut i = 0;
    while i < a_len {
        if a[i] != b[i] { return false; }
        i += 1;
    }

    return true;
}

impl<T: Eq> &[T] : Eq {
    #[inline(always)]
    pure fn eq(other: & &[T]) -> bool { eq(self, (*other)) }
    #[inline(always)]
    pure fn ne(other: & &[T]) -> bool { !self.eq(other) }
}

impl<T: Eq> ~[T] : Eq {
    #[inline(always)]
    pure fn eq(other: &~[T]) -> bool { eq(self, (*other)) }
    #[inline(always)]
    pure fn ne(other: &~[T]) -> bool { !self.eq(other) }
}

impl<T: Eq> @[T] : Eq {
    #[inline(always)]
    pure fn eq(other: &@[T]) -> bool { eq(self, (*other)) }
    #[inline(always)]
    pure fn ne(other: &@[T]) -> bool { !self.eq(other) }
}

// Lexicographical comparison

pure fn lt<T: Ord>(a: &[T], b: &[T]) -> bool {
    let (a_len, b_len) = (a.len(), b.len());
    let mut end = uint::min(a_len, b_len);

    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;
    }

    return a_len < b_len;
}

pure fn le<T: Ord>(a: &[T], b: &[T]) -> bool { !lt(b, a) }
pure fn ge<T: Ord>(a: &[T], b: &[T]) -> bool { !lt(a, b) }
pure fn gt<T: Ord>(a: &[T], b: &[T]) -> bool { lt(b, a)  }

impl<T: Ord> &[T] : Ord {
    #[inline(always)]
    pure fn lt(other: & &[T]) -> bool { lt(self, (*other)) }
    #[inline(always)]
    pure fn le(other: & &[T]) -> bool { le(self, (*other)) }
    #[inline(always)]
    pure fn ge(other: & &[T]) -> bool { ge(self, (*other)) }
    #[inline(always)]
    pure fn gt(other: & &[T]) -> bool { gt(self, (*other)) }
}

impl<T: Ord> ~[T] : Ord {
    #[inline(always)]
    pure fn lt(other: &~[T]) -> bool { lt(self, (*other)) }
    #[inline(always)]
    pure fn le(other: &~[T]) -> bool { le(self, (*other)) }
    #[inline(always)]
    pure fn ge(other: &~[T]) -> bool { ge(self, (*other)) }
    #[inline(always)]
    pure fn gt(other: &~[T]) -> bool { gt(self, (*other)) }
}

impl<T: Ord> @[T] : Ord {
    #[inline(always)]
    pure fn lt(other: &@[T]) -> bool { lt(self, (*other)) }
    #[inline(always)]
    pure fn le(other: &@[T]) -> bool { le(self, (*other)) }
    #[inline(always)]
    pure fn ge(other: &@[T]) -> bool { ge(self, (*other)) }
    #[inline(always)]
    pure fn gt(other: &@[T]) -> bool { gt(self, (*other)) }
}

#[cfg(notest)]
pub mod traits {
    impl<T: Copy> ~[T] : Add<&[const T],~[T]> {
        #[inline(always)]
        pure fn add(rhs: & &[const T]) -> ~[T] {
            append(copy self, (*rhs))
        }
    }

    impl<T: Copy> ~[mut T] : Add<&[const T],~[mut T]> {
        #[inline(always)]
        pure fn add(rhs: & &[const T]) -> ~[mut T] {
            append_mut(copy self, (*rhs))
        }
    }
}

#[cfg(test)]
pub mod traits {}

pub trait ConstVector {
    pure fn is_empty() -> bool;
    pure fn is_not_empty() -> bool;
    pure fn len() -> uint;
}

/// Extension methods for vectors
impl<T> &[const T]: ConstVector {
    /// Returns true if a vector contains no elements
    #[inline]
    pure fn is_empty() -> bool { is_empty(self) }
    /// Returns true if a vector contains some elements
    #[inline]
    pure fn is_not_empty() -> bool { is_not_empty(self) }
    /// Returns the length of a vector
    #[inline]
    pure fn len() -> uint { len(self) }
}

pub trait CopyableVector<T> {
    pure fn head() -> T;
    pure fn init() -> ~[T];
    pure fn last() -> T;
    pure fn slice(start: uint, end: uint) -> ~[T];
    pure fn tail() -> ~[T];
}

/// Extension methods for vectors
impl<T: Copy> &[const T]: CopyableVector<T> {
    /// Returns the first element of a vector
    #[inline]
    pure fn head() -> T { head(self) }
    /// Returns all but the last elemnt of a vector
    #[inline]
    pure fn init() -> ~[T] { init(self) }
    /// Returns the last element of a `v`, failing if the vector is empty.
    #[inline]
    pure fn last() -> T { last(self) }
    /// Returns a copy of the elements from [`start`..`end`) from `v`.
    #[inline]
    pure fn slice(start: uint, end: uint) -> ~[T] { slice(self, start, end) }
    /// Returns all but the first element of a vector
    #[inline]
    pure fn tail() -> ~[T] { tail(self) }
}

pub trait ImmutableVector<T> {
    pure fn view(start: uint, end: uint) -> &self/[T];
    pure fn foldr<U: Copy>(z: U, p: fn(t: &T, u: U) -> U) -> U;
    pure fn map<U>(f: fn(t: &T) -> U) -> ~[U];
    pure fn mapi<U>(f: fn(uint, t: &T) -> U) -> ~[U];
    fn map_r<U>(f: fn(x: &T) -> U) -> ~[U];
    pure fn alli(f: fn(uint, t: &T) -> bool) -> bool;
    pure fn flat_map<U>(f: fn(t: &T) -> ~[U]) -> ~[U];
    pure fn filter_map<U: Copy>(f: fn(t: &T) -> Option<U>) -> ~[U];
}

pub trait ImmutableEqVector<T: Eq> {
    pure fn position(f: fn(t: &T) -> bool) -> Option<uint>;
    pure fn position_elem(t: &T) -> Option<uint>;
    pure fn rposition(f: fn(t: &T) -> bool) -> Option<uint>;
    pure fn rposition_elem(t: &T) -> Option<uint>;
}

/// Extension methods for vectors
impl<T> &[T]: ImmutableVector<T> {
    /// Return a slice that points into another slice.
    pure fn view(start: uint, end: uint) -> &self/[T] {
        view(self, start, end)
    }
    /// Reduce a vector from right to left
    #[inline]
    pure fn foldr<U: Copy>(z: U, p: fn(t: &T, u: U) -> U) -> U {
        foldr(self, z, p)
    }
    /// Apply a function to each element of a vector and return the results
    #[inline]
    pure fn map<U>(f: fn(t: &T) -> U) -> ~[U] { map(self, f) }
    /**
     * Apply a function to the index and value of each element in the vector
     * and return the results
     */
    pure fn mapi<U>(f: fn(uint, t: &T) -> U) -> ~[U] {
        mapi(self, f)
    }

    #[inline]
    fn map_r<U>(f: fn(x: &T) -> U) -> ~[U] {
        let mut r = ~[];
        let mut i = 0;
        while i < self.len() {
            r.push(f(&self[i]));
            i += 1;
        }
        move r
    }

    /**
     * Returns true if the function returns true for all elements.
     *
     *     If the vector is empty, true is returned.
     */
    pure fn alli(f: fn(uint, t: &T) -> bool) -> bool {
        alli(self, f)
    }
    /**
     * Apply a function to each element of a vector and return a concatenation
     * of each result vector
     */
    #[inline]
    pure fn flat_map<U>(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]
    pure fn filter_map<U: Copy>(f: fn(t: &T) -> Option<U>) -> ~[U] {
        filter_map(self, f)
    }
}

impl<T: Eq> &[T]: ImmutableEqVector<T> {
    /**
     * Find the first index matching some predicate
     *
     * Apply function `f` to each element of `v`.  When function `f` returns
     * true then an option containing the index is returned. If `f` matches no
     * elements then none is returned.
     */
    #[inline]
    pure fn position(f: fn(t: &T) -> bool) -> Option<uint> {
        position(self, f)
    }

    /// Find the first index containing a matching value
    #[inline]
    pure fn position_elem(x: &T) -> Option<uint> {
        position_elem(self, x)
    }

    /**
     * Find the last index matching some predicate
     *
     * Apply function `f` to each element of `v` in reverse order.  When
     * function `f` returns true then an option containing the index is
     * returned. If `f` matches no elements then none is returned.
     */
    #[inline]
    pure fn rposition(f: fn(t: &T) -> bool) -> Option<uint> {
        rposition(self, f)
    }

    /// Find the last index containing a matching value
    #[inline]
    pure fn rposition_elem(t: &T) -> Option<uint> {
        rposition_elem(self, t)
    }
}

pub trait ImmutableCopyableVector<T> {
    pure fn filter(f: fn(t: &T) -> bool) -> ~[T];

    pure fn rfind(f: fn(t: &T) -> bool) -> Option<T>;
}

/// Extension methods for vectors
impl<T: Copy> &[T]: ImmutableCopyableVector<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]
    pure fn filter(f: fn(t: &T) -> bool) -> ~[T] {
        filter(self, f)
    }

    /**
     * Search for the last element that matches a given predicate
     *
     * Apply function `f` to each element of `v` in reverse order. When
     * function `f` returns true then an option containing the element is
     * returned. If `f` matches no elements then none is returned.
     */
    #[inline]
    pure fn rfind(f: fn(t: &T) -> bool) -> Option<T> { rfind(self, f) }
}

pub trait MutableVector<T> {
    fn push(&mut self, t: T);
    fn push_all_move(&mut self, rhs: ~[T]);
    fn pop(&mut self) -> T;
    fn shift(&mut self) -> T;
    fn unshift(&mut self, x: T);
    fn swap_remove(&mut self, index: uint) -> T;
    fn truncate(&mut self, newlen: uint);
}

pub trait MutableCopyableVector<T: Copy> {
    fn push_all(&mut self, rhs: &[const T]);
    fn grow(&mut self, n: uint, initval: &T);
    fn grow_fn(&mut self, n: uint, op: iter::InitOp<T>);
    fn grow_set(&mut self, index: uint, initval: &T, val: T);
}

trait MutableEqVector<T: Eq> {
    fn dedup(&mut self);
}

impl<T> ~[T]: MutableVector<T> {
    fn push(&mut self, t: T) {
        push(self, move t);
    }

    fn push_all_move(&mut self, rhs: ~[T]) {
        push_all_move(self, move rhs);
    }

    fn pop(&mut self) -> T {
        pop(self)
    }

    fn shift(&mut self) -> T {
        shift(self)
    }

    fn unshift(&mut self, x: T) {
        unshift(self, x)
    }

    fn swap_remove(&mut self, index: uint) -> T {
        swap_remove(self, index)
    }

    fn truncate(&mut self, newlen: uint) {
        truncate(self, newlen);
    }
}

impl<T: Copy> ~[T]: MutableCopyableVector<T> {
    fn push_all(&mut self, rhs: &[const T]) {
        push_all(self, rhs);
    }

    fn grow(&mut self, n: uint, initval: &T) {
        grow(self, n, initval);
    }

    fn grow_fn(&mut self, n: uint, op: iter::InitOp<T>) {
        grow_fn(self, n, op);
    }

    fn grow_set(&mut self, index: uint, initval: &T, val: T) {
        grow_set(self, index, initval, val);
    }
}

impl<T: Eq> ~[T]: MutableEqVector<T> {
    fn dedup(&mut self) {
        dedup(self)
    }
}


/**
* Constructs a vector from an unsafe pointer to a buffer
*
* # Arguments
*
* * ptr - An unsafe pointer to a buffer of `T`
* * elts - The number of elements in the buffer
*/
// Wrapper for fn in raw: needs to be called by net_tcp::on_tcp_read_cb
pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
    raw::from_buf_raw(ptr, elts)
}

/// The internal 'unboxed' representation of a vector
pub struct UnboxedVecRepr {
    mut fill: uint,
    mut alloc: uint,
    data: u8
}

/// Unsafe operations
mod raw {

    /// The internal representation of a (boxed) vector
    pub struct VecRepr {
        box_header: box::raw::BoxHeaderRepr,
        unboxed: UnboxedVecRepr
    }

    pub type SliceRepr = {
        mut data: *u8,
        mut len: uint
    };

    /**
     * Sets the length of a vector
     *
     * This will explicitly set the size of the vector, without actually
     * modifing its buffers, so it is up to the caller to ensure that
     * the vector is actually the specified size.
     */
    #[inline(always)]
    pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
        let repr: **VecRepr = ::cast::transmute(v);
        (**repr).unboxed.fill = new_len * sys::size_of::<T>();
    }

    /**
     * Returns an unsafe pointer to the vector's buffer
     *
     * The caller must ensure that the vector outlives the pointer this
     * function returns, or else it will end up pointing to garbage.
     *
     * Modifying the vector may cause its buffer to be reallocated, which
     * would also make any pointers to it invalid.
     */
    #[inline(always)]
    pub unsafe fn to_ptr<T>(v: &[T]) -> *T {
        let repr: **SliceRepr = ::cast::transmute(&v);
        return ::cast::reinterpret_cast(&addr_of(&((**repr).data)));
    }

    /** see `to_ptr()` */
    #[inline(always)]
    pub unsafe fn to_const_ptr<T>(v: &[const T]) -> *const T {
        let repr: **SliceRepr = ::cast::transmute(&v);
        return ::cast::reinterpret_cast(&addr_of(&((**repr).data)));
    }

    /** see `to_ptr()` */
    #[inline(always)]
    pub unsafe fn to_mut_ptr<T>(v: &[mut T]) -> *mut T {
        let repr: **SliceRepr = ::cast::transmute(&v);
        return ::cast::reinterpret_cast(&addr_of(&((**repr).data)));
    }

    /**
     * Form a slice from a pointer and length (as a number of units,
     * not bytes).
     */
    #[inline(always)]
    pub unsafe fn buf_as_slice<T,U>(p: *T,
                                    len: uint,
                                    f: fn(v: &[T]) -> U) -> U {
        let pair = (p, len * sys::size_of::<T>());
        let v : *(&blk/[T]) =
            ::cast::reinterpret_cast(&addr_of(&pair));
        f(*v)
    }

    /**
     * Unchecked vector indexing.
     */
    #[inline(always)]
    pub unsafe fn get<T: Copy>(v: &[const T], i: uint) -> T {
        as_const_buf(v, |p, _len| *ptr::const_offset(p, i))
    }

    /**
     * Unchecked vector index assignment.  Does not drop the
     * old value and hence is only suitable when the vector
     * is newly allocated.
     */
    #[inline(always)]
    pub unsafe fn init_elem<T>(v: &[mut T], i: uint, val: T) {
        let mut box = Some(move val);
        do as_mut_buf(v) |p, _len| {
            let mut box2 = None;
            box2 <-> box;
            rusti::move_val_init(&mut(*ptr::mut_offset(p, i)),
                                 option::unwrap(move box2));
        }
    }

    /**
    * Constructs a vector from an unsafe pointer to a buffer
    *
    * # Arguments
    *
    * * ptr - An unsafe pointer to a buffer of `T`
    * * elts - The number of elements in the buffer
    */
    // Was in raw, but needs to be called by net_tcp::on_tcp_read_cb
    #[inline(always)]
    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::memcpy(p_dst, ptr, elts));
        move dst
    }

    /**
      * Copies data from one vector to another.
      *
      * Copies `count` bytes from `src` to `dst`. The source and destination
      * may overlap.
      */
    pub unsafe fn memcpy<T>(dst: &[mut T], src: &[const T], count: uint) {
        do as_mut_buf(dst) |p_dst, _len_dst| {
            do as_const_buf(src) |p_src, _len_src| {
                ptr::memcpy(p_dst, p_src, count)
            }
        }
    }

    /**
      * Copies data from one vector to another.
      *
      * Copies `count` bytes from `src` to `dst`. The source and destination
      * may overlap.
      */
    pub unsafe fn memmove<T>(dst: &[mut T], src: &[const T], count: uint) {
        do as_mut_buf(dst) |p_dst, _len_dst| {
            do as_const_buf(src) |p_src, _len_src| {
                ptr::memmove(p_dst, p_src, count)
            }
        }
    }
}

/// Operations on `[u8]`
pub mod bytes {

    /// Bytewise string comparison
    pub pure fn cmp(a: &~[u8], b: &~[u8]) -> int {
        let a_len = len(*a);
        let b_len = len(*b);
        let n = uint::min(a_len, b_len) as libc::size_t;
        let r = unsafe {
            libc::memcmp(raw::to_ptr(*a) as *libc::c_void,
                         raw::to_ptr(*b) as *libc::c_void, n) as int
        };

        if r != 0 { r } else {
            if a_len == b_len {
                0
            } else if a_len < b_len {
                -1
            } else {
                1
            }
        }
    }

    /// Bytewise less than or equal
    pub pure fn lt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) < 0 }

    /// Bytewise less than or equal
    pub pure fn le(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) <= 0 }

    /// Bytewise equality
    pub pure fn eq(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) == 0 }

    /// Bytewise inequality
    pub pure fn ne(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) != 0 }

    /// Bytewise greater than or equal
    pub pure fn ge(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) >= 0 }

    /// Bytewise greater than
    pub pure fn gt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) > 0 }

    /**
      * Copies data from one vector to another.
      *
      * Copies `count` bytes from `src` to `dst`. The source and destination
      * may not overlap.
      */
    pub fn memcpy(dst: &[mut u8], src: &[const u8], count: uint) {
        assert dst.len() >= count;
        assert src.len() >= count;

        unsafe { vec::raw::memcpy(dst, src, count) }
    }

    /**
      * Copies data from one vector to another.
      *
      * Copies `count` bytes from `src` to `dst`. The source and destination
      * may overlap.
      */
    pub fn memmove(dst: &[mut u8], src: &[const u8], count: uint) {
        assert dst.len() >= count;
        assert src.len() >= count;

        unsafe { vec::raw::memmove(dst, src, count) }
    }
}

// ___________________________________________________________________________
// ITERATION TRAIT METHODS
//
// This cannot be used with iter-trait.rs because of the region pointer
// required in the slice.

impl<A> &[A]: iter::BaseIter<A> {
    pub pure fn each(blk: fn(v: &A) -> bool) {
        // FIXME(#2263)---should be able to call each(self, blk)
        for each(self) |e| {
            if (!blk(e)) {
                return;
            }
        }
    }
    pure fn size_hint() -> Option<uint> { Some(len(self)) }
}

impl<A> &[A]: iter::ExtendedIter<A> {
    pub pure fn eachi(blk: fn(uint, v: &A) -> bool) {
        iter::eachi(&self, blk)
    }
    pub pure fn all(blk: fn(&A) -> bool) -> bool { iter::all(&self, blk) }
    pub pure fn any(blk: fn(&A) -> bool) -> bool { iter::any(&self, blk) }
    pub pure fn foldl<B>(b0: B, blk: fn(&B, &A) -> B) -> B {
        iter::foldl(&self, move b0, blk)
    }
    pub pure fn position(f: fn(&A) -> bool) -> Option<uint> {
        iter::position(&self, f)
    }
}

impl<A: Eq> &[A]: iter::EqIter<A> {
    pub pure fn contains(x: &A) -> bool { iter::contains(&self, x) }
    pub pure fn count(x: &A) -> uint { iter::count(&self, x) }
}

impl<A: Copy> &[A]: iter::CopyableIter<A> {
    pure fn filter_to_vec(pred: fn(a: A) -> bool) -> ~[A] {
        iter::filter_to_vec(&self, pred)
    }
    pure fn map_to_vec<B>(op: fn(v: A) -> B) -> ~[B] {
        iter::map_to_vec(&self, op)
    }
    pure fn to_vec() -> ~[A] { iter::to_vec(&self) }

    pure fn flat_map_to_vec<B:Copy,IB:BaseIter<B>>(op: fn(A) -> IB) -> ~[B] {
        iter::flat_map_to_vec(&self, op)
    }

    pub pure fn find(p: fn(a: A) -> bool) -> Option<A> {
        iter::find(&self, p)
    }
}

impl<A: Copy Ord> &[A]: iter::CopyableOrderedIter<A> {
    pure fn min() -> A { iter::min(&self) }
    pure fn max() -> A { iter::max(&self) }
}
// ___________________________________________________________________________

#[cfg(test)]
mod tests {

    fn square(n: uint) -> uint { return n * n; }

    fn square_ref(n: &uint) -> uint { return square(*n); }

    pure fn is_three(n: &uint) -> bool { return *n == 3u; }

    pure fn is_odd(n: &uint) -> bool { return *n % 2u == 1u; }

    pure fn is_equal(x: &uint, y:&uint) -> bool { return *x == *y; }

    fn square_if_odd(n: &uint) -> Option<uint> {
        return if *n % 2u == 1u { Some(*n * *n) } else { None };
    }

    fn add(x: uint, y: &uint) -> uint { return x + *y; }

    #[test]
    fn test_unsafe_ptrs() {
        unsafe {
            // Test on-stack copy-from-buf.
            let a = ~[1, 2, 3];
            let mut ptr = raw::to_ptr(a);
            let b = from_buf(ptr, 3u);
            assert (len(b) == 3u);
            assert (b[0] == 1);
            assert (b[1] == 2);
            assert (b[2] == 3);

            // Test on-heap copy-from-buf.
            let c = ~[1, 2, 3, 4, 5];
            ptr = raw::to_ptr(c);
            let d = from_buf(ptr, 5u);
            assert (len(d) == 5u);
            assert (d[0] == 1);
            assert (d[1] == 2);
            assert (d[2] == 3);
            assert (d[3] == 4);
            assert (d[4] == 5);
        }
    }

    #[test]
    fn test_from_fn() {
        // Test on-stack from_fn.
        let mut v = from_fn(3u, square);
        assert (len(v) == 3u);
        assert (v[0] == 0u);
        assert (v[1] == 1u);
        assert (v[2] == 4u);

        // Test on-heap from_fn.
        v = from_fn(5u, square);
        assert (len(v) == 5u);
        assert (v[0] == 0u);
        assert (v[1] == 1u);
        assert (v[2] == 4u);
        assert (v[3] == 9u);
        assert (v[4] == 16u);
    }

    #[test]
    fn test_from_elem() {
        // Test on-stack from_elem.
        let mut v = from_elem(2u, 10u);
        assert (len(v) == 2u);
        assert (v[0] == 10u);
        assert (v[1] == 10u);

        // Test on-heap from_elem.
        v = from_elem(6u, 20u);
        assert (v[0] == 20u);
        assert (v[1] == 20u);
        assert (v[2] == 20u);
        assert (v[3] == 20u);
        assert (v[4] == 20u);
        assert (v[5] == 20u);
    }

    #[test]
    fn test_is_empty() {
        assert (is_empty::<int>(~[]));
        assert (!is_empty(~[0]));
    }

    #[test]
    fn test_is_not_empty() {
        assert (is_not_empty(~[0]));
        assert (!is_not_empty::<int>(~[]));
    }

    #[test]
    fn test_head() {
        let a = ~[11, 12];
        assert (head(a) == 11);
    }

    #[test]
    fn test_tail() {
        let mut a = ~[11];
        assert (tail(a) == ~[]);

        a = ~[11, 12];
        assert (tail(a) == ~[12]);
    }

    #[test]
    fn test_last() {
        let mut n = last_opt(~[]);
        assert (n.is_none());
        n = last_opt(~[1, 2, 3]);
        assert (n == Some(3));
        n = last_opt(~[1, 2, 3, 4, 5]);
        assert (n == Some(5));
    }

    #[test]
    fn test_slice() {
        // Test on-stack -> on-stack slice.
        let mut v = slice(~[1, 2, 3], 1u, 3u);
        assert (len(v) == 2u);
        assert (v[0] == 2);
        assert (v[1] == 3);

        // Test on-heap -> on-stack slice.
        v = slice(~[1, 2, 3, 4, 5], 0u, 3u);
        assert (len(v) == 3u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (v[2] == 3);

        // Test on-heap -> on-heap slice.
        v = slice(~[1, 2, 3, 4, 5, 6], 1u, 6u);
        assert (len(v) == 5u);
        assert (v[0] == 2);
        assert (v[1] == 3);
        assert (v[2] == 4);
        assert (v[3] == 5);
        assert (v[4] == 6);
    }

    #[test]
    fn test_pop() {
        // Test on-stack pop.
        let mut v = ~[1, 2, 3];
        let mut e = v.pop();
        assert (len(v) == 2u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (e == 3);

        // Test on-heap pop.
        v = ~[1, 2, 3, 4, 5];
        e = v.pop();
        assert (len(v) == 4u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (v[2] == 3);
        assert (v[3] == 4);
        assert (e == 5);
    }

    #[test]
    fn test_swap_remove() {
        let mut v = ~[1, 2, 3, 4, 5];
        let mut e = v.swap_remove(0);
        assert (len(v) == 4);
        assert e == 1;
        assert (v[0] == 5);
        e = v.swap_remove(3);
        assert (len(v) == 3);
        assert e == 4;
        assert (v[0] == 5);
        assert (v[1] == 2);
        assert (v[2] == 3);
    }

    #[test]
    fn test_swap_remove_noncopyable() {
        // Tests that we don't accidentally run destructors twice.
        let mut v = ~[::private::exclusive(()), ::private::exclusive(()),
                      ::private::exclusive(())];
        let mut _e = v.swap_remove(0);
        assert (len(v) == 2);
        _e = v.swap_remove(1);
        assert (len(v) == 1);
        _e = v.swap_remove(0);
        assert (len(v) == 0);
    }

    #[test]
    fn test_push() {
        // Test on-stack push().
        let mut v = ~[];
        v.push(1);
        assert (len(v) == 1u);
        assert (v[0] == 1);

        // Test on-heap push().
        v.push(2);
        assert (len(v) == 2u);
        assert (v[0] == 1);
        assert (v[1] == 2);
    }

    #[test]
    fn test_grow() {
        // Test on-stack grow().
        let mut v = ~[];
        v.grow(2u, &1);
        assert (len(v) == 2u);
        assert (v[0] == 1);
        assert (v[1] == 1);

        // Test on-heap grow().
        v.grow(3u, &2);
        assert (len(v) == 5u);
        assert (v[0] == 1);
        assert (v[1] == 1);
        assert (v[2] == 2);
        assert (v[3] == 2);
        assert (v[4] == 2);
    }

    #[test]
    fn test_grow_fn() {
        let mut v = ~[];
        v.grow_fn(3u, square);
        assert (len(v) == 3u);
        assert (v[0] == 0u);
        assert (v[1] == 1u);
        assert (v[2] == 4u);
    }

    #[test]
    fn test_grow_set() {
        let mut v = ~[1, 2, 3];
        v.grow_set(4u, &4, 5);
        assert (len(v) == 5u);
        assert (v[0] == 1);
        assert (v[1] == 2);
        assert (v[2] == 3);
        assert (v[3] == 4);
        assert (v[4] == 5);
    }

    #[test]
    fn test_truncate() {
        let mut v = ~[@6,@5,@4];
        v.truncate(1);
        assert(v.len() == 1);
        assert(*(v[0]) == 6);
        // If the unsafe block didn't drop things properly, we blow up here.
    }

    #[test]
    fn test_dedup() {
        fn case(a: ~[uint], b: ~[uint]) {
            let mut v = a;
            v.dedup();
            assert(v == b);
        }
        case(~[], ~[]);
        case(~[1], ~[1]);
        case(~[1,1], ~[1]);
        case(~[1,2,3], ~[1,2,3]);
        case(~[1,1,2,3], ~[1,2,3]);
        case(~[1,2,2,3], ~[1,2,3]);
        case(~[1,2,3,3], ~[1,2,3]);
        case(~[1,1,2,2,2,3,3], ~[1,2,3]);
    }

    #[test]
    fn test_dedup_unique() {
        let mut v0 = ~[~1, ~1, ~2, ~3];
        v0.dedup();
        let mut v1 = ~[~1, ~2, ~2, ~3];
        v1.dedup();
        let mut v2 = ~[~1, ~2, ~3, ~3];
        v2.dedup();
        /*
         * If the ~pointers were leaked or otherwise misused, valgrind and/or
         * rustrt should raise errors.
         */
    }

    #[test]
    fn test_dedup_shared() {
        let mut v0 = ~[@1, @1, @2, @3];
        v0.dedup();
        let mut v1 = ~[@1, @2, @2, @3];
        v1.dedup();
        let mut v2 = ~[@1, @2, @3, @3];
        v2.dedup();
        /*
         * If the @pointers were leaked or otherwise misused, valgrind and/or
         * rustrt should raise errors.
         */
    }

    #[test]
    fn test_map() {
        // Test on-stack map.
        let mut v = ~[1u, 2u, 3u];
        let mut w = map(v, square_ref);
        assert (len(w) == 3u);
        assert (w[0] == 1u);
        assert (w[1] == 4u);
        assert (w[2] == 9u);

        // Test on-heap map.
        v = ~[1u, 2u, 3u, 4u, 5u];
        w = map(v, square_ref);
        assert (len(w) == 5u);
        assert (w[0] == 1u);
        assert (w[1] == 4u);
        assert (w[2] == 9u);
        assert (w[3] == 16u);
        assert (w[4] == 25u);
    }

    #[test]
    fn test_map2() {
        fn times(x: &int, y: &int) -> int { return *x * *y; }
        let f = times;
        let v0 = ~[1, 2, 3, 4, 5];
        let v1 = ~[5, 4, 3, 2, 1];
        let u = map2::<int, int, int>(v0, v1, f);
        let mut i = 0;
        while i < 5 { assert (v0[i] * v1[i] == u[i]); i += 1; }
    }

    #[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);
        assert (len(w) == 2u);
        assert (w[0] == 1u);
        assert (w[1] == 9u);

        // Test on-heap filter-map.
        v = ~[1u, 2u, 3u, 4u, 5u];
        w = filter_map(v, square_if_odd);
        assert (len(w) == 3u);
        assert (w[0] == 1u);
        assert (w[1] == 9u);
        assert (w[2] == 25u);

        fn halve(i: &int) -> Option<int> {
            if *i % 2 == 0 {
                return option::Some::<int>(*i / 2);
            } else { return option::None::<int>; }
        }
        fn halve_for_sure(i: &int) -> int { return *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_map(all_even, halve) == map(all_even, halve_for_sure));
        assert (filter_map(all_odd1, halve) == ~[]);
        assert (filter_map(all_odd2, halve) == ~[]);
        assert (filter_map(mix, halve) == mix_dest);
    }

    #[test]
    fn test_filter() {
        assert filter(~[1u, 2u, 3u], is_odd) == ~[1u, 3u];
        assert filter(~[1u, 2u, 4u, 8u, 16u], is_three) == ~[];
    }

    #[test]
    fn test_foldl() {
        // Test on-stack fold.
        let mut v = ~[1u, 2u, 3u];
        let mut sum = foldl(0u, v, add);
        assert (sum == 6u);

        // Test on-heap fold.
        v = ~[1u, 2u, 3u, 4u, 5u];
        sum = foldl(0u, v, add);
        assert (sum == 15u);
    }

    #[test]
    fn test_foldl2() {
        fn sub(a: int, b: &int) -> int {
            a - *b
        }
        let mut v = ~[1, 2, 3, 4];
        let sum = foldl(0, v, sub);
        assert sum == -10;
    }

    #[test]
    fn test_foldr() {
        fn sub(a: &int, b: int) -> int {
            *a - b
        }
        let mut v = ~[1, 2, 3, 4];
        let sum = foldr(v, 0, sub);
        assert sum == -2;
    }

    #[test]
    fn test_each_empty() {
        for each::<int>(~[]) |_v| {
            fail; // should never be executed
        }
    }

    #[test]
    fn test_iter_nonempty() {
        let mut i = 0;
        for each(~[1, 2, 3]) |v| {
            i += *v;
        }
        assert i == 6;
    }

    #[test]
    fn test_iteri() {
        let mut i = 0;
        for eachi(~[1, 2, 3]) |j, v| {
            if i == 0 { assert *v == 1; }
            assert j + 1u == *v as uint;
            i += *v;
        }
        assert i == 6;
    }

    #[test]
    fn test_reach_empty() {
        for rev_each::<int>(~[]) |_v| {
            fail; // should never execute
        }
    }

    #[test]
    fn test_reach_nonempty() {
        let mut i = 0;
        for rev_each(~[1, 2, 3]) |v| {
            if i == 0 { assert *v == 3; }
            i += *v
        }
        assert i == 6;
    }

    #[test]
    fn test_reachi() {
        let mut i = 0;
        for rev_eachi(~[0, 1, 2]) |j, v| {
            if i == 0 { assert *v == 2; }
            assert j == *v as uint;
            i += *v;
        }
        assert i == 3;
    }

    #[test]
    fn test_each_permutation() {
        let mut results: ~[~[int]];

        results = ~[];
        for each_permutation(~[]) |v| { results.push(from_slice(v)); }
        assert results == ~[~[]];

        results = ~[];
        for each_permutation(~[7]) |v| { results.push(from_slice(v)); }
        assert results == ~[~[7]];

        results = ~[];
        for each_permutation(~[1,1]) |v| { results.push(from_slice(v)); }
        assert results == ~[~[1,1],~[1,1]];

        results = ~[];
        for each_permutation(~[5,2,0]) |v| { results.push(from_slice(v)); }
        assert results ==
            ~[~[5,2,0],~[5,0,2],~[2,5,0],~[2,0,5],~[0,5,2],~[0,2,5]];
    }

    #[test]
    fn test_any_and_all() {
        assert (any(~[1u, 2u, 3u], is_three));
        assert (!any(~[0u, 1u, 2u], is_three));
        assert (any(~[1u, 2u, 3u, 4u, 5u], is_three));
        assert (!any(~[1u, 2u, 4u, 5u, 6u], is_three));

        assert (all(~[3u, 3u, 3u], is_three));
        assert (!all(~[3u, 3u, 2u], is_three));
        assert (all(~[3u, 3u, 3u, 3u, 3u], is_three));
        assert (!all(~[3u, 3u, 0u, 1u, 2u], is_three));
    }

    #[test]
    fn test_any2_and_all2() {

        assert (any2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal));
        assert (any2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal));
        assert (!any2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal));
        assert (any2(~[2u, 4u, 6u], ~[2u, 4u], is_equal));

        assert (all2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal));
        assert (!all2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal));
        assert (!all2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal));
        assert (!all2(~[2u, 4u, 6u], ~[2u, 4u], is_equal));
    }

    #[test]
    fn test_zip_unzip() {
        let v1 = ~[1, 2, 3];
        let v2 = ~[4, 5, 6];

        let z1 = zip(v1, v2);

        assert ((1, 4) == z1[0]);
        assert ((2, 5) == z1[1]);
        assert ((3, 6) == z1[2]);

        let (left, right) = unzip(z1);

        assert ((1, 4) == (left[0], right[0]));
        assert ((2, 5) == (left[1], right[1]));
        assert ((3, 6) == (left[2], right[2]));
    }

    #[test]
    fn test_position_elem() {
        assert position_elem(~[], &1).is_none();

        let v1 = ~[1, 2, 3, 3, 2, 5];
        assert position_elem(v1, &1) == Some(0u);
        assert position_elem(v1, &2) == Some(1u);
        assert position_elem(v1, &5) == Some(5u);
        assert position_elem(v1, &4).is_none();
    }

    #[test]
    fn test_position() {
        fn less_than_three(i: &int) -> bool { return *i < 3; }
        fn is_eighteen(i: &int) -> bool { return *i == 18; }

        assert position(~[], less_than_three).is_none();

        let v1 = ~[5, 4, 3, 2, 1];
        assert position(v1, less_than_three) == Some(3u);
        assert position(v1, is_eighteen).is_none();
    }

    #[test]
    fn test_position_between() {
        assert position_between(~[], 0u, 0u, f).is_none();

        fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];

        assert position_between(v, 0u, 0u, f).is_none();
        assert position_between(v, 0u, 1u, f).is_none();
        assert position_between(v, 0u, 2u, f) == Some(1u);
        assert position_between(v, 0u, 3u, f) == Some(1u);
        assert position_between(v, 0u, 4u, f) == Some(1u);

        assert position_between(v, 1u, 1u, f).is_none();
        assert position_between(v, 1u, 2u, f) == Some(1u);
        assert position_between(v, 1u, 3u, f) == Some(1u);
        assert position_between(v, 1u, 4u, f) == Some(1u);

        assert position_between(v, 2u, 2u, f).is_none();
        assert position_between(v, 2u, 3u, f).is_none();
        assert position_between(v, 2u, 4u, f) == Some(3u);

        assert position_between(v, 3u, 3u, f).is_none();
        assert position_between(v, 3u, 4u, f) == Some(3u);

        assert position_between(v, 4u, 4u, f).is_none();
    }

    #[test]
    fn test_find() {
        assert find(~[], f).is_none();

        fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
        fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];

        assert find(v, f) == Some((1, 'b'));
        assert find(v, g).is_none();
    }

    #[test]
    fn test_find_between() {
        assert find_between(~[], 0u, 0u, f).is_none();

        fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];

        assert find_between(v, 0u, 0u, f).is_none();
        assert find_between(v, 0u, 1u, f).is_none();
        assert find_between(v, 0u, 2u, f) == Some((1, 'b'));
        assert find_between(v, 0u, 3u, f) == Some((1, 'b'));
        assert find_between(v, 0u, 4u, f) == Some((1, 'b'));

        assert find_between(v, 1u, 1u, f).is_none();
        assert find_between(v, 1u, 2u, f) == Some((1, 'b'));
        assert find_between(v, 1u, 3u, f) == Some((1, 'b'));
        assert find_between(v, 1u, 4u, f) == Some((1, 'b'));

        assert find_between(v, 2u, 2u, f).is_none();
        assert find_between(v, 2u, 3u, f).is_none();
        assert find_between(v, 2u, 4u, f) == Some((3, 'b'));

        assert find_between(v, 3u, 3u, f).is_none();
        assert find_between(v, 3u, 4u, f) == Some((3, 'b'));

        assert find_between(v, 4u, 4u, f).is_none();
    }

    #[test]
    fn test_rposition() {
        assert find(~[], f).is_none();

        fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
        fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];

        assert position(v, f) == Some(1u);
        assert position(v, g).is_none();
    }

    #[test]
    fn test_rposition_between() {
        assert rposition_between(~[], 0u, 0u, f).is_none();

        fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];

        assert rposition_between(v, 0u, 0u, f).is_none();
        assert rposition_between(v, 0u, 1u, f).is_none();
        assert rposition_between(v, 0u, 2u, f) == Some(1u);
        assert rposition_between(v, 0u, 3u, f) == Some(1u);
        assert rposition_between(v, 0u, 4u, f) == Some(3u);

        assert rposition_between(v, 1u, 1u, f).is_none();
        assert rposition_between(v, 1u, 2u, f) == Some(1u);
        assert rposition_between(v, 1u, 3u, f) == Some(1u);
        assert rposition_between(v, 1u, 4u, f) == Some(3u);

        assert rposition_between(v, 2u, 2u, f).is_none();
        assert rposition_between(v, 2u, 3u, f).is_none();
        assert rposition_between(v, 2u, 4u, f) == Some(3u);

        assert rposition_between(v, 3u, 3u, f).is_none();
        assert rposition_between(v, 3u, 4u, f) == Some(3u);

        assert rposition_between(v, 4u, 4u, f).is_none();
    }

    #[test]
    fn test_rfind() {
        assert rfind(~[], f).is_none();

        fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
        fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];

        assert rfind(v, f) == Some((3, 'b'));
        assert rfind(v, g).is_none();
    }

    #[test]
    fn test_rfind_between() {
        assert rfind_between(~[], 0u, 0u, f).is_none();

        fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
        let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];

        assert rfind_between(v, 0u, 0u, f).is_none();
        assert rfind_between(v, 0u, 1u, f).is_none();
        assert rfind_between(v, 0u, 2u, f) == Some((1, 'b'));
        assert rfind_between(v, 0u, 3u, f) == Some((1, 'b'));
        assert rfind_between(v, 0u, 4u, f) == Some((3, 'b'));

        assert rfind_between(v, 1u, 1u, f).is_none();
        assert rfind_between(v, 1u, 2u, f) == Some((1, 'b'));
        assert rfind_between(v, 1u, 3u, f) == Some((1, 'b'));
        assert rfind_between(v, 1u, 4u, f) == Some((3, 'b'));

        assert rfind_between(v, 2u, 2u, f).is_none();
        assert rfind_between(v, 2u, 3u, f).is_none();
        assert rfind_between(v, 2u, 4u, f) == Some((3, 'b'));

        assert rfind_between(v, 3u, 3u, f).is_none();
        assert rfind_between(v, 3u, 4u, f) == Some((3, 'b'));

        assert rfind_between(v, 4u, 4u, f).is_none();
    }

    #[test]
    fn reverse_and_reversed() {
        let v: ~[mut int] = ~[mut 10, 20];
        assert (v[0] == 10);
        assert (v[1] == 20);
        reverse(v);
        assert (v[0] == 20);
        assert (v[1] == 10);
        let v2 = reversed::<int>(~[10, 20]);
        assert (v2[0] == 20);
        assert (v2[1] == 10);
        v[0] = 30;
        assert (v2[0] == 20);
        // Make sure they work with 0-length vectors too.

        let v4 = reversed::<int>(~[]);
        assert (v4 == ~[]);
        let v3: ~[mut int] = ~[mut];
        reverse::<int>(v3);
    }

    #[test]
    fn reversed_mut() {
        let v2 = reversed::<int>(~[mut 10, 20]);
        assert (v2[0] == 20);
        assert (v2[1] == 10);
    }

    #[test]
    fn test_init() {
        let v = init(~[1, 2, 3]);
        assert v == ~[1, 2];
    }

    #[test]
    fn test_split() {
        fn f(x: &int) -> bool { *x == 3 }

        assert split(~[], f) == ~[];
        assert split(~[1, 2], f) == ~[~[1, 2]];
        assert split(~[3, 1, 2], f) == ~[~[], ~[1, 2]];
        assert split(~[1, 2, 3], f) == ~[~[1, 2], ~[]];
        assert split(~[1, 2, 3, 4, 3, 5], f) == ~[~[1, 2], ~[4], ~[5]];
    }

    #[test]
    fn test_splitn() {
        fn f(x: &int) -> bool { *x == 3 }

        assert splitn(~[], 1u, f) == ~[];
        assert splitn(~[1, 2], 1u, f) == ~[~[1, 2]];
        assert splitn(~[3, 1, 2], 1u, f) == ~[~[], ~[1, 2]];
        assert 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 rsplit(~[], f) == ~[];
        assert rsplit(~[1, 2], f) == ~[~[1, 2]];
        assert 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 rsplitn(~[], 1u, f) == ~[];
        assert rsplitn(~[1, 2], 1u, f) == ~[~[1, 2]];
        assert rsplitn(~[1, 2, 3], 1u, f) == ~[~[1, 2], ~[]];
        assert rsplitn(~[1, 2, 3, 4, 3, 5], 1u, f) ==
                       ~[~[1, 2, 3, 4], ~[5]];
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_init_empty() {
        init::<int>(~[]);
    }

    #[test]
    fn test_concat() {
        assert concat(~[~[1], ~[2,3]]) == ~[1, 2, 3];
    }

    #[test]
    fn test_connect() {
        assert connect(~[], &0) == ~[];
        assert connect(~[~[1], ~[2, 3]], &0) == ~[1, 0, 2, 3];
        assert connect(~[~[1], ~[2], ~[3]], &0) == ~[1, 0, 2, 0, 3];
    }

    #[test]
    fn test_windowed () {
        assert ~[~[1u,2u,3u],~[2u,3u,4u],~[3u,4u,5u],~[4u,5u,6u]]
            == windowed (3u, ~[1u,2u,3u,4u,5u,6u]);

        assert ~[~[1u,2u,3u,4u],~[2u,3u,4u,5u],~[3u,4u,5u,6u]]
            == windowed (4u, ~[1u,2u,3u,4u,5u,6u]);

        assert ~[] == windowed (7u, ~[1u,2u,3u,4u,5u,6u]);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_windowed_() {
        let _x = windowed (0u, ~[1u,2u,3u,4u,5u,6u]);
    }

    #[test]
    fn to_mut_no_copy() {
        unsafe {
            let x = ~[1, 2, 3];
            let addr = raw::to_ptr(x);
            let x_mut = to_mut(x);
            let addr_mut = raw::to_ptr(x_mut);
            assert addr == addr_mut;
        }
    }

    #[test]
    fn from_mut_no_copy() {
        unsafe {
            let x = ~[mut 1, 2, 3];
            let addr = raw::to_ptr(x);
            let x_imm = from_mut(x);
            let addr_imm = raw::to_ptr(x_imm);
            assert addr == addr_imm;
        }
    }

    #[test]
    fn test_unshift() {
        let mut x = ~[1, 2, 3];
        x.unshift(0);
        assert x == ~[0, 1, 2, 3];
    }

    #[test]
    fn test_capacity() {
        let mut v = ~[0u64];
        reserve(&mut v, 10u);
        assert capacity(&v) == 10u;
        let mut v = ~[0u32];
        reserve(&mut v, 10u);
        assert capacity(&v) == 10u;
    }

    #[test]
    fn test_view() {
        let v = ~[1, 2, 3, 4, 5];
        let v = v.view(1u, 3u);
        assert(len(v) == 2u);
        assert(v[0] == 2);
        assert(v[1] == 3);
    }


    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_from_fn_fail() {
        do from_fn(100) |v| {
            if v == 50 { fail }
            (~0, @0)
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_build_fail() {
        do build |push| {
            push((~0, @0));
            push((~0, @0));
            push((~0, @0));
            push((~0, @0));
            fail;
        };
    }

    #[test]
    #[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]
    fn test_consume_mut_fail() {
        let v = ~[mut (~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do consume_mut(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| {
            if i == 50 {
                fail
            }
            (~0, @0)
        }
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_map_fail() {
        let v = [mut (~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do map(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            ~[(~0, @0)]
        };
    }

    #[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_mapi_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do mapi(v) |_i, _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;
        do map(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            ~[(~0, @0)]
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    #[allow(non_implicitly_copyable_typarams)]
    fn test_map2_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do map2(v, v) |_elt1, _elt2| {
            if i == 2 {
                fail
            }
            i += 0;
            ~[(~0, @0)]
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    #[allow(non_implicitly_copyable_typarams)]
    fn test_filter_map_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do filter_map(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 filter(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            true
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    #[allow(non_implicitly_copyable_typarams)]
    fn test_foldl_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do foldl((~0, @0), v) |_a, _b| {
            if i == 2 {
                fail
            }
            i += 0;
            (~0, @0)
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    #[allow(non_implicitly_copyable_typarams)]
    fn test_foldr_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do foldr(v, (~0, @0)) |_a, _b| {
            if i == 2 {
                fail
            }
            i += 0;
            (~0, @0)
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_any_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do any(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            false
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_any2_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do any(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            false
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_all_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do all(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            true
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_alli_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do alli(v) |_i, _elt| {
            if i == 2 {
                fail
            }
            i += 0;
            true
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_all2_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do all2(v, v) |_elt1, _elt2| {
            if i == 2 {
                fail
            }
            i += 0;
            true
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    #[allow(non_implicitly_copyable_typarams)]
    fn test_find_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do find(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            false
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_position_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do position(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            false
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_rposition_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do rposition(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            false
        };
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_each_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do each(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
            false
        }
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_eachi_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        do eachi(v) |_i, _elt| {
            if i == 2 {
                fail
            }
            i += 0;
            false
        }
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    #[allow(non_implicitly_copyable_typarams)]
    fn test_permute_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        let mut i = 0;
        for each_permutation(v) |_elt| {
            if i == 2 {
                fail
            }
            i += 0;
        }
    }

    #[test]
    #[ignore(windows)]
    #[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| {
            fail
        }
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_as_const_buf_fail() {
        let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        do as_const_buf(v) |_buf, _i| {
            fail
        }
    }

    #[test]
    #[ignore(windows)]
    #[should_fail]
    fn test_as_mut_buf_fail() {
        let v = [mut (~0, @0), (~0, @0), (~0, @0), (~0, @0)];
        do as_mut_buf(v) |_buf, _i| {
            fail
        }
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
