2013-02-20 17:02:21 -06:00
|
|
|
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 18:48:01 -06:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
//! Vectors
|
2012-03-15 20:58:14 -05:00
|
|
|
|
2012-09-28 00:20:47 -05:00
|
|
|
#[warn(non_camel_case_types)];
|
|
|
|
|
2013-04-17 16:19:25 -05:00
|
|
|
use cast::transmute;
|
2012-12-23 16:41:37 -06:00
|
|
|
use cast;
|
2013-04-17 16:19:25 -05:00
|
|
|
use container::{Container, Mutable};
|
2013-06-18 01:52:14 -05:00
|
|
|
use cmp;
|
2013-03-26 15:38:07 -05:00
|
|
|
use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
|
2013-03-15 17:26:59 -05:00
|
|
|
use clone::Clone;
|
2013-06-21 06:57:22 -05:00
|
|
|
use iterator::{FromIterator, Iterator, IteratorUtil};
|
2013-06-06 15:34:50 -05:00
|
|
|
use iter::FromIter;
|
2013-01-08 21:37:25 -06:00
|
|
|
use kinds::Copy;
|
2012-12-23 16:41:37 -06:00
|
|
|
use libc;
|
2013-06-14 20:27:52 -05:00
|
|
|
use num::Zero;
|
2013-06-28 22:44:55 -05:00
|
|
|
use ops::Add;
|
2013-01-08 21:37:25 -06:00
|
|
|
use option::{None, Option, Some};
|
2013-04-22 16:27:30 -05:00
|
|
|
use ptr::to_unsafe_ptr;
|
2012-12-23 16:41:37 -06:00
|
|
|
use ptr;
|
2013-06-03 12:50:29 -05:00
|
|
|
use ptr::RawPtr;
|
2012-12-23 16:41:37 -06:00
|
|
|
use sys;
|
2013-06-21 05:12:01 -05:00
|
|
|
use sys::size_of;
|
2012-12-23 16:41:37 -06:00
|
|
|
use uint;
|
2013-04-22 16:27:30 -05:00
|
|
|
use unstable::intrinsics;
|
2013-06-20 04:39:49 -05:00
|
|
|
#[cfg(stage0)]
|
|
|
|
use intrinsic::{get_tydesc};
|
|
|
|
#[cfg(not(stage0))]
|
2013-06-29 21:40:40 -05:00
|
|
|
use unstable::intrinsics::{get_tydesc, contains_managed};
|
2012-12-23 16:41:37 -06:00
|
|
|
use vec;
|
2013-05-05 23:42:54 -05:00
|
|
|
use util;
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))] use cmp::Equiv;
|
2013-03-26 15:38:07 -05:00
|
|
|
|
2013-06-28 22:44:55 -05:00
|
|
|
#[doc(hidden)]
|
2013-03-05 13:57:50 -06:00
|
|
|
pub mod rustrt {
|
|
|
|
use libc;
|
|
|
|
use vec::raw;
|
2013-06-20 04:39:49 -05:00
|
|
|
#[cfg(stage0)]
|
|
|
|
use intrinsic::{TyDesc};
|
|
|
|
#[cfg(not(stage0))]
|
|
|
|
use unstable::intrinsics::{TyDesc};
|
2013-03-05 13:57:50 -06:00
|
|
|
|
|
|
|
#[abi = "cdecl"]
|
|
|
|
pub extern {
|
|
|
|
// These names are terrible. reserve_shared applies
|
|
|
|
// to ~[] and reserve_shared_actual applies to @[].
|
2013-03-29 18:55:04 -05:00
|
|
|
#[fast_ffi]
|
2013-06-20 04:39:49 -05:00
|
|
|
unsafe fn vec_reserve_shared(t: *TyDesc,
|
2013-05-07 16:20:56 -05:00
|
|
|
v: **raw::VecRepr,
|
|
|
|
n: libc::size_t);
|
2013-03-29 18:55:04 -05:00
|
|
|
#[fast_ffi]
|
2013-06-20 04:39:49 -05:00
|
|
|
unsafe fn vec_reserve_shared_actual(t: *TyDesc,
|
2013-05-07 16:20:56 -05:00
|
|
|
v: **raw::VecRepr,
|
|
|
|
n: libc::size_t);
|
2013-03-05 13:57:50 -06:00
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Returns true if two vectors have the same length
|
2013-06-23 22:44:11 -05:00
|
|
|
pub fn same_length<T, U>(xs: &[T], ys: &[U]) -> bool {
|
2013-03-09 15:41:43 -06:00
|
|
|
xs.len() == ys.len()
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
2013-04-30 04:39:16 -05:00
|
|
|
* Creates and initializes an owned vector.
|
2012-07-04 16:53:12 -05:00
|
|
|
*
|
2013-04-30 04:39:16 -05:00
|
|
|
* Creates an owned vector of size `n_elts` and initializes the elements
|
2012-07-04 16:53:12 -05:00
|
|
|
* to the value returned by the function `op`.
|
|
|
|
*/
|
2013-06-23 16:57:39 -05:00
|
|
|
pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> ~[T] {
|
2012-10-05 16:58:42 -05:00
|
|
|
unsafe {
|
|
|
|
let mut v = with_capacity(n_elts);
|
|
|
|
do as_mut_buf(v) |p, _len| {
|
|
|
|
let mut i: uint = 0u;
|
|
|
|
while i < n_elts {
|
2013-05-31 23:55:19 -05:00
|
|
|
intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
|
2012-10-05 16:58:42 -05:00
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
raw::set_len(&mut v, n_elts);
|
2013-03-09 15:41:43 -06:00
|
|
|
v
|
2012-10-05 16:58:42 -05:00
|
|
|
}
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
2013-04-30 04:39:16 -05:00
|
|
|
* Creates and initializes an owned vector.
|
2012-07-04 16:53:12 -05:00
|
|
|
*
|
2013-04-30 04:39:16 -05:00
|
|
|
* Creates an owned vector of size `n_elts` and initializes the elements
|
2012-07-04 16:53:12 -05:00
|
|
|
* to the value `t`.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] {
|
2013-06-14 18:58:55 -05:00
|
|
|
// FIXME (#7136): manually inline from_fn for 2x plus speedup (sadly very
|
|
|
|
// important, from_elem is a bottleneck in borrowck!). Unfortunately it
|
|
|
|
// still is substantially slower than using the unsafe
|
|
|
|
// vec::with_capacity/ptr::set_memory for primitive types.
|
2013-05-31 23:55:19 -05:00
|
|
|
unsafe {
|
|
|
|
let mut v = with_capacity(n_elts);
|
|
|
|
do as_mut_buf(v) |p, _len| {
|
|
|
|
let mut i = 0u;
|
|
|
|
while i < n_elts {
|
|
|
|
intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), copy t);
|
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
raw::set_len(&mut v, n_elts);
|
|
|
|
v
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2013-06-13 21:06:47 -05:00
|
|
|
/// Creates a new unique vector with the same contents as the slice
|
|
|
|
pub fn to_owned<T:Copy>(t: &[T]) -> ~[T] {
|
2013-06-15 19:26:59 -05:00
|
|
|
from_fn(t.len(), |i| copy t[i])
|
2013-06-13 21:06:47 -05:00
|
|
|
}
|
|
|
|
|
2013-04-24 21:33:13 -05:00
|
|
|
/// Creates a new vector with a capacity of `capacity`
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn with_capacity<T>(capacity: uint) -> ~[T] {
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut vec = ~[];
|
2013-06-27 09:40:47 -05:00
|
|
|
vec.reserve(capacity);
|
2013-03-09 15:41:43 -06:00
|
|
|
vec
|
2012-09-21 20:43:30 -05:00
|
|
|
}
|
|
|
|
|
2012-07-17 18:31:19 -05:00
|
|
|
/**
|
|
|
|
* Builds a vector by calling a provided function with an argument
|
|
|
|
* function that pushes an element to the back of a vector.
|
2013-03-25 17:34:15 -05:00
|
|
|
* This version takes an initial capacity for the vector.
|
2012-07-17 18:31:19 -05:00
|
|
|
*
|
|
|
|
* # Arguments
|
|
|
|
*
|
|
|
|
* * size - An initial size of the vector to reserve
|
2013-03-25 17:34:15 -05:00
|
|
|
* * builder - A function that will construct the vector. It receives
|
2012-07-17 18:31:19 -05:00
|
|
|
* as an argument a function that will push an element
|
|
|
|
* onto the vector being constructed.
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] {
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut vec = with_capacity(size);
|
2013-04-08 15:50:34 -05:00
|
|
|
builder(|x| vec.push(x));
|
2012-12-12 17:38:50 -06:00
|
|
|
vec
|
2012-07-17 18:31:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Builds a vector by calling a provided function with an argument
|
|
|
|
* function that pushes an element to the back of a vector.
|
|
|
|
*
|
|
|
|
* # Arguments
|
|
|
|
*
|
2013-03-25 17:34:15 -05:00
|
|
|
* * builder - A function that will construct the vector. It receives
|
2012-07-17 18:31:19 -05:00
|
|
|
* as an argument a function that will push an element
|
|
|
|
* onto the vector being constructed.
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn build<A>(builder: &fn(push: &fn(v: A))) -> ~[A] {
|
2012-07-17 18:31:19 -05:00
|
|
|
build_sized(4, builder)
|
|
|
|
}
|
|
|
|
|
2012-08-23 12:22:14 -05:00
|
|
|
/**
|
|
|
|
* 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
|
2013-05-08 12:34:47 -05:00
|
|
|
* * builder - A function that will construct the vector. It receives
|
2012-08-23 12:22:14 -05:00
|
|
|
* as an argument a function that will push an element
|
|
|
|
* onto the vector being constructed.
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn build_sized_opt<A>(size: Option<uint>,
|
|
|
|
builder: &fn(push: &fn(v: A)))
|
|
|
|
-> ~[A] {
|
2013-01-04 18:01:26 -06:00
|
|
|
build_sized(size.get_or_default(4), builder)
|
2012-08-23 12:22:14 -05:00
|
|
|
}
|
|
|
|
|
2011-12-13 18:25:51 -06:00
|
|
|
// Accessors
|
|
|
|
|
2013-01-30 00:40:13 -06:00
|
|
|
/// Copies
|
2013-01-29 00:44:59 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Split the vector `v` by applying each element against the predicate `f`.
|
2013-03-07 16:38:38 -06:00
|
|
|
pub fn split<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] {
|
2013-06-08 20:38:47 -05:00
|
|
|
let ln = v.len();
|
2012-08-01 19:30:05 -05:00
|
|
|
if (ln == 0u) { return ~[] }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut start = 0u;
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut result = ~[];
|
2012-01-26 20:13:43 -06:00
|
|
|
while start < ln {
|
2013-06-21 19:08:35 -05:00
|
|
|
match position_between(v, start, ln, |t| f(t)) {
|
2012-09-26 19:33:34 -05:00
|
|
|
None => break,
|
|
|
|
Some(i) => {
|
2013-06-27 04:48:50 -05:00
|
|
|
result.push(v.slice(start, i).to_owned());
|
2012-09-26 19:33:34 -05:00
|
|
|
start = i + 1u;
|
|
|
|
}
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
}
|
2013-06-27 04:48:50 -05:00
|
|
|
result.push(v.slice(start, ln).to_owned());
|
2012-12-12 17:38:50 -06:00
|
|
|
result
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Split the vector `v` by applying each element against the predicate `f` up
|
|
|
|
* to `n` times.
|
|
|
|
*/
|
2013-03-07 16:38:38 -06:00
|
|
|
pub fn splitn<T:Copy>(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] {
|
2013-06-08 20:38:47 -05:00
|
|
|
let ln = v.len();
|
2012-08-01 19:30:05 -05:00
|
|
|
if (ln == 0u) { return ~[] }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut start = 0u;
|
|
|
|
let mut count = n;
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut result = ~[];
|
2012-01-26 20:13:43 -06:00
|
|
|
while start < ln && count > 0u {
|
2013-06-21 19:08:35 -05:00
|
|
|
match position_between(v, start, ln, |t| f(t)) {
|
2012-09-26 19:33:34 -05:00
|
|
|
None => break,
|
|
|
|
Some(i) => {
|
2013-06-27 04:48:50 -05:00
|
|
|
result.push(v.slice(start, i).to_owned());
|
2012-09-26 19:33:34 -05:00
|
|
|
// Make sure to skip the separator.
|
|
|
|
start = i + 1u;
|
|
|
|
count -= 1u;
|
|
|
|
}
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
}
|
2013-06-27 04:48:50 -05:00
|
|
|
result.push(v.slice(start, ln).to_owned());
|
2012-12-12 17:38:50 -06:00
|
|
|
result
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Reverse split the vector `v` by applying each element against the predicate
|
|
|
|
* `f`.
|
|
|
|
*/
|
2013-03-07 16:38:38 -06:00
|
|
|
pub fn rsplit<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] {
|
2013-06-08 20:38:47 -05:00
|
|
|
let ln = v.len();
|
2012-09-19 00:35:28 -05:00
|
|
|
if (ln == 0) { return ~[] }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut end = ln;
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut result = ~[];
|
2012-09-19 00:35:28 -05:00
|
|
|
while end > 0 {
|
2013-06-21 19:08:35 -05:00
|
|
|
match rposition_between(v, 0, end, |t| f(t)) {
|
2012-09-26 19:33:34 -05:00
|
|
|
None => break,
|
|
|
|
Some(i) => {
|
2013-06-27 04:48:50 -05:00
|
|
|
result.push(v.slice(i + 1, end).to_owned());
|
2012-09-26 19:33:34 -05:00
|
|
|
end = i;
|
|
|
|
}
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
}
|
2013-06-27 04:48:50 -05:00
|
|
|
result.push(v.slice(0u, end).to_owned());
|
2012-09-02 17:37:15 -05:00
|
|
|
reverse(result);
|
2013-03-09 15:41:43 -06:00
|
|
|
result
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Reverse split the vector `v` by applying each element against the predicate
|
|
|
|
* `f` up to `n times.
|
|
|
|
*/
|
2013-03-07 16:38:38 -06:00
|
|
|
pub fn rsplitn<T:Copy>(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] {
|
2013-06-08 20:38:47 -05:00
|
|
|
let ln = v.len();
|
2012-08-01 19:30:05 -05:00
|
|
|
if (ln == 0u) { return ~[] }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut end = ln;
|
|
|
|
let mut count = n;
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut result = ~[];
|
2012-01-26 20:13:43 -06:00
|
|
|
while end > 0u && count > 0u {
|
2013-06-21 19:08:35 -05:00
|
|
|
match rposition_between(v, 0u, end, |t| f(t)) {
|
2012-09-26 19:33:34 -05:00
|
|
|
None => break,
|
|
|
|
Some(i) => {
|
2013-06-27 04:48:50 -05:00
|
|
|
result.push(v.slice(i + 1u, end).to_owned());
|
2012-09-26 19:33:34 -05:00
|
|
|
// Make sure to skip the separator.
|
|
|
|
end = i;
|
|
|
|
count -= 1u;
|
|
|
|
}
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
}
|
2013-06-27 04:48:50 -05:00
|
|
|
result.push(v.slice(0u, end).to_owned());
|
2012-09-02 17:37:15 -05:00
|
|
|
reverse(result);
|
2012-12-12 17:38:50 -06:00
|
|
|
result
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
/// 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));
|
|
|
|
/// }
|
|
|
|
/// ~~~
|
2013-03-07 16:38:38 -06:00
|
|
|
pub fn consume<T>(mut v: ~[T], f: &fn(uint, v: T)) {
|
2013-01-23 13:43:58 -06:00
|
|
|
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
|
2013-05-05 23:42:54 -05:00
|
|
|
let x = intrinsics::init();
|
2013-01-23 13:43:58 -06:00
|
|
|
let p = ptr::mut_offset(p, i);
|
2013-05-31 09:21:29 -05:00
|
|
|
f(i, ptr::replace_ptr(p, x));
|
2013-01-23 13:43:58 -06:00
|
|
|
}
|
2012-07-03 19:33:20 -05:00
|
|
|
}
|
|
|
|
|
2013-01-23 13:43:58 -06:00
|
|
|
raw::set_len(&mut v, 0);
|
|
|
|
}
|
2012-07-03 19:33:20 -05:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
/// 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.
|
2013-03-29 09:29:52 -05:00
|
|
|
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
|
2013-05-05 23:42:54 -05:00
|
|
|
let x = intrinsics::init();
|
2013-03-29 09:29:52 -05:00
|
|
|
let p = ptr::mut_offset(p, i);
|
2013-05-31 09:21:29 -05:00
|
|
|
f(i, ptr::replace_ptr(p, x));
|
2013-03-29 09:29:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
raw::set_len(&mut v, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-01 14:11:54 -05:00
|
|
|
/**
|
|
|
|
* Remove consecutive repeated elements from a vector; if the vector is
|
|
|
|
* sorted, this removes all duplicates.
|
|
|
|
*/
|
2013-02-20 19:07:17 -06:00
|
|
|
pub fn dedup<T:Eq>(v: &mut ~[T]) {
|
2013-01-23 13:43:58 -06:00
|
|
|
unsafe {
|
|
|
|
if v.len() < 1 { return; }
|
2013-06-06 20:54:14 -05:00
|
|
|
let mut last_written = 0;
|
|
|
|
let mut next_to_read = 1;
|
2013-06-23 22:44:11 -05:00
|
|
|
do as_mut_buf(*v) |p, ln| {
|
2013-01-23 13:43:58 -06:00
|
|
|
// 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) {
|
2013-05-31 09:21:29 -05:00
|
|
|
ptr::replace_ptr(ptr::mut_offset(p, next_to_read),
|
|
|
|
intrinsics::uninit());
|
2013-01-23 13:43:58 -06:00
|
|
|
} else {
|
|
|
|
last_written += 1;
|
2013-05-09 06:05:17 -05:00
|
|
|
// last_written <= next_to_read < ln
|
|
|
|
if next_to_read != last_written {
|
2013-05-31 09:21:29 -05:00
|
|
|
ptr::swap_ptr(ptr::mut_offset(p, last_written),
|
|
|
|
ptr::mut_offset(p, next_to_read));
|
2013-05-09 06:05:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-13 18:25:51 -06:00
|
|
|
// Appending
|
2013-05-28 16:35:52 -05:00
|
|
|
|
|
|
|
/// Iterates over the `rhs` vector, copying each element and appending it to the
|
|
|
|
/// `lhs`. Afterwards, the `lhs` is then returned for use again.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-06-23 22:44:11 -05:00
|
|
|
pub fn append<T:Copy>(lhs: ~[T], rhs: &[T]) -> ~[T] {
|
2012-12-12 17:38:50 -06:00
|
|
|
let mut v = lhs;
|
2013-04-08 15:50:34 -05:00
|
|
|
v.push_all(rhs);
|
2012-12-12 17:38:50 -06:00
|
|
|
v
|
2012-06-13 18:14:01 -05:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
/// Appends one element to the vector provided. The vector itself is then
|
|
|
|
/// returned for use again.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
|
2012-12-12 17:38:50 -06:00
|
|
|
let mut v = lhs;
|
2013-04-08 15:50:34 -05:00
|
|
|
v.push(x);
|
2012-12-12 17:38:50 -06:00
|
|
|
v
|
2012-06-28 15:52:13 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2013-02-20 19:07:17 -06:00
|
|
|
pub fn grow<T:Copy>(v: &mut ~[T], n: uint, initval: &T) {
|
2013-02-09 00:21:45 -06:00
|
|
|
let new_len = v.len() + n;
|
2013-06-27 09:40:47 -05:00
|
|
|
v.reserve_at_least(new_len);
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i: uint = 0u;
|
2012-06-13 18:14:01 -05:00
|
|
|
|
2012-09-26 19:33:34 -05:00
|
|
|
while i < n {
|
2013-06-15 19:26:59 -05:00
|
|
|
v.push(copy *initval);
|
2012-09-26 19:33:34 -05:00
|
|
|
i += 1u;
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2013-06-23 16:57:39 -05:00
|
|
|
pub fn grow_fn<T>(v: &mut ~[T], n: uint, op: &fn(uint) -> T) {
|
2013-02-09 00:21:45 -06:00
|
|
|
let new_len = v.len() + n;
|
2013-06-27 09:40:47 -05:00
|
|
|
v.reserve_at_least(new_len);
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i: uint = 0u;
|
2012-09-26 19:33:34 -05:00
|
|
|
while i < n {
|
|
|
|
v.push(op(i));
|
|
|
|
i += 1u;
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-02-20 19:07:17 -06:00
|
|
|
pub fn grow_set<T:Copy>(v: &mut ~[T], index: uint, initval: &T, val: T) {
|
2012-09-28 00:20:47 -05:00
|
|
|
let l = v.len();
|
2013-01-11 23:01:42 -06:00
|
|
|
if index >= l { grow(&mut *v, index - l + 1u, initval); }
|
2012-12-12 17:38:50 -06:00
|
|
|
v[index] = val;
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Functional utilities
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Apply a function to each element of a vector and return the results
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn map<T, U>(v: &[T], f: &fn(t: &T) -> U) -> ~[U] {
|
2013-06-08 20:38:47 -05:00
|
|
|
let mut result = with_capacity(v.len());
|
2013-06-24 17:34:20 -05:00
|
|
|
for v.iter().advance |elem| {
|
2013-04-08 15:50:34 -05:00
|
|
|
result.push(f(elem));
|
2012-09-26 19:33:34 -05:00
|
|
|
}
|
2012-12-12 17:38:50 -06:00
|
|
|
result
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
/// 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.
|
2013-03-07 16:38:38 -06:00
|
|
|
pub fn map_consume<T, U>(v: ~[T], f: &fn(v: T) -> U) -> ~[U] {
|
2012-07-03 19:33:20 -05:00
|
|
|
let mut result = ~[];
|
2012-12-12 17:38:50 -06:00
|
|
|
do consume(v) |_i, x| {
|
|
|
|
result.push(f(x));
|
2012-07-03 19:33:20 -05:00
|
|
|
}
|
2012-12-12 17:38:50 -06:00
|
|
|
result
|
2012-07-03 19:33:20 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Apply a function to each element of a vector and return the results
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn mapi<T, U>(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] {
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut i = 0;
|
|
|
|
do map(v) |e| {
|
|
|
|
i += 1;
|
|
|
|
f(i - 1, e)
|
|
|
|
}
|
2012-05-18 12:40:54 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Apply a function to each element of a vector and return a concatenation
|
|
|
|
* of each result vector
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn flat_map<T, U>(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut result = ~[];
|
2013-06-24 17:34:20 -05:00
|
|
|
for v.iter().advance |elem| { result.push_all_move(f(elem)); }
|
2012-12-12 17:38:50 -06:00
|
|
|
result
|
2012-03-02 16:36:22 -06:00
|
|
|
}
|
|
|
|
|
2013-04-25 00:38:44 -05:00
|
|
|
/**
|
|
|
|
* Apply a function to each pair of elements and return the results.
|
|
|
|
* Equivalent to `map(zip(v0, v1), f)`.
|
|
|
|
*/
|
|
|
|
pub fn map_zip<T:Copy,U:Copy,V>(v0: &[T], v1: &[U],
|
2013-03-07 16:38:38 -06:00
|
|
|
f: &fn(t: &T, v: &U) -> V) -> ~[V] {
|
2013-06-08 20:38:47 -05:00
|
|
|
let v0_len = v0.len();
|
|
|
|
if v0_len != v1.len() { fail!(); }
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut u: ~[V] = ~[];
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = 0u;
|
2012-06-13 18:14:01 -05:00
|
|
|
while i < v0_len {
|
2013-04-08 15:50:34 -05:00
|
|
|
u.push(f(&v0[i], &v1[i]));
|
2012-06-13 18:14:01 -05:00
|
|
|
i += 1u;
|
|
|
|
}
|
2012-12-12 17:38:50 -06:00
|
|
|
u
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2013-01-31 19:12:29 -06:00
|
|
|
pub fn filter_map<T, U>(
|
|
|
|
v: ~[T],
|
2013-03-07 16:38:38 -06:00
|
|
|
f: &fn(t: T) -> Option<U>) -> ~[U]
|
2013-01-31 19:12:29 -06:00
|
|
|
{
|
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
}
|
|
|
|
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn filter_mapped<T, U: Copy>(
|
2013-01-31 19:12:29 -06:00
|
|
|
v: &[T],
|
2013-03-07 16:38:38 -06:00
|
|
|
f: &fn(t: &T) -> Option<U>) -> ~[U]
|
2013-01-31 19:12:29 -06:00
|
|
|
{
|
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* Like `filter_map()`, but operates on a borrowed slice
|
|
|
|
* and does not consume the input.
|
|
|
|
*/
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut result = ~[];
|
2013-06-24 17:34:20 -05:00
|
|
|
for v.iter().advance |elem| {
|
2012-09-28 00:20:47 -05:00
|
|
|
match f(elem) {
|
2012-08-20 14:23:37 -05:00
|
|
|
None => {/* no-op */ }
|
2013-04-08 15:50:34 -05:00
|
|
|
Some(result_elem) => { result.push(result_elem); }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
}
|
2012-12-12 17:38:50 -06:00
|
|
|
result
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2013-01-07 23:16:19 -06:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-03-07 16:38:38 -06:00
|
|
|
pub fn filter<T>(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] {
|
2013-01-07 23:16:19 -06:00
|
|
|
let mut result = ~[];
|
2013-01-09 19:14:30 -06:00
|
|
|
// FIXME (#4355 maybe): using v.consume here crashes
|
|
|
|
// do v.consume |_, elem| {
|
|
|
|
do consume(v) |_, elem| {
|
2013-01-07 23:16:19 -06:00
|
|
|
if f(&elem) { result.push(elem); }
|
|
|
|
}
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn filtered<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut result = ~[];
|
2013-06-24 17:34:20 -05:00
|
|
|
for v.iter().advance |elem| {
|
2013-06-15 19:26:59 -05:00
|
|
|
if f(elem) { result.push(copy *elem); }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
2012-12-12 17:38:50 -06:00
|
|
|
result
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2013-06-02 22:19:37 -05:00
|
|
|
/// Flattens a vector of vectors of T into a single vector of T.
|
2013-06-14 21:56:41 -05:00
|
|
|
pub fn concat<T:Copy>(v: &[~[T]]) -> ~[T] { v.concat_vec() }
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
|
|
/// Concatenate a vector of vectors, placing a given separator between each
|
2013-06-14 21:56:41 -05:00
|
|
|
pub fn connect<T:Copy>(v: &[~[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
|
|
/// Flattens a vector of vectors of T into a single vector of T.
|
2013-06-14 21:56:41 -05:00
|
|
|
pub fn concat_slices<T:Copy>(v: &[&[T]]) -> ~[T] { v.concat_vec() }
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Concatenate a vector of vectors, placing a given separator between each
|
2013-06-14 21:56:41 -05:00
|
|
|
pub fn connect_slices<T:Copy>(v: &[&[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
|
|
#[allow(missing_doc)]
|
|
|
|
pub trait VectorVector<T> {
|
2013-06-14 21:56:41 -05:00
|
|
|
// FIXME #5898: calling these .concat and .connect conflicts with
|
|
|
|
// StrVector::con{cat,nect}, since they have generic contents.
|
|
|
|
pub fn concat_vec(&self) -> ~[T];
|
|
|
|
pub fn connect_vec(&self, sep: &T) -> ~[T];
|
2013-06-02 22:19:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'self, T:Copy> VectorVector<T> for &'self [~[T]] {
|
|
|
|
/// Flattens a vector of slices of T into a single vector of T.
|
2013-06-14 21:56:41 -05:00
|
|
|
pub fn concat_vec(&self) -> ~[T] {
|
2013-06-02 22:19:37 -05:00
|
|
|
self.flat_map(|&inner| inner)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Concatenate a vector of vectors, placing a given separator between each.
|
2013-06-14 21:56:41 -05:00
|
|
|
pub fn connect_vec(&self, sep: &T) -> ~[T] {
|
2013-06-02 22:19:37 -05:00
|
|
|
let mut r = ~[];
|
|
|
|
let mut first = true;
|
2013-06-21 07:29:53 -05:00
|
|
|
for self.iter().advance |&inner| {
|
2013-06-15 19:26:59 -05:00
|
|
|
if first { first = false; } else { r.push(copy *sep); }
|
2013-06-02 22:19:37 -05:00
|
|
|
r.push_all(inner);
|
|
|
|
}
|
|
|
|
r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'self, T:Copy> VectorVector<T> for &'self [&'self [T]] {
|
|
|
|
/// Flattens a vector of slices of T into a single vector of T.
|
2013-06-14 21:56:41 -05:00
|
|
|
pub fn concat_vec(&self) -> ~[T] {
|
2013-06-02 22:19:37 -05:00
|
|
|
self.flat_map(|&inner| inner.to_owned())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Concatenate a vector of slices, placing a given separator between each.
|
2013-06-14 21:56:41 -05:00
|
|
|
pub fn connect_vec(&self, sep: &T) -> ~[T] {
|
2013-06-02 22:19:37 -05:00
|
|
|
let mut r = ~[];
|
|
|
|
let mut first = true;
|
2013-06-21 07:29:53 -05:00
|
|
|
for self.iter().advance |&inner| {
|
2013-06-15 19:26:59 -05:00
|
|
|
if first { first = false; } else { r.push(copy *sep); }
|
2013-06-02 22:19:37 -05:00
|
|
|
r.push_all(inner);
|
|
|
|
}
|
|
|
|
r
|
2012-01-28 17:41:53 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Return true if a vector contains an element with the given value
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn contains<T:Eq>(v: &[T], x: &T) -> bool {
|
2013-06-24 17:34:20 -05:00
|
|
|
for v.iter().advance |elt| { if *x == *elt { return true; } }
|
2013-03-09 15:41:43 -06:00
|
|
|
false
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn find_between<T:Copy>(v: &[T], start: uint, end: uint,
|
2013-03-07 16:38:38 -06:00
|
|
|
f: &fn(t: &T) -> bool) -> Option<T> {
|
2013-06-15 19:26:59 -05:00
|
|
|
position_between(v, start, end, f).map(|i| copy v[*i])
|
2012-01-26 20:14:27 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn rfind<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> Option<T> {
|
2013-06-08 20:38:47 -05:00
|
|
|
rfind_between(v, 0u, v.len(), f)
|
2012-01-26 20:14:27 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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
|
2012-09-28 00:20:47 -05:00
|
|
|
* the element is returned. If `f` matches no elements then none is return.
|
2012-07-04 16:53:12 -05:00
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn rfind_between<T:Copy>(v: &[T],
|
|
|
|
start: uint,
|
|
|
|
end: uint,
|
|
|
|
f: &fn(t: &T) -> bool)
|
|
|
|
-> Option<T> {
|
2013-06-15 19:26:59 -05:00
|
|
|
rposition_between(v, start, end, f).map(|i| copy v[*i])
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Find the first index containing a matching value
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn position_elem<T:Eq>(v: &[T], x: &T) -> Option<uint> {
|
2013-06-18 21:59:48 -05:00
|
|
|
v.iter().position_(|y| *x == *y)
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn position_between<T>(v: &[T],
|
|
|
|
start: uint,
|
|
|
|
end: uint,
|
|
|
|
f: &fn(t: &T) -> bool)
|
|
|
|
-> Option<uint> {
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(start <= end);
|
2013-06-08 20:38:47 -05:00
|
|
|
assert!(end <= v.len());
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = start;
|
2012-09-28 00:20:47 -05:00
|
|
|
while i < end { if f(&v[i]) { return Some::<uint>(i); } i += 1u; }
|
2013-03-09 15:41:43 -06:00
|
|
|
None
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Find the last index containing a matching value
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn rposition_elem<T:Eq>(v: &[T], x: &T) -> Option<uint> {
|
2012-09-28 00:20:47 -05:00
|
|
|
rposition(v, |y| *x == *y)
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn rposition<T>(v: &[T], f: &fn(t: &T) -> bool) -> Option<uint> {
|
2013-06-08 20:38:47 -05:00
|
|
|
rposition_between(v, 0u, v.len(), f)
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn rposition_between<T>(v: &[T], start: uint, end: uint,
|
2013-03-07 16:38:38 -06:00
|
|
|
f: &fn(t: &T) -> bool) -> Option<uint> {
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(start <= end);
|
2013-06-08 20:38:47 -05:00
|
|
|
assert!(end <= v.len());
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = end;
|
2012-01-26 10:42:50 -06:00
|
|
|
while i > start {
|
2012-09-28 00:20:47 -05:00
|
|
|
if f(&v[i - 1u]) { return Some::<uint>(i - 1u); }
|
2012-01-26 10:42:50 -06:00
|
|
|
i -= 1u;
|
|
|
|
}
|
2013-03-09 15:41:43 -06:00
|
|
|
None
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2013-01-04 15:52:18 -06:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Binary search a sorted vector with a comparator function.
|
|
|
|
*
|
|
|
|
* The comparator should implement an order consistent with the sort
|
|
|
|
* order of the underlying vector, returning an order code that indicates
|
|
|
|
* whether its argument is `Less`, `Equal` or `Greater` the desired target.
|
|
|
|
*
|
|
|
|
* Returns the index where the comparator returned `Equal`, or `None` if
|
|
|
|
* not found.
|
|
|
|
*/
|
2013-01-08 10:44:31 -06:00
|
|
|
pub fn bsearch<T>(v: &[T], f: &fn(&T) -> Ordering) -> Option<uint> {
|
2013-01-04 15:52:18 -06:00
|
|
|
let mut base : uint = 0;
|
|
|
|
let mut lim : uint = v.len();
|
|
|
|
|
|
|
|
while lim != 0 {
|
|
|
|
let ix = base + (lim >> 1);
|
|
|
|
match f(&v[ix]) {
|
|
|
|
Equal => return Some(ix),
|
|
|
|
Less => {
|
|
|
|
base = ix + 1;
|
|
|
|
lim -= 1;
|
|
|
|
}
|
|
|
|
Greater => ()
|
|
|
|
}
|
|
|
|
lim >>= 1;
|
|
|
|
}
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Binary search a sorted vector for a given element.
|
|
|
|
*
|
|
|
|
* Returns the index of the element or None if not found.
|
|
|
|
*/
|
2013-01-08 10:44:31 -06:00
|
|
|
pub fn bsearch_elem<T:TotalOrd>(v: &[T], x: &T) -> Option<uint> {
|
2013-01-04 15:52:18 -06:00
|
|
|
bsearch(v, |p| p.cmp(x))
|
|
|
|
}
|
|
|
|
|
2011-12-13 18:25:51 -06:00
|
|
|
// 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)
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
2012-08-23 19:51:34 -05:00
|
|
|
* Convert a vector of pairs into a pair of vectors, by reference. As unzip().
|
2012-07-04 16:53:12 -05:00
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
|
2013-06-06 20:54:14 -05:00
|
|
|
let mut ts = ~[];
|
|
|
|
let mut us = ~[];
|
2013-06-24 17:34:20 -05:00
|
|
|
for v.iter().advance |p| {
|
2013-06-15 19:26:59 -05:00
|
|
|
let (t, u) = copy *p;
|
2013-04-08 15:50:34 -05:00
|
|
|
ts.push(t);
|
|
|
|
us.push(u);
|
2012-06-27 17:21:50 -05:00
|
|
|
}
|
2013-03-09 15:41:43 -06:00
|
|
|
(ts, us)
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
2012-08-23 19:51:34 -05:00
|
|
|
* Convert a vector of pairs into a pair of vectors.
|
2012-07-04 16:53:12 -05:00
|
|
|
*
|
2012-08-23 19:51:34 -05:00
|
|
|
* 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.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
|
2013-06-06 20:54:14 -05:00
|
|
|
let mut ts = ~[];
|
|
|
|
let mut us = ~[];
|
2013-04-08 15:50:34 -05:00
|
|
|
do consume(v) |_i, p| {
|
|
|
|
let (t, u) = p;
|
|
|
|
ts.push(t);
|
|
|
|
us.push(u);
|
2012-08-23 19:51:34 -05:00
|
|
|
}
|
2012-12-12 17:38:50 -06:00
|
|
|
(ts, us)
|
2012-08-23 19:51:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert two vectors to a vector of pairs, by reference. As zip().
|
2012-07-04 16:53:12 -05:00
|
|
|
*/
|
2013-06-23 22:44:11 -05:00
|
|
|
pub fn zip_slice<T:Copy,U:Copy>(v: &[T], u: &[U])
|
2012-08-23 19:51:34 -05:00
|
|
|
-> ~[(T, U)] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut zipped = ~[];
|
2013-06-08 20:38:47 -05:00
|
|
|
let sz = v.len();
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = 0u;
|
2013-06-08 20:38:47 -05:00
|
|
|
assert_eq!(sz, u.len());
|
2013-01-23 13:43:58 -06:00
|
|
|
while i < sz {
|
2013-06-15 19:26:59 -05:00
|
|
|
zipped.push((copy v[i], copy u[i]));
|
2013-04-08 15:50:34 -05:00
|
|
|
i += 1u;
|
2013-01-23 13:43:58 -06:00
|
|
|
}
|
2012-12-12 17:38:50 -06:00
|
|
|
zipped
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-08-23 19:51:34 -05:00
|
|
|
/**
|
|
|
|
* Convert two vectors to a vector of pairs.
|
|
|
|
*
|
2013-06-06 02:38:41 -05:00
|
|
|
* Returns a vector of tuples, where the i-th tuple contains the
|
2012-08-23 19:51:34 -05:00
|
|
|
* i-th elements from each of the input vectors.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn zip<T, U>(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] {
|
2013-06-08 20:38:47 -05:00
|
|
|
let mut i = v.len();
|
|
|
|
assert_eq!(i, u.len());
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut w = with_capacity(i);
|
2012-08-23 19:51:34 -05:00
|
|
|
while i > 0 {
|
2013-04-08 15:50:34 -05:00
|
|
|
w.push((v.pop(),u.pop()));
|
2012-08-23 19:51:34 -05:00
|
|
|
i -= 1;
|
|
|
|
}
|
2013-04-08 15:50:34 -05:00
|
|
|
reverse(w);
|
2012-12-12 17:38:50 -06:00
|
|
|
w
|
2012-08-23 19:51:34 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-02-12 17:34:48 -06:00
|
|
|
pub fn swap<T>(v: &mut [T], a: uint, b: uint) {
|
2013-05-05 23:42:54 -05:00
|
|
|
unsafe {
|
|
|
|
// Can't take two mutable loans from one vector, so instead just cast
|
|
|
|
// them to their raw pointers to do the swap
|
2013-06-08 14:02:32 -05:00
|
|
|
let pa: *mut T = &mut v[a];
|
|
|
|
let pb: *mut T = &mut v[b];
|
2013-05-31 09:21:29 -05:00
|
|
|
ptr::swap_ptr(pa, pb);
|
2013-05-05 23:42:54 -05:00
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Reverse the order of elements in a vector, in place
|
2013-02-12 17:34:48 -06:00
|
|
|
pub fn reverse<T>(v: &mut [T]) {
|
2012-10-23 13:11:23 -05:00
|
|
|
let mut i: uint = 0;
|
2013-06-08 20:38:47 -05:00
|
|
|
let ln = v.len();
|
2013-05-05 23:42:54 -05:00
|
|
|
while i < ln / 2 {
|
|
|
|
swap(v, i, ln - i - 1);
|
|
|
|
i += 1;
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Returns a vector with the order of elements reversed
|
2013-06-23 22:44:11 -05:00
|
|
|
pub fn reversed<T:Copy>(v: &[T]) -> ~[T] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut rs: ~[T] = ~[];
|
2013-06-08 20:38:47 -05:00
|
|
|
let mut i = v.len();
|
2012-12-12 17:38:50 -06:00
|
|
|
if i == 0 { return (rs); } else { i -= 1; }
|
2013-06-15 19:26:59 -05:00
|
|
|
while i != 0 { rs.push(copy v[i]); i -= 1; }
|
|
|
|
rs.push(copy v[0]);
|
2012-12-12 17:38:50 -06:00
|
|
|
rs
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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).
|
|
|
|
*
|
2013-06-08 20:38:47 -05:00
|
|
|
* The total number of permutations produced is `v.len()!`. If `v` contains
|
2012-07-04 16:53:12 -05:00
|
|
|
* repeated elements, then some permutations are repeated.
|
2013-02-13 17:52:58 -06:00
|
|
|
*
|
|
|
|
* See [Algorithms to generate
|
|
|
|
* permutations](http://en.wikipedia.org/wiki/Permutation).
|
|
|
|
*
|
|
|
|
* # Arguments
|
|
|
|
*
|
|
|
|
* * `values` - A vector of values from which the permutations are
|
|
|
|
* chosen
|
|
|
|
*
|
|
|
|
* * `fun` - The function to iterate over the combinations
|
2012-07-04 16:53:12 -05:00
|
|
|
*/
|
2013-05-16 21:57:49 -05:00
|
|
|
pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) -> bool {
|
2013-02-13 17:52:58 -06:00
|
|
|
let length = values.len();
|
2013-06-15 19:26:59 -05:00
|
|
|
let mut permutation = vec::from_fn(length, |i| copy values[i]);
|
2013-02-13 17:52:58 -06:00
|
|
|
if length <= 1 {
|
|
|
|
fun(permutation);
|
2013-05-16 21:57:49 -05:00
|
|
|
return true;
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
|
|
|
let mut indices = vec::from_fn(length, |i| i);
|
|
|
|
loop {
|
2013-05-16 21:57:49 -05:00
|
|
|
if !fun(permutation) { return true; }
|
2013-02-13 17:52:58 -06:00
|
|
|
// find largest k such that indices[k] < indices[k+1]
|
|
|
|
// if no such k exists, all permutations have been generated
|
|
|
|
let mut k = length - 2;
|
|
|
|
while k > 0 && indices[k] >= indices[k+1] {
|
|
|
|
k -= 1;
|
|
|
|
}
|
2013-05-16 21:57:49 -05:00
|
|
|
if k == 0 && indices[0] > indices[1] { return true; }
|
2013-02-13 17:52:58 -06:00
|
|
|
// find largest l such that indices[k] < indices[l]
|
|
|
|
// k+1 is guaranteed to be such
|
|
|
|
let mut l = length - 1;
|
|
|
|
while indices[k] >= indices[l] {
|
|
|
|
l -= 1;
|
|
|
|
}
|
|
|
|
// swap indices[k] and indices[l]; sort indices[k+1..]
|
|
|
|
// (they're just reversed)
|
2013-05-15 19:35:43 -05:00
|
|
|
vec::swap(indices, k, l);
|
2013-06-26 18:37:19 -05:00
|
|
|
reverse(indices.mut_slice(k+1, length));
|
2013-02-13 17:52:58 -06:00
|
|
|
// fixup permutation based on indices
|
|
|
|
for uint::range(k, length) |i| {
|
2013-06-15 19:26:59 -05:00
|
|
|
permutation[i] = copy values[indices[i]];
|
2012-06-27 17:21:50 -05:00
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-16 08:00:16 -05:00
|
|
|
/**
|
|
|
|
* 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]`)
|
|
|
|
*
|
2013-05-27 08:49:54 -05:00
|
|
|
* ~~~ {.rust}
|
2013-04-16 08:00:16 -05:00
|
|
|
* for windowed(2, &[1,2,3,4]) |v| {
|
|
|
|
* io::println(fmt!("%?", v));
|
|
|
|
* }
|
|
|
|
* ~~~
|
|
|
|
*
|
|
|
|
*/
|
2013-05-03 15:33:33 -05:00
|
|
|
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;
|
|
|
|
}
|
2012-01-23 04:41:40 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Work with the buffer of a vector.
|
|
|
|
*
|
|
|
|
* Allows for unsafe manipulation of vector contents, which is useful for
|
|
|
|
* foreign interop.
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn as_imm_buf<T,U>(s: &[T],
|
|
|
|
/* NB---this CANNOT be const, see below */
|
|
|
|
f: &fn(*T, uint) -> U) -> U {
|
2012-09-12 12:38:17 -05:00
|
|
|
|
2013-03-22 19:58:50 -05:00
|
|
|
// NB---Do not change the type of s to `&const [T]`. This is
|
2012-09-12 12:38:17 -05:00
|
|
|
// 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!
|
|
|
|
|
2012-06-24 22:18:18 -05:00
|
|
|
unsafe {
|
2013-04-22 16:27:30 -05:00
|
|
|
let v : *(*T,uint) = transmute(&s);
|
2012-06-24 22:18:18 -05:00
|
|
|
let (buf,len) = *v;
|
2013-01-08 02:24:43 -06:00
|
|
|
f(buf, len / sys::nonzero_size_of::<T>())
|
2012-06-24 22:18:18 -05:00
|
|
|
}
|
2012-04-20 19:37:17 -05:00
|
|
|
}
|
|
|
|
|
2012-09-13 13:46:10 -05:00
|
|
|
/// Similar to `as_imm_buf` but passing a `*mut T`
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn as_mut_buf<T,U>(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U {
|
2012-09-12 12:38:17 -05:00
|
|
|
unsafe {
|
2013-04-22 16:27:30 -05:00
|
|
|
let v : *(*mut T,uint) = transmute(&s);
|
2012-09-12 12:38:17 -05:00
|
|
|
let (buf,len) = *v;
|
2013-01-08 02:24:43 -06:00
|
|
|
f(buf, len / sys::nonzero_size_of::<T>())
|
2012-06-24 22:18:18 -05:00
|
|
|
}
|
2012-06-02 21:03:28 -05:00
|
|
|
}
|
|
|
|
|
2012-08-27 19:15:54 -05:00
|
|
|
// Equality
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
/// 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.
|
2013-03-27 14:20:44 -05:00
|
|
|
fn eq<T: Eq>(a: &[T], b: &[T]) -> bool {
|
2012-08-27 19:15:54 -05:00
|
|
|
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;
|
|
|
|
}
|
2013-03-27 14:20:44 -05:00
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
/// 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`.
|
2013-03-27 14:20:44 -05:00
|
|
|
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; }
|
2012-08-27 19:15:54 -05:00
|
|
|
|
2013-03-27 14:20:44 -05:00
|
|
|
let mut i = 0;
|
|
|
|
while i < a_len {
|
|
|
|
if !a[i].equals(&b[i]) { return false; }
|
|
|
|
i += 1;
|
|
|
|
}
|
2013-03-09 15:41:43 -06:00
|
|
|
true
|
2012-08-27 19:15:54 -05:00
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-25 15:21:04 -05:00
|
|
|
impl<'self,T:Eq> Eq for &'self [T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) }
|
2012-10-19 08:01:01 -05:00
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-02-20 19:07:17 -06:00
|
|
|
impl<T:Eq> Eq for ~[T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
|
2012-09-19 20:00:26 -05:00
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-02-20 19:07:17 -06:00
|
|
|
impl<T:Eq> Eq for @[T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn ne(&self, other: &@[T]) -> bool { !self.eq(other) }
|
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-27 14:20:44 -05:00
|
|
|
impl<'self,T:TotalEq> TotalEq for &'self [T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) }
|
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-27 14:20:44 -05:00
|
|
|
impl<T:TotalEq> TotalEq for ~[T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) }
|
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-27 14:20:44 -05:00
|
|
|
impl<T:TotalEq> TotalEq for @[T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-27 14:20:44 -05:00
|
|
|
fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) }
|
2012-09-19 20:00:26 -05:00
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-25 15:21:04 -05:00
|
|
|
impl<'self,T:Eq> Equiv<~[T]> for &'self [T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) }
|
2013-03-04 21:43:14 -06:00
|
|
|
}
|
|
|
|
|
2012-08-27 19:15:54 -05:00
|
|
|
// Lexicographical comparison
|
|
|
|
|
2013-03-21 23:20:48 -05:00
|
|
|
fn cmp<T: TotalOrd>(a: &[T], b: &[T]) -> Ordering {
|
2013-03-01 21:07:12 -06:00
|
|
|
let low = uint::min(a.len(), b.len());
|
|
|
|
|
|
|
|
for uint::range(0, low) |idx| {
|
|
|
|
match a[idx].cmp(&b[idx]) {
|
|
|
|
Greater => return Greater,
|
|
|
|
Less => return Less,
|
|
|
|
Equal => ()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
a.len().cmp(&b.len())
|
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-25 15:21:04 -05:00
|
|
|
impl<'self,T:TotalOrd> TotalOrd for &'self [T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) }
|
2013-03-01 21:07:12 -06:00
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-01 21:07:12 -06:00
|
|
|
impl<T: TotalOrd> TotalOrd for ~[T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) }
|
2013-03-01 21:07:12 -06:00
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-01 21:07:12 -06:00
|
|
|
impl<T: TotalOrd> TotalOrd for @[T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) }
|
2013-03-01 21:07:12 -06:00
|
|
|
}
|
|
|
|
|
2013-03-21 23:20:48 -05:00
|
|
|
fn lt<T:Ord>(a: &[T], b: &[T]) -> bool {
|
2012-08-27 19:15:54 -05:00
|
|
|
let (a_len, b_len) = (a.len(), b.len());
|
2013-04-12 00:10:01 -05:00
|
|
|
let end = uint::min(a_len, b_len);
|
2012-08-27 19:15:54 -05:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-03-09 15:41:43 -06:00
|
|
|
a_len < b_len
|
2012-08-27 19:15:54 -05:00
|
|
|
}
|
|
|
|
|
2013-03-21 23:20:48 -05:00
|
|
|
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) }
|
2012-08-29 21:23:15 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-03-25 15:21:04 -05:00
|
|
|
impl<'self,T:Ord> Ord for &'self [T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) }
|
2012-10-19 08:01:01 -05:00
|
|
|
}
|
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-02-20 19:07:17 -06:00
|
|
|
impl<T:Ord> Ord for ~[T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) }
|
2012-09-19 20:00:26 -05:00
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-02-20 19:07:17 -06:00
|
|
|
impl<T:Ord> Ord for @[T] {
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) }
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) }
|
2012-09-19 20:00:26 -05:00
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
2013-05-08 06:11:23 -05:00
|
|
|
#[cfg(not(test))]
|
2013-06-28 22:44:55 -05:00
|
|
|
impl<'self,T:Copy> Add<&'self [T], ~[T]> for ~[T] {
|
|
|
|
#[inline]
|
|
|
|
fn add(&self, rhs: & &'self [T]) -> ~[T] {
|
|
|
|
append(copy *self, (*rhs))
|
2012-10-19 08:01:01 -05:00
|
|
|
}
|
2012-07-27 16:51:19 -05:00
|
|
|
}
|
|
|
|
|
2013-06-23 22:44:11 -05:00
|
|
|
impl<'self, T> Container for &'self [T] {
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Returns true if a vector contains no elements
|
2012-03-17 20:02:45 -05:00
|
|
|
#[inline]
|
2013-06-15 01:20:06 -05:00
|
|
|
fn is_empty(&self) -> bool {
|
2013-06-23 22:44:11 -05:00
|
|
|
as_imm_buf(*self, |_p, len| len == 0u)
|
2013-06-08 20:38:47 -05:00
|
|
|
}
|
2013-01-24 21:19:44 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Returns the length of a vector
|
2012-06-02 21:03:28 -05:00
|
|
|
#[inline]
|
2013-06-15 01:20:06 -05:00
|
|
|
fn len(&self) -> uint {
|
2013-06-23 22:44:11 -05:00
|
|
|
as_imm_buf(*self, |_p, len| len)
|
2013-06-08 20:38:47 -05:00
|
|
|
}
|
2013-06-15 01:20:06 -05:00
|
|
|
}
|
2013-06-08 20:38:47 -05:00
|
|
|
|
2013-06-15 01:20:06 -05:00
|
|
|
impl<T> Container for ~[T] {
|
|
|
|
/// Returns true if a vector contains no elements
|
|
|
|
#[inline]
|
|
|
|
fn is_empty(&self) -> bool {
|
2013-06-23 22:44:11 -05:00
|
|
|
as_imm_buf(*self, |_p, len| len == 0u)
|
2013-06-15 01:20:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the length of a vector
|
|
|
|
#[inline]
|
|
|
|
fn len(&self) -> uint {
|
2013-06-23 22:44:11 -05:00
|
|
|
as_imm_buf(*self, |_p, len| len)
|
2013-06-15 01:20:06 -05:00
|
|
|
}
|
2012-06-02 21:03:28 -05:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2012-10-01 17:45:34 -05:00
|
|
|
pub trait CopyableVector<T> {
|
2013-03-21 23:20:48 -05:00
|
|
|
fn to_owned(&self) -> ~[T];
|
2012-07-11 14:45:54 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Extension methods for vectors
|
2013-03-15 14:24:24 -05:00
|
|
|
impl<'self,T:Copy> CopyableVector<T> for &'self [T] {
|
2013-06-13 21:06:47 -05:00
|
|
|
/// Returns a copy of `v`.
|
2012-06-02 21:03:28 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn to_owned(&self) -> ~[T] {
|
2013-06-27 09:40:47 -05:00
|
|
|
let mut result = with_capacity(self.len());
|
2013-06-21 07:29:53 -05:00
|
|
|
for self.iter().advance |e| {
|
2013-04-30 13:10:21 -05:00
|
|
|
result.push(copy *e);
|
2013-03-16 13:11:31 -05:00
|
|
|
}
|
2013-03-20 13:13:13 -05:00
|
|
|
result
|
2013-01-07 21:46:45 -06:00
|
|
|
}
|
2012-06-02 21:03:28 -05:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2013-04-10 15:11:35 -05:00
|
|
|
pub trait ImmutableVector<'self, T> {
|
|
|
|
fn slice(&self, start: uint, end: uint) -> &'self [T];
|
2013-04-17 18:34:53 -05:00
|
|
|
fn iter(self) -> VecIterator<'self, T>;
|
2013-06-07 21:39:52 -05:00
|
|
|
fn rev_iter(self) -> VecRevIterator<'self, T>;
|
2013-04-10 15:11:35 -05:00
|
|
|
fn head(&self) -> &'self T;
|
|
|
|
fn head_opt(&self) -> Option<&'self T>;
|
|
|
|
fn tail(&self) -> &'self [T];
|
|
|
|
fn tailn(&self, n: uint) -> &'self [T];
|
|
|
|
fn init(&self) -> &'self [T];
|
|
|
|
fn initn(&self, n: uint) -> &'self [T];
|
|
|
|
fn last(&self) -> &'self T;
|
|
|
|
fn last_opt(&self) -> Option<&'self T>;
|
2013-05-14 04:10:50 -05:00
|
|
|
fn rposition(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
|
2013-04-10 15:11:35 -05:00
|
|
|
fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U];
|
|
|
|
fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U];
|
|
|
|
fn map_r<U>(&self, f: &fn(x: &T) -> U) -> ~[U];
|
|
|
|
fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U];
|
|
|
|
fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U];
|
2013-04-19 17:57:31 -05:00
|
|
|
unsafe fn unsafe_ref(&self, index: uint) -> *T;
|
2013-04-10 15:11:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Extension methods for vectors
|
|
|
|
impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
|
|
|
|
/// Return a slice that points into another slice.
|
|
|
|
#[inline]
|
|
|
|
fn slice(&self, start: uint, end: uint) -> &'self [T] {
|
2013-06-27 04:48:50 -05:00
|
|
|
assert!(start <= end);
|
|
|
|
assert!(end <= self.len());
|
|
|
|
do as_imm_buf(*self) |p, _len| {
|
|
|
|
unsafe {
|
|
|
|
transmute((ptr::offset(p, start),
|
|
|
|
(end - start) * sys::nonzero_size_of::<T>()))
|
|
|
|
}
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
}
|
|
|
|
|
2013-04-17 18:34:53 -05:00
|
|
|
#[inline]
|
|
|
|
fn iter(self) -> VecIterator<'self, T> {
|
|
|
|
unsafe {
|
|
|
|
let p = vec::raw::to_ptr(self);
|
|
|
|
VecIterator{ptr: p, end: p.offset(self.len()),
|
|
|
|
lifetime: cast::transmute(p)}
|
|
|
|
}
|
|
|
|
}
|
2013-06-07 21:39:52 -05:00
|
|
|
#[inline]
|
|
|
|
fn rev_iter(self) -> VecRevIterator<'self, T> {
|
|
|
|
unsafe {
|
|
|
|
let p = vec::raw::to_ptr(self);
|
|
|
|
VecRevIterator{ptr: p.offset(self.len() - 1),
|
|
|
|
end: p.offset(-1),
|
|
|
|
lifetime: cast::transmute(p)}
|
|
|
|
}
|
|
|
|
}
|
2013-04-17 18:34:53 -05:00
|
|
|
|
2013-04-10 15:11:35 -05:00
|
|
|
/// Returns the first element of a vector, failing if the vector is empty.
|
|
|
|
#[inline]
|
2013-06-27 07:36:27 -05:00
|
|
|
fn head(&self) -> &'self T {
|
|
|
|
if self.len() == 0 { fail!("head: empty vector") }
|
|
|
|
&self[0]
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
2013-06-27 07:36:27 -05:00
|
|
|
/// Returns the first element of a vector, or `None` if it is empty
|
2013-04-10 15:11:35 -05:00
|
|
|
#[inline]
|
2013-06-27 07:36:27 -05:00
|
|
|
fn head_opt(&self) -> Option<&'self T> {
|
|
|
|
if self.len() == 0 { None } else { Some(&self[0]) }
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
|
|
/// Returns all but the first element of a vector
|
|
|
|
#[inline]
|
2013-06-27 07:36:27 -05:00
|
|
|
fn tail(&self) -> &'self [T] { self.slice(1, self.len()) }
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
|
|
/// Returns all but the first `n' elements of a vector
|
|
|
|
#[inline]
|
2013-06-27 07:36:27 -05:00
|
|
|
fn tailn(&self, n: uint) -> &'self [T] { self.slice(n, self.len()) }
|
2013-04-10 15:11:35 -05:00
|
|
|
|
2013-06-27 07:36:27 -05:00
|
|
|
/// Returns all but the last element of a vector
|
2013-04-10 15:11:35 -05:00
|
|
|
#[inline]
|
2013-06-27 07:36:27 -05:00
|
|
|
fn init(&self) -> &'self [T] {
|
|
|
|
self.slice(0, self.len() - 1)
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
|
|
/// Returns all but the last `n' elemnts of a vector
|
|
|
|
#[inline]
|
2013-06-27 07:36:27 -05:00
|
|
|
fn initn(&self, n: uint) -> &'self [T] {
|
|
|
|
self.slice(0, self.len() - n)
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
2013-06-27 07:36:27 -05:00
|
|
|
/// Returns the last element of a vector, failing if the vector is empty.
|
2013-04-10 15:11:35 -05:00
|
|
|
#[inline]
|
2013-06-27 07:36:27 -05:00
|
|
|
fn last(&self) -> &'self T {
|
|
|
|
if self.len() == 0 { fail!("last: empty vector") }
|
|
|
|
&self[self.len() - 1]
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
2013-06-27 07:36:27 -05:00
|
|
|
/// Returns the last element of a vector, or `None` if it is empty.
|
2013-04-10 15:11:35 -05:00
|
|
|
#[inline]
|
2013-06-27 07:36:27 -05:00
|
|
|
fn last_opt(&self) -> Option<&'self T> {
|
|
|
|
if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
2013-05-14 04:10:50 -05:00
|
|
|
/**
|
|
|
|
* 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]
|
|
|
|
fn rposition(&self, f: &fn(t: &T) -> bool) -> Option<uint> {
|
|
|
|
rposition(*self, f)
|
|
|
|
}
|
|
|
|
|
2013-04-10 15:11:35 -05:00
|
|
|
/// Apply a function to each element of a vector and return the results
|
|
|
|
#[inline]
|
|
|
|
fn map<U>(&self, 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
|
|
|
|
*/
|
|
|
|
fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U] {
|
|
|
|
mapi(*self, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn map_r<U>(&self, f: &fn(x: &T) -> U) -> ~[U] {
|
|
|
|
let mut r = ~[];
|
|
|
|
let mut i = 0;
|
|
|
|
while i < self.len() {
|
|
|
|
r.push(f(&self[i]));
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
r
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Apply a function to each element of a vector and return a concatenation
|
|
|
|
* of each result vector
|
|
|
|
*/
|
|
|
|
#[inline]
|
|
|
|
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)
|
|
|
|
}
|
2013-04-19 17:57:31 -05:00
|
|
|
|
|
|
|
/// Returns a pointer to the element at the given index, without doing
|
|
|
|
/// bounds checking.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-04-19 17:57:31 -05:00
|
|
|
unsafe fn unsafe_ref(&self, index: uint) -> *T {
|
|
|
|
let (ptr, _): (*T, uint) = transmute(*self);
|
|
|
|
ptr.offset(index)
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2013-02-20 19:07:17 -06:00
|
|
|
pub trait ImmutableEqVector<T:Eq> {
|
2013-03-21 23:20:48 -05:00
|
|
|
fn position_elem(&self, t: &T) -> Option<uint>;
|
|
|
|
fn rposition_elem(&self, t: &T) -> Option<uint>;
|
2013-01-07 10:38:24 -06:00
|
|
|
}
|
|
|
|
|
2013-03-25 15:21:04 -05:00
|
|
|
impl<'self,T:Eq> ImmutableEqVector<T> for &'self [T] {
|
2012-08-27 18:26:35 -05:00
|
|
|
/// Find the first index containing a matching value
|
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn position_elem(&self, x: &T) -> Option<uint> {
|
2013-01-07 21:46:45 -06:00
|
|
|
position_elem(*self, x)
|
2012-09-28 00:20:47 -05:00
|
|
|
}
|
|
|
|
|
2012-08-27 18:26:35 -05:00
|
|
|
/// Find the last index containing a matching value
|
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn rposition_elem(&self, t: &T) -> Option<uint> {
|
2013-01-07 21:46:45 -06:00
|
|
|
rposition_elem(*self, t)
|
2012-09-28 00:20:47 -05:00
|
|
|
}
|
2012-08-27 18:26:35 -05:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2012-10-01 17:45:34 -05:00
|
|
|
pub trait ImmutableCopyableVector<T> {
|
2013-03-21 23:20:48 -05:00
|
|
|
fn filtered(&self, f: &fn(&T) -> bool) -> ~[T];
|
|
|
|
fn rfind(&self, f: &fn(t: &T) -> bool) -> Option<T>;
|
|
|
|
fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]);
|
2013-04-17 16:19:25 -05:00
|
|
|
unsafe fn unsafe_get(&self, elem: uint) -> T;
|
2012-07-11 14:45:54 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Extension methods for vectors
|
2013-03-25 15:21:04 -05:00
|
|
|
impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2012-06-02 21:03:28 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] {
|
2013-01-07 23:15:25 -06:00
|
|
|
filtered(*self, f)
|
2012-09-28 00:20:47 -05:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2012-06-02 21:03:28 -05:00
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn rfind(&self, f: &fn(t: &T) -> bool) -> Option<T> {
|
2013-01-07 21:46:45 -06:00
|
|
|
rfind(*self, f)
|
|
|
|
}
|
2013-01-07 10:49:41 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Partitions the vector into those that satisfies the predicate, and
|
|
|
|
* those that do not.
|
|
|
|
*/
|
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]) {
|
2013-06-27 09:10:18 -05:00
|
|
|
let mut lefts = ~[];
|
|
|
|
let mut rights = ~[];
|
|
|
|
|
|
|
|
for self.iter().advance |elt| {
|
|
|
|
if f(elt) {
|
|
|
|
lefts.push(copy *elt);
|
|
|
|
} else {
|
|
|
|
rights.push(copy *elt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(lefts, rights)
|
2013-01-07 10:49:41 -06:00
|
|
|
}
|
2013-04-17 16:19:25 -05:00
|
|
|
|
|
|
|
/// Returns the element at the given index, without doing bounds checking.
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-04-18 17:53:29 -05:00
|
|
|
unsafe fn unsafe_get(&self, index: uint) -> T {
|
2013-06-15 19:26:59 -05:00
|
|
|
copy *self.unsafe_ref(index)
|
2013-04-17 16:19:25 -05:00
|
|
|
}
|
2012-06-02 21:03:28 -05:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2013-01-07 10:38:24 -06:00
|
|
|
pub trait OwnedVector<T> {
|
2013-06-27 09:40:47 -05:00
|
|
|
fn reserve(&mut self, n: uint);
|
|
|
|
fn reserve_at_least(&mut self, n: uint);
|
|
|
|
fn capacity(&self) -> uint;
|
|
|
|
|
2012-10-02 13:37:37 -05:00
|
|
|
fn push(&mut self, t: T);
|
2013-06-27 08:53:37 -05:00
|
|
|
unsafe fn push_fast(&mut self, t: T);
|
|
|
|
|
2012-10-02 13:37:37 -05:00
|
|
|
fn push_all_move(&mut self, rhs: ~[T]);
|
2012-09-28 00:20:47 -05:00
|
|
|
fn pop(&mut self) -> T;
|
|
|
|
fn shift(&mut self) -> T;
|
2012-10-02 13:37:37 -05:00
|
|
|
fn unshift(&mut self, x: T);
|
2012-11-25 07:28:16 -06:00
|
|
|
fn insert(&mut self, i: uint, x:T);
|
|
|
|
fn remove(&mut self, i: uint) -> T;
|
2012-09-28 00:20:47 -05:00
|
|
|
fn swap_remove(&mut self, index: uint) -> T;
|
|
|
|
fn truncate(&mut self, newlen: uint);
|
2013-03-21 23:20:48 -05:00
|
|
|
fn retain(&mut self, f: &fn(t: &T) -> bool);
|
2013-03-07 16:38:38 -06:00
|
|
|
fn consume(self, f: &fn(uint, v: T));
|
2013-03-29 09:29:52 -05:00
|
|
|
fn consume_reverse(self, f: &fn(uint, v: T));
|
2013-03-07 16:38:38 -06:00
|
|
|
fn filter(self, f: &fn(t: &T) -> bool) -> ~[T];
|
2013-03-21 23:20:48 -05:00
|
|
|
fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]);
|
2013-06-23 16:57:39 -05:00
|
|
|
fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T);
|
2012-09-26 19:33:34 -05:00
|
|
|
}
|
|
|
|
|
2013-02-14 13:47:00 -06:00
|
|
|
impl<T> OwnedVector<T> for ~[T] {
|
2013-06-27 09:40:47 -05:00
|
|
|
/**
|
|
|
|
* Reserves capacity for exactly `n` elements in the given vector.
|
|
|
|
*
|
|
|
|
* If the capacity for `self` is already equal to or greater than the requested
|
|
|
|
* capacity, then no action is taken.
|
|
|
|
*
|
|
|
|
* # Arguments
|
|
|
|
*
|
|
|
|
* * n - The number of elements to reserve space for
|
|
|
|
*/
|
|
|
|
#[inline]
|
2013-06-29 21:40:40 -05:00
|
|
|
#[cfg(stage0)]
|
2013-06-27 09:40:47 -05:00
|
|
|
fn reserve(&mut self, n: uint) {
|
|
|
|
// Only make the (slow) call into the runtime if we have to
|
|
|
|
use managed;
|
|
|
|
if self.capacity() < n {
|
|
|
|
unsafe {
|
|
|
|
let ptr: **raw::VecRepr = cast::transmute(self);
|
|
|
|
let td = get_tydesc::<T>();
|
|
|
|
if ((**ptr).box_header.ref_count ==
|
|
|
|
managed::raw::RC_MANAGED_UNIQUE) {
|
|
|
|
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
|
|
|
|
} else {
|
|
|
|
rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-29 21:40:40 -05:00
|
|
|
/**
|
|
|
|
* Reserves capacity for exactly `n` elements in the given vector.
|
|
|
|
*
|
|
|
|
* If the capacity for `self` is already equal to or greater than the requested
|
|
|
|
* capacity, then no action is taken.
|
|
|
|
*
|
|
|
|
* # Arguments
|
|
|
|
*
|
|
|
|
* * n - The number of elements to reserve space for
|
|
|
|
*/
|
|
|
|
#[inline]
|
|
|
|
#[cfg(not(stage0))]
|
|
|
|
fn reserve(&mut self, n: uint) {
|
|
|
|
// Only make the (slow) call into the runtime if we have to
|
|
|
|
if self.capacity() < n {
|
|
|
|
unsafe {
|
|
|
|
let ptr: **raw::VecRepr = cast::transmute(self);
|
|
|
|
let td = get_tydesc::<T>();
|
|
|
|
if contains_managed::<T>() {
|
|
|
|
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
|
|
|
|
} else {
|
|
|
|
rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-27 09:40:47 -05:00
|
|
|
/**
|
|
|
|
* 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 `self` is already equal to or greater than the requested
|
|
|
|
* capacity, then no action is taken.
|
|
|
|
*
|
|
|
|
* # Arguments
|
|
|
|
*
|
|
|
|
* * n - The number of elements to reserve space for
|
|
|
|
*/
|
|
|
|
fn reserve_at_least(&mut self, n: uint) {
|
|
|
|
self.reserve(uint::next_power_of_two(n));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the number of elements the vector can hold without reallocating.
|
|
|
|
#[inline]
|
|
|
|
fn capacity(&self) -> uint {
|
|
|
|
unsafe {
|
|
|
|
let repr: **raw::VecRepr = transmute(self);
|
|
|
|
(**repr).unboxed.alloc / sys::nonzero_size_of::<T>()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-27 08:53:37 -05:00
|
|
|
/// Append an element to a vector
|
2013-01-07 10:17:03 -06:00
|
|
|
#[inline]
|
2012-10-02 13:37:37 -05:00
|
|
|
fn push(&mut self, t: T) {
|
2013-06-27 08:53:37 -05:00
|
|
|
unsafe {
|
|
|
|
let repr: **raw::VecRepr = transmute(&mut *self);
|
|
|
|
let fill = (**repr).unboxed.fill;
|
|
|
|
if (**repr).unboxed.alloc <= fill {
|
|
|
|
// need more space
|
|
|
|
reserve_no_inline(self);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.push_fast(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
// this peculiar function is because reserve_at_least is very
|
|
|
|
// large (because of reserve), and will be inlined, which
|
|
|
|
// makes push too large.
|
|
|
|
#[inline(never)]
|
|
|
|
fn reserve_no_inline<T>(v: &mut ~[T]) {
|
|
|
|
let new_len = v.len() + 1;
|
2013-06-27 09:40:47 -05:00
|
|
|
v.reserve_at_least(new_len);
|
2013-06-27 08:53:37 -05:00
|
|
|
}
|
2012-09-26 19:33:34 -05:00
|
|
|
}
|
|
|
|
|
2013-06-27 08:53:37 -05:00
|
|
|
// This doesn't bother to make sure we have space.
|
|
|
|
#[inline] // really pretty please
|
|
|
|
unsafe fn push_fast(&mut self, t: T) {
|
|
|
|
let repr: **mut raw::VecRepr = transmute(self);
|
|
|
|
let fill = (**repr).unboxed.fill;
|
|
|
|
(**repr).unboxed.fill += sys::nonzero_size_of::<T>();
|
|
|
|
let p = to_unsafe_ptr(&((**repr).unboxed.data));
|
|
|
|
let p = ptr::offset(p, fill) as *mut T;
|
|
|
|
intrinsics::move_val_init(&mut(*p), t);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Takes ownership of the vector `rhs`, moving all elements into
|
|
|
|
/// the current vector. This does not copy any elements, and it is
|
|
|
|
/// illegal to use the `rhs` vector after calling this method
|
|
|
|
/// (because it is moved here).
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ~~~ {.rust}
|
|
|
|
/// let mut a = ~[~1];
|
|
|
|
/// a.push_all_move(~[~2, ~3, ~4]);
|
|
|
|
/// assert!(a == ~[~1, ~2, ~3, ~4]);
|
|
|
|
/// ~~~
|
|
|
|
#[inline]
|
|
|
|
fn push_all_move(&mut self, mut rhs: ~[T]) {
|
|
|
|
let new_len = self.len() + rhs.len();
|
2013-06-27 09:40:47 -05:00
|
|
|
self.reserve(new_len);
|
2013-06-27 08:53:37 -05:00
|
|
|
unsafe {
|
|
|
|
do as_mut_buf(rhs) |p, len| {
|
|
|
|
for uint::range(0, len) |i| {
|
|
|
|
let x = ptr::replace_ptr(ptr::mut_offset(p, i),
|
|
|
|
intrinsics::uninit());
|
|
|
|
self.push(x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
raw::set_len(&mut rhs, 0);
|
|
|
|
}
|
2012-09-26 19:33:34 -05:00
|
|
|
}
|
2012-09-28 00:20:47 -05:00
|
|
|
|
2013-06-27 07:59:52 -05:00
|
|
|
/// Remove the last element from a vector and return it
|
2012-09-28 00:20:47 -05:00
|
|
|
fn pop(&mut self) -> T {
|
2013-06-27 07:59:52 -05:00
|
|
|
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
|
|
|
|
}
|
2012-09-28 00:20:47 -05:00
|
|
|
}
|
|
|
|
|
2013-06-27 07:59:52 -05:00
|
|
|
/// Removes the first element from a vector and return it
|
2012-09-28 00:20:47 -05:00
|
|
|
fn shift(&mut self) -> T {
|
2013-06-27 07:59:52 -05:00
|
|
|
unsafe {
|
|
|
|
assert!(!self.is_empty());
|
|
|
|
|
|
|
|
if self.len() == 1 { return self.pop() }
|
|
|
|
|
|
|
|
if self.len() == 2 {
|
|
|
|
let last = self.pop();
|
|
|
|
let first = self.pop();
|
|
|
|
self.push(last);
|
|
|
|
return first;
|
|
|
|
}
|
|
|
|
|
|
|
|
let ln = self.len();
|
|
|
|
let next_ln = self.len() - 1;
|
|
|
|
|
|
|
|
// Save the last element. We're going to overwrite its position
|
|
|
|
let work_elt = self.pop();
|
|
|
|
// We still should have room to work where what last element was
|
2013-06-27 09:40:47 -05:00
|
|
|
assert!(self.capacity() >= ln);
|
2013-06-27 07:59:52 -05:00
|
|
|
// Pretend like we have the original length so we can use
|
|
|
|
// the vector copy_memory to overwrite the hole we just made
|
|
|
|
raw::set_len(self, ln);
|
|
|
|
|
|
|
|
// Memcopy the head element (the one we want) to the location we just
|
|
|
|
// popped. For the moment it unsafely exists at both the head and last
|
|
|
|
// positions
|
|
|
|
{
|
|
|
|
let first_slice = self.slice(0, 1);
|
|
|
|
let last_slice = self.slice(next_ln, ln);
|
|
|
|
raw::copy_memory(transmute(last_slice), first_slice, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Memcopy everything to the left one element
|
|
|
|
{
|
|
|
|
let init_slice = self.slice(0, next_ln);
|
|
|
|
let tail_slice = self.slice(1, ln);
|
|
|
|
raw::copy_memory(transmute(init_slice),
|
|
|
|
tail_slice,
|
|
|
|
next_ln);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the new length. Now the vector is back to normal
|
|
|
|
raw::set_len(self, next_ln);
|
|
|
|
|
|
|
|
// Swap out the element we want from the end
|
|
|
|
let vp = raw::to_mut_ptr(*self);
|
|
|
|
let vp = ptr::mut_offset(vp, next_ln - 1);
|
|
|
|
|
|
|
|
ptr::replace_ptr(vp, work_elt)
|
|
|
|
}
|
2012-09-28 00:20:47 -05:00
|
|
|
}
|
|
|
|
|
2013-06-27 07:59:52 -05:00
|
|
|
/// Prepend an element to the vector
|
2012-10-02 13:37:37 -05:00
|
|
|
fn unshift(&mut self, x: T) {
|
2013-06-27 07:59:52 -05:00
|
|
|
let v = util::replace(self, ~[x]);
|
|
|
|
self.push_all_move(v);
|
2012-09-28 00:20:47 -05:00
|
|
|
}
|
|
|
|
|
2013-06-27 07:59:52 -05:00
|
|
|
/// Insert an element at position i within v, shifting all
|
|
|
|
/// elements after position i one position to the right.
|
2012-11-25 07:28:16 -06:00
|
|
|
fn insert(&mut self, i: uint, x:T) {
|
2013-06-27 07:59:52 -05:00
|
|
|
let len = self.len();
|
|
|
|
assert!(i <= len);
|
|
|
|
|
|
|
|
self.push(x);
|
|
|
|
let mut j = len;
|
|
|
|
while j > i {
|
|
|
|
swap(*self, j, j - 1);
|
|
|
|
j -= 1;
|
|
|
|
}
|
2012-11-25 07:28:16 -06:00
|
|
|
}
|
|
|
|
|
2013-06-27 07:59:52 -05:00
|
|
|
/// Remove and return the element at position i within v, shifting
|
|
|
|
/// all elements after position i one position to the left.
|
2012-11-25 07:28:16 -06:00
|
|
|
fn remove(&mut self, i: uint) -> T {
|
2013-06-27 07:59:52 -05:00
|
|
|
let len = self.len();
|
|
|
|
assert!(i < len);
|
|
|
|
|
|
|
|
let mut j = i;
|
|
|
|
while j < len - 1 {
|
|
|
|
swap(*self, j, j + 1);
|
|
|
|
j += 1;
|
|
|
|
}
|
|
|
|
self.pop()
|
2012-11-25 07:28:16 -06:00
|
|
|
}
|
|
|
|
|
2013-06-27 07:59:52 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2012-09-28 00:20:47 -05:00
|
|
|
fn swap_remove(&mut self, index: uint) -> T {
|
2013-06-27 07:59:52 -05:00
|
|
|
let ln = self.len();
|
|
|
|
if index >= ln {
|
|
|
|
fail!("vec::swap_remove - index %u >= length %u", index, ln);
|
|
|
|
}
|
|
|
|
if index < ln - 1 {
|
|
|
|
swap(*self, index, ln - 1);
|
|
|
|
}
|
|
|
|
self.pop()
|
2012-09-28 00:20:47 -05:00
|
|
|
}
|
|
|
|
|
2013-06-27 08:58:07 -05:00
|
|
|
/// Shorten a vector, dropping excess elements.
|
2012-09-28 00:20:47 -05:00
|
|
|
fn truncate(&mut self, newlen: uint) {
|
2013-06-27 08:58:07 -05:00
|
|
|
do as_mut_buf(*self) |p, oldlen| {
|
|
|
|
assert!(newlen <= oldlen);
|
|
|
|
unsafe {
|
|
|
|
// This loop is optimized out for non-drop types.
|
|
|
|
for uint::range(newlen, oldlen) |i| {
|
|
|
|
ptr::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unsafe { raw::set_len(self, newlen); }
|
2012-09-28 00:20:47 -05:00
|
|
|
}
|
2012-10-19 08:01:01 -05:00
|
|
|
|
2013-06-27 09:01:21 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Like `filter()`, but in place. Preserves order of `v`. Linear time.
|
|
|
|
*/
|
2013-03-21 23:20:48 -05:00
|
|
|
fn retain(&mut self, f: &fn(t: &T) -> bool) {
|
2013-06-27 09:01:21 -05:00
|
|
|
let len = self.len();
|
|
|
|
let mut deleted: uint = 0;
|
|
|
|
|
|
|
|
for uint::range(0, len) |i| {
|
|
|
|
if !f(&self[i]) {
|
|
|
|
deleted += 1;
|
|
|
|
} else if deleted > 0 {
|
|
|
|
swap(*self, i - deleted, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if deleted > 0 {
|
|
|
|
self.truncate(len - deleted);
|
|
|
|
}
|
2012-10-19 08:01:01 -05:00
|
|
|
}
|
2013-01-07 10:17:03 -06:00
|
|
|
|
2013-01-07 10:46:24 -06:00
|
|
|
#[inline]
|
2013-03-07 16:38:38 -06:00
|
|
|
fn consume(self, f: &fn(uint, v: T)) {
|
2013-01-07 10:46:24 -06:00
|
|
|
consume(self, f)
|
|
|
|
}
|
2013-01-07 10:49:41 -06:00
|
|
|
|
2013-03-29 09:29:52 -05:00
|
|
|
#[inline]
|
|
|
|
fn consume_reverse(self, f: &fn(uint, v: T)) {
|
|
|
|
consume_reverse(self, f)
|
|
|
|
}
|
|
|
|
|
2013-01-07 23:16:19 -06:00
|
|
|
#[inline]
|
2013-03-07 16:38:38 -06:00
|
|
|
fn filter(self, f: &fn(&T) -> bool) -> ~[T] {
|
2013-01-07 23:16:19 -06:00
|
|
|
filter(self, f)
|
|
|
|
}
|
|
|
|
|
2013-01-07 10:49:41 -06:00
|
|
|
/**
|
|
|
|
* Partitions the vector into those that satisfies the predicate, and
|
|
|
|
* those that do not.
|
|
|
|
*/
|
|
|
|
#[inline]
|
2013-03-07 16:38:38 -06:00
|
|
|
fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]) {
|
2013-06-27 09:10:18 -05:00
|
|
|
let mut lefts = ~[];
|
|
|
|
let mut rights = ~[];
|
|
|
|
|
|
|
|
do self.consume |_, elt| {
|
|
|
|
if f(&elt) {
|
|
|
|
lefts.push(elt);
|
|
|
|
} else {
|
|
|
|
rights.push(elt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(lefts, rights)
|
2013-01-07 10:49:41 -06:00
|
|
|
}
|
2013-02-17 13:08:04 -06:00
|
|
|
|
|
|
|
#[inline]
|
2013-06-23 16:57:39 -05:00
|
|
|
fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T) {
|
2013-02-17 13:08:04 -06:00
|
|
|
grow_fn(self, n, op);
|
|
|
|
}
|
2012-09-26 19:33:34 -05:00
|
|
|
}
|
|
|
|
|
2013-02-14 13:47:00 -06:00
|
|
|
impl<T> Mutable for ~[T] {
|
2013-01-24 22:08:16 -06:00
|
|
|
/// Clear the vector, removing all values.
|
|
|
|
fn clear(&mut self) { self.truncate(0) }
|
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2013-02-20 19:07:17 -06:00
|
|
|
pub trait OwnedCopyableVector<T:Copy> {
|
2013-06-23 22:44:11 -05:00
|
|
|
fn push_all(&mut self, rhs: &[T]);
|
2013-01-07 10:38:24 -06:00
|
|
|
fn grow(&mut self, n: uint, initval: &T);
|
|
|
|
fn grow_set(&mut self, index: uint, initval: &T, val: T);
|
|
|
|
}
|
|
|
|
|
2013-02-20 19:07:17 -06:00
|
|
|
impl<T:Copy> OwnedCopyableVector<T> for ~[T] {
|
2013-06-27 08:53:37 -05:00
|
|
|
/// Iterates over the slice `rhs`, copies each element, and then appends it to
|
|
|
|
/// the vector provided `v`. The `rhs` vector is traversed in-order.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ~~~ {.rust}
|
|
|
|
/// let mut a = ~[1];
|
|
|
|
/// a.push_all([2, 3, 4]);
|
|
|
|
/// assert!(a == ~[1, 2, 3, 4]);
|
|
|
|
/// ~~~
|
2013-01-07 10:17:03 -06:00
|
|
|
#[inline]
|
2013-06-23 22:44:11 -05:00
|
|
|
fn push_all(&mut self, rhs: &[T]) {
|
2013-06-27 08:53:37 -05:00
|
|
|
let new_len = self.len() + rhs.len();
|
2013-06-27 09:40:47 -05:00
|
|
|
self.reserve(new_len);
|
2013-06-27 08:53:37 -05:00
|
|
|
|
|
|
|
for uint::range(0u, rhs.len()) |i| {
|
|
|
|
self.push(unsafe { raw::get(rhs, i) })
|
|
|
|
}
|
2012-09-26 19:33:34 -05:00
|
|
|
}
|
2012-09-28 00:20:47 -05:00
|
|
|
|
2013-01-07 10:17:03 -06:00
|
|
|
#[inline]
|
2012-09-28 00:20:47 -05:00
|
|
|
fn grow(&mut self, n: uint, initval: &T) {
|
|
|
|
grow(self, n, initval);
|
|
|
|
}
|
|
|
|
|
2013-01-07 10:17:03 -06:00
|
|
|
#[inline]
|
2012-10-02 13:37:37 -05:00
|
|
|
fn grow_set(&mut self, index: uint, initval: &T, val: T) {
|
2012-09-28 00:20:47 -05:00
|
|
|
grow_set(self, index, initval, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2013-02-20 19:07:17 -06:00
|
|
|
trait OwnedEqVector<T:Eq> {
|
2013-01-07 10:38:24 -06:00
|
|
|
fn dedup(&mut self);
|
|
|
|
}
|
|
|
|
|
2013-02-20 19:07:17 -06:00
|
|
|
impl<T:Eq> OwnedEqVector<T> for ~[T] {
|
2013-01-07 10:17:03 -06:00
|
|
|
#[inline]
|
2012-09-28 00:20:47 -05:00
|
|
|
fn dedup(&mut self) {
|
|
|
|
dedup(self)
|
|
|
|
}
|
2012-09-26 19:33:34 -05:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2013-05-26 20:40:07 -05:00
|
|
|
pub trait MutableVector<'self, T> {
|
2013-05-29 00:56:21 -05:00
|
|
|
fn mut_slice(self, start: uint, end: uint) -> &'self mut [T];
|
2013-06-07 21:39:52 -05:00
|
|
|
fn mut_iter(self) -> VecMutIterator<'self, T>;
|
|
|
|
fn mut_rev_iter(self) -> VecMutRevIterator<'self, T>;
|
2013-05-26 20:40:07 -05:00
|
|
|
|
2013-06-18 01:52:14 -05:00
|
|
|
/**
|
|
|
|
* Consumes `src` and moves as many elements as it can into `self`
|
|
|
|
* from the range [start,end).
|
|
|
|
*
|
|
|
|
* Returns the number of elements copied (the shorter of self.len()
|
|
|
|
* and end - start).
|
|
|
|
*
|
|
|
|
* # Arguments
|
|
|
|
*
|
|
|
|
* * src - A mutable vector of `T`
|
|
|
|
* * start - The index into `src` to start copying from
|
|
|
|
* * end - The index into `str` to stop copying from
|
|
|
|
*/
|
|
|
|
fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
|
|
|
|
|
2013-04-18 17:53:29 -05:00
|
|
|
unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T;
|
|
|
|
unsafe fn unsafe_set(&self, index: uint, val: T);
|
2013-04-17 16:19:25 -05:00
|
|
|
}
|
|
|
|
|
2013-05-26 20:40:07 -05:00
|
|
|
impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
|
2013-06-27 04:48:50 -05:00
|
|
|
/// Return a slice that points into another slice.
|
2013-05-26 20:40:07 -05:00
|
|
|
#[inline]
|
2013-05-29 00:56:21 -05:00
|
|
|
fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
|
2013-06-27 04:48:50 -05:00
|
|
|
assert!(start <= end);
|
|
|
|
assert!(end <= self.len());
|
|
|
|
do as_mut_buf(self) |p, _len| {
|
|
|
|
unsafe {
|
|
|
|
transmute((ptr::mut_offset(p, start),
|
|
|
|
(end - start) * sys::nonzero_size_of::<T>()))
|
|
|
|
}
|
|
|
|
}
|
2013-05-26 20:40:07 -05:00
|
|
|
}
|
|
|
|
|
2013-06-06 00:12:39 -05:00
|
|
|
#[inline]
|
2013-06-07 21:39:52 -05:00
|
|
|
fn mut_iter(self) -> VecMutIterator<'self, T> {
|
2013-06-06 00:12:39 -05:00
|
|
|
unsafe {
|
|
|
|
let p = vec::raw::to_mut_ptr(self);
|
2013-06-07 21:39:52 -05:00
|
|
|
VecMutIterator{ptr: p, end: p.offset(self.len()),
|
2013-06-06 00:12:39 -05:00
|
|
|
lifetime: cast::transmute(p)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
fn mut_rev_iter(self) -> VecMutRevIterator<'self, T> {
|
|
|
|
unsafe {
|
|
|
|
let p = vec::raw::to_mut_ptr(self);
|
|
|
|
VecMutRevIterator{ptr: p.offset(self.len() - 1),
|
|
|
|
end: p.offset(-1),
|
|
|
|
lifetime: cast::transmute(p)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-18 01:52:14 -05:00
|
|
|
#[inline]
|
|
|
|
fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
|
|
|
|
for self.mut_iter().zip(src.mut_slice(start, end).mut_iter()).advance |(a, b)| {
|
|
|
|
util::swap(a, b);
|
|
|
|
}
|
|
|
|
cmp::min(self.len(), end-start)
|
|
|
|
}
|
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-04-18 17:53:29 -05:00
|
|
|
unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T {
|
2013-04-17 16:19:25 -05:00
|
|
|
let pair_ptr: &(*mut T, uint) = transmute(self);
|
|
|
|
let (ptr, _) = *pair_ptr;
|
2013-04-18 17:53:29 -05:00
|
|
|
ptr.offset(index)
|
|
|
|
}
|
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-04-18 17:53:29 -05:00
|
|
|
unsafe fn unsafe_set(&self, index: uint, val: T) {
|
|
|
|
*self.unsafe_mut_ref(index) = val;
|
2013-04-17 16:19:25 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-18 01:52:14 -05:00
|
|
|
/// Trait for ~[T] where T is Cloneable
|
|
|
|
pub trait MutableCloneableVector<T> {
|
|
|
|
/// Copies as many elements from `src` as it can into `self`
|
|
|
|
/// (the shorter of self.len() and src.len()). Returns the number of elements copied.
|
|
|
|
fn copy_from(self, &[T]) -> uint;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'self, T:Clone> MutableCloneableVector<T> for &'self mut [T] {
|
|
|
|
#[inline]
|
|
|
|
fn copy_from(self, src: &[T]) -> uint {
|
|
|
|
for self.mut_iter().zip(src.iter()).advance |(a, b)| {
|
|
|
|
*a = b.clone();
|
|
|
|
}
|
|
|
|
cmp::min(self.len(), src.len())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-11 17:37:37 -05:00
|
|
|
/**
|
|
|
|
* 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)
|
|
|
|
}
|
|
|
|
|
2012-10-11 19:58:45 -05:00
|
|
|
/// The internal 'unboxed' representation of a vector
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2012-10-11 19:58:45 -05:00
|
|
|
pub struct UnboxedVecRepr {
|
2013-04-02 16:15:04 -05:00
|
|
|
fill: uint,
|
|
|
|
alloc: uint,
|
2012-10-11 19:58:45 -05:00
|
|
|
data: u8
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Unsafe operations
|
2012-12-14 17:47:11 -06:00
|
|
|
pub mod raw {
|
2013-04-22 16:27:30 -05:00
|
|
|
use cast::transmute;
|
2013-01-08 21:37:25 -06:00
|
|
|
use kinds::Copy;
|
2012-12-23 16:41:37 -06:00
|
|
|
use managed;
|
2013-01-08 21:37:25 -06:00
|
|
|
use option::{None, Some};
|
2012-12-23 16:41:37 -06:00
|
|
|
use ptr;
|
|
|
|
use sys;
|
2013-04-22 16:27:30 -05:00
|
|
|
use unstable::intrinsics;
|
2013-06-23 22:44:11 -05:00
|
|
|
use vec::{UnboxedVecRepr, as_imm_buf, as_mut_buf, with_capacity};
|
2013-05-05 23:42:54 -05:00
|
|
|
use util;
|
2012-09-14 21:09:38 -05:00
|
|
|
|
|
|
|
/// The internal representation of a (boxed) vector
|
2013-05-28 16:35:52 -05:00
|
|
|
#[allow(missing_doc)]
|
2012-10-01 17:45:34 -05:00
|
|
|
pub struct VecRepr {
|
2012-12-03 19:45:19 -06:00
|
|
|
box_header: managed::raw::BoxHeaderRepr,
|
2012-09-14 21:09:38 -05:00
|
|
|
unboxed: UnboxedVecRepr
|
|
|
|
}
|
|
|
|
|
2013-05-28 16:35:52 -05:00
|
|
|
/// The internal representation of a slice
|
2013-01-22 10:12:52 -06:00
|
|
|
pub struct SliceRepr {
|
2013-05-28 16:35:52 -05:00
|
|
|
/// Pointer to the base of this slice
|
2013-04-02 16:15:04 -05:00
|
|
|
data: *u8,
|
2013-05-28 16:35:52 -05:00
|
|
|
/// The length of the slice
|
2013-04-02 16:15:04 -05:00
|
|
|
len: uint
|
2013-01-22 10:12:52 -06:00
|
|
|
}
|
2012-07-12 21:44:00 -05:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2012-10-01 17:45:34 -05:00
|
|
|
pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
|
2013-04-22 16:27:30 -05:00
|
|
|
let repr: **mut VecRepr = transmute(v);
|
2013-01-08 02:24:43 -06:00
|
|
|
(**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-15 23:34:32 -05:00
|
|
|
pub fn to_ptr<T>(v: &[T]) -> *T {
|
|
|
|
unsafe {
|
|
|
|
let repr: **SliceRepr = transmute(&v);
|
|
|
|
transmute(&((**repr).data))
|
|
|
|
}
|
2012-07-12 21:44:00 -05:00
|
|
|
}
|
|
|
|
|
2012-09-12 12:38:17 -05:00
|
|
|
/** see `to_ptr()` */
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-05-15 23:34:32 -05:00
|
|
|
pub fn to_mut_ptr<T>(v: &mut [T]) -> *mut T {
|
|
|
|
unsafe {
|
|
|
|
let repr: **SliceRepr = transmute(&v);
|
|
|
|
transmute(&((**repr).data))
|
|
|
|
}
|
2012-09-12 12:38:17 -05:00
|
|
|
}
|
2012-04-25 19:18:06 -05:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Form a slice from a pointer and length (as a number of units,
|
|
|
|
* not bytes).
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2012-09-26 23:35:42 -05:00
|
|
|
pub unsafe fn buf_as_slice<T,U>(p: *T,
|
|
|
|
len: uint,
|
2013-03-07 16:38:38 -06:00
|
|
|
f: &fn(v: &[T]) -> U) -> U {
|
2013-01-08 02:24:43 -06:00
|
|
|
let pair = (p, len * sys::nonzero_size_of::<T>());
|
2013-04-22 16:27:30 -05:00
|
|
|
let v : *(&'blk [T]) = transmute(&pair);
|
2012-04-25 19:18:06 -05:00
|
|
|
f(*v)
|
|
|
|
}
|
2012-07-20 21:20:13 -05:00
|
|
|
|
2013-03-09 21:14:35 -06:00
|
|
|
/**
|
|
|
|
* Form a slice from a pointer and length (as a number of units,
|
|
|
|
* not bytes).
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-03-09 21:14:35 -06:00
|
|
|
pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
|
|
|
|
len: uint,
|
|
|
|
f: &fn(v: &mut [T]) -> U) -> U {
|
|
|
|
let pair = (p, len * sys::nonzero_size_of::<T>());
|
2013-04-22 16:27:30 -05:00
|
|
|
let v : *(&'blk mut [T]) = transmute(&pair);
|
2013-03-09 21:14:35 -06:00
|
|
|
f(*v)
|
|
|
|
}
|
|
|
|
|
2012-08-01 14:37:13 -05:00
|
|
|
/**
|
|
|
|
* Unchecked vector indexing.
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-06-23 22:44:11 -05:00
|
|
|
pub unsafe fn get<T:Copy>(v: &[T], i: uint) -> T {
|
|
|
|
as_imm_buf(v, |p, _len| copy *ptr::offset(p, i))
|
2012-08-01 14:37:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-09-28 00:20:47 -05:00
|
|
|
* Unchecked vector index assignment. Does not drop the
|
|
|
|
* old value and hence is only suitable when the vector
|
|
|
|
* is newly allocated.
|
2012-08-01 14:37:13 -05:00
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-02-12 17:34:48 -06:00
|
|
|
pub unsafe fn init_elem<T>(v: &mut [T], i: uint, val: T) {
|
2012-12-12 17:38:50 -06:00
|
|
|
let mut box = Some(val);
|
2012-08-01 14:37:13 -05:00
|
|
|
do as_mut_buf(v) |p, _len| {
|
2013-05-05 23:42:54 -05:00
|
|
|
let box2 = util::replace(&mut box, None);
|
2013-02-20 10:57:15 -06:00
|
|
|
intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)),
|
2013-03-09 15:41:43 -06:00
|
|
|
box2.unwrap());
|
2012-08-01 14:37:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-11 17:37:37 -05:00
|
|
|
/**
|
|
|
|
* 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
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2012-10-11 17:37:37 -05:00
|
|
|
pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
|
|
|
|
let mut dst = with_capacity(elts);
|
|
|
|
set_len(&mut dst, elts);
|
2013-01-10 01:11:04 -06:00
|
|
|
as_mut_buf(dst, |p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts));
|
2012-12-12 17:38:50 -06:00
|
|
|
dst
|
2012-10-11 17:37:37 -05:00
|
|
|
}
|
|
|
|
|
2012-07-20 21:20:13 -05:00
|
|
|
/**
|
|
|
|
* Copies data from one vector to another.
|
|
|
|
*
|
|
|
|
* Copies `count` bytes from `src` to `dst`. The source and destination
|
|
|
|
* may overlap.
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-06-23 22:44:11 -05:00
|
|
|
pub unsafe fn copy_memory<T>(dst: &mut [T], src: &[T],
|
2013-01-13 18:34:54 -06:00
|
|
|
count: uint) {
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(dst.len() >= count);
|
|
|
|
assert!(src.len() >= count);
|
2013-01-05 04:52:37 -06:00
|
|
|
|
2012-09-12 12:38:17 -05:00
|
|
|
do as_mut_buf(dst) |p_dst, _len_dst| {
|
2013-06-23 22:44:11 -05:00
|
|
|
do as_imm_buf(src) |p_src, _len_src| {
|
2013-01-10 01:11:04 -06:00
|
|
|
ptr::copy_memory(p_dst, p_src, count)
|
2012-07-20 21:20:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Operations on `[u8]`
|
2012-10-01 17:45:34 -05:00
|
|
|
pub mod bytes {
|
2012-12-23 16:41:37 -06:00
|
|
|
use libc;
|
|
|
|
use uint;
|
2013-01-08 21:29:16 -06:00
|
|
|
use vec::raw;
|
2013-01-08 21:37:25 -06:00
|
|
|
use vec;
|
2013-06-18 01:20:53 -05:00
|
|
|
use ptr;
|
|
|
|
|
|
|
|
/// A trait for operations on mutable operations on `[u8]`
|
|
|
|
pub trait MutableByteVector {
|
|
|
|
/// Sets all bytes of the receiver to the given value.
|
|
|
|
pub fn set_memory(self, value: u8);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'self> MutableByteVector for &'self mut [u8] {
|
|
|
|
#[inline]
|
|
|
|
fn set_memory(self, value: u8) {
|
|
|
|
do vec::as_mut_buf(self) |p, len| {
|
|
|
|
unsafe { ptr::set_memory(p, value, len) };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Bytewise string comparison
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn memcmp(a: &~[u8], b: &~[u8]) -> int {
|
2013-03-09 15:41:43 -06:00
|
|
|
let a_len = a.len();
|
|
|
|
let b_len = b.len();
|
2012-08-30 14:54:50 -05:00
|
|
|
let n = uint::min(a_len, b_len) as libc::size_t;
|
2012-06-24 22:18:18 -05:00
|
|
|
let r = unsafe {
|
2012-09-12 19:45:23 -05:00
|
|
|
libc::memcmp(raw::to_ptr(*a) as *libc::c_void,
|
|
|
|
raw::to_ptr(*b) as *libc::c_void, n) as int
|
2012-06-24 22:18:18 -05:00
|
|
|
};
|
2012-01-06 09:36:56 -06:00
|
|
|
|
|
|
|
if r != 0 { r } else {
|
|
|
|
if a_len == b_len {
|
|
|
|
0
|
|
|
|
} else if a_len < b_len {
|
|
|
|
-1
|
|
|
|
} else {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Bytewise less than or equal
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn lt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) < 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Bytewise less than or equal
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn le(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) <= 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Bytewise equality
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn eq(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) == 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Bytewise inequality
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn ne(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) != 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Bytewise greater than or equal
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn ge(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) >= 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Bytewise greater than
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn gt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) > 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-07-20 21:20:13 -05:00
|
|
|
/**
|
|
|
|
* Copies data from one vector to another.
|
|
|
|
*
|
|
|
|
* Copies `count` bytes from `src` to `dst`. The source and destination
|
2013-01-15 01:36:45 -06:00
|
|
|
* may overlap.
|
2012-07-20 21:20:13 -05:00
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-06-23 22:44:11 -05:00
|
|
|
pub fn copy_memory(dst: &mut [u8], src: &[u8], count: uint) {
|
2013-01-10 01:11:04 -06:00
|
|
|
// Bound checks are done at vec::raw::copy_memory.
|
|
|
|
unsafe { vec::raw::copy_memory(dst, src, count) }
|
2012-07-20 21:20:13 -05:00
|
|
|
}
|
2012-01-06 09:36:56 -06:00
|
|
|
}
|
|
|
|
|
2013-03-15 17:26:59 -05:00
|
|
|
impl<A:Clone> Clone for ~[A] {
|
|
|
|
#[inline]
|
|
|
|
fn clone(&self) -> ~[A] {
|
2013-03-22 15:09:20 -05:00
|
|
|
self.map(|item| item.clone())
|
2013-03-15 17:26:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-17 02:05:51 -05:00
|
|
|
// This works because every lifetime is a sub-lifetime of 'static
|
|
|
|
impl<'self, A> Zero for &'self [A] {
|
|
|
|
fn zero() -> &'self [A] { &'self [] }
|
|
|
|
fn is_zero(&self) -> bool { self.is_empty() }
|
|
|
|
}
|
|
|
|
|
2013-06-14 20:27:52 -05:00
|
|
|
impl<A> Zero for ~[A] {
|
|
|
|
fn zero() -> ~[A] { ~[] }
|
|
|
|
fn is_zero(&self) -> bool { self.len() == 0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<A> Zero for @[A] {
|
|
|
|
fn zero() -> @[A] { @[] }
|
|
|
|
fn is_zero(&self) -> bool { self.len() == 0 }
|
|
|
|
}
|
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
macro_rules! iterator {
|
|
|
|
/* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
|
|
|
|
(struct $name:ident -> $ptr:ty, $elem:ty) => {
|
|
|
|
pub struct $name<'self, T> {
|
|
|
|
priv ptr: $ptr,
|
|
|
|
priv end: $ptr,
|
|
|
|
priv lifetime: $elem // FIXME: #5922
|
|
|
|
}
|
|
|
|
};*/
|
|
|
|
(impl $name:ident -> $elem:ty, $step:expr) => {
|
|
|
|
// could be implemented with &[T] with .slice(), but this avoids bounds checks
|
|
|
|
impl<'self, T> Iterator<$elem> for $name<'self, T> {
|
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<$elem> {
|
|
|
|
unsafe {
|
|
|
|
if self.ptr == self.end {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let old = self.ptr;
|
|
|
|
self.ptr = self.ptr.offset($step);
|
|
|
|
Some(cast::transmute(old))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-06-21 05:12:01 -05:00
|
|
|
|
|
|
|
#[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)
|
|
|
|
}
|
2013-06-07 21:39:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//iterator!{struct VecIterator -> *T, &'self T}
|
|
|
|
/// An iterator for iterating over a vector
|
2013-04-17 18:34:53 -05:00
|
|
|
pub struct VecIterator<'self, T> {
|
|
|
|
priv ptr: *T,
|
|
|
|
priv end: *T,
|
|
|
|
priv lifetime: &'self T // FIXME: #5922
|
|
|
|
}
|
2013-06-07 21:39:52 -05:00
|
|
|
iterator!{impl VecIterator -> &'self T, 1}
|
2013-04-17 18:34:53 -05:00
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
//iterator!{struct VecRevIterator -> *T, &'self T}
|
|
|
|
/// An iterator for iterating over a vector in reverse
|
|
|
|
pub struct VecRevIterator<'self, T> {
|
|
|
|
priv ptr: *T,
|
|
|
|
priv end: *T,
|
|
|
|
priv lifetime: &'self T // FIXME: #5922
|
2013-04-17 18:34:53 -05:00
|
|
|
}
|
2013-06-07 21:39:52 -05:00
|
|
|
iterator!{impl VecRevIterator -> &'self T, -1}
|
2012-06-02 21:03:28 -05:00
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
//iterator!{struct VecMutIterator -> *mut T, &'self mut T}
|
|
|
|
/// An iterator for mutating the elements of a vector
|
|
|
|
pub struct VecMutIterator<'self, T> {
|
2013-06-06 00:12:39 -05:00
|
|
|
priv ptr: *mut T,
|
|
|
|
priv end: *mut T,
|
|
|
|
priv lifetime: &'self mut T // FIXME: #5922
|
|
|
|
}
|
2013-06-07 21:39:52 -05:00
|
|
|
iterator!{impl VecMutIterator -> &'self mut T, 1}
|
2013-06-06 00:12:39 -05:00
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
//iterator!{struct VecMutRevIterator -> *mut T, &'self mut T}
|
|
|
|
/// An iterator for mutating the elements of a vector in reverse
|
|
|
|
pub struct VecMutRevIterator<'self, T> {
|
|
|
|
priv ptr: *mut T,
|
|
|
|
priv end: *mut T,
|
|
|
|
priv lifetime: &'self mut T // FIXME: #5922
|
2013-06-06 00:12:39 -05:00
|
|
|
}
|
2013-06-07 21:39:52 -05:00
|
|
|
iterator!{impl VecMutRevIterator -> &'self mut T, -1}
|
2013-06-06 00:12:39 -05:00
|
|
|
|
2013-06-06 15:34:50 -05:00
|
|
|
impl<T> FromIter<T> for ~[T]{
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2013-06-06 15:34:50 -05:00
|
|
|
pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
|
|
|
|
let mut v = ~[];
|
|
|
|
for iter |x| { v.push(x) }
|
|
|
|
v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-25 16:07:44 -05:00
|
|
|
#[cfg(stage0)]
|
2013-06-24 00:21:32 -05:00
|
|
|
impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
|
|
|
|
pub fn from_iterator(iterator: &mut T) -> ~[A] {
|
|
|
|
let mut xs = ~[];
|
|
|
|
for iterator.advance |x| {
|
|
|
|
xs.push(x);
|
|
|
|
}
|
|
|
|
xs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-25 16:07:44 -05:00
|
|
|
|
|
|
|
#[cfg(not(stage0))]
|
2013-06-21 06:57:22 -05:00
|
|
|
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());
|
|
|
|
for iterator.advance |x| {
|
|
|
|
xs.push(x);
|
|
|
|
}
|
|
|
|
xs
|
|
|
|
}
|
|
|
|
}
|
2013-06-25 16:07:44 -05:00
|
|
|
|
2013-06-21 06:57:22 -05:00
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2013-01-08 21:37:25 -06:00
|
|
|
use option::{None, Option, Some};
|
2013-02-25 13:11:21 -06:00
|
|
|
use sys;
|
2013-01-08 21:37:25 -06:00
|
|
|
use vec::*;
|
2013-03-01 21:07:12 -06:00
|
|
|
use cmp::*;
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2013-03-09 15:41:43 -06:00
|
|
|
fn square(n: uint) -> uint { n * n }
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2013-03-09 15:41:43 -06:00
|
|
|
fn square_ref(n: &uint) -> uint { square(*n) }
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2013-03-21 23:20:48 -05:00
|
|
|
fn is_three(n: &uint) -> bool { *n == 3u }
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2013-03-21 23:20:48 -05:00
|
|
|
fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2013-03-21 23:20:48 -05:00
|
|
|
fn is_equal(x: &uint, y:&uint) -> bool { *x == *y }
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2013-01-31 19:12:29 -06:00
|
|
|
fn square_if_odd_r(n: &uint) -> Option<uint> {
|
2013-03-09 15:41:43 -06:00
|
|
|
if *n % 2u == 1u { Some(*n * *n) } else { None }
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2013-01-31 19:12:29 -06:00
|
|
|
fn square_if_odd_v(n: uint) -> Option<uint> {
|
2013-03-09 15:41:43 -06:00
|
|
|
if n % 2u == 1u { Some(n * n) } else { None }
|
2013-01-31 19:12:29 -06:00
|
|
|
}
|
|
|
|
|
2013-03-09 15:41:43 -06:00
|
|
|
fn add(x: uint, y: &uint) -> uint { x + *y }
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
#[test]
|
2012-06-24 22:18:18 -05:00
|
|
|
fn test_unsafe_ptrs() {
|
|
|
|
unsafe {
|
|
|
|
// Test on-stack copy-from-buf.
|
2012-06-29 18:26:56 -05:00
|
|
|
let a = ~[1, 2, 3];
|
2012-09-12 19:45:23 -05:00
|
|
|
let mut ptr = raw::to_ptr(a);
|
2012-10-11 18:18:36 -05:00
|
|
|
let b = from_buf(ptr, 3u);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(b.len(), 3u);
|
|
|
|
assert_eq!(b[0], 1);
|
|
|
|
assert_eq!(b[1], 2);
|
|
|
|
assert_eq!(b[2], 3);
|
2012-06-24 22:18:18 -05:00
|
|
|
|
|
|
|
// Test on-heap copy-from-buf.
|
2012-06-29 18:26:56 -05:00
|
|
|
let c = ~[1, 2, 3, 4, 5];
|
2012-09-12 19:45:23 -05:00
|
|
|
ptr = raw::to_ptr(c);
|
2012-10-11 18:18:36 -05:00
|
|
|
let d = from_buf(ptr, 5u);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(d.len(), 5u);
|
|
|
|
assert_eq!(d[0], 1);
|
|
|
|
assert_eq!(d[1], 2);
|
|
|
|
assert_eq!(d[2], 3);
|
|
|
|
assert_eq!(d[3], 4);
|
|
|
|
assert_eq!(d[4], 5);
|
2012-06-24 22:18:18 -05:00
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-12 17:52:30 -05:00
|
|
|
fn test_from_fn() {
|
|
|
|
// Test on-stack from_fn.
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut v = from_fn(3u, square);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 3u);
|
|
|
|
assert_eq!(v[0], 0u);
|
|
|
|
assert_eq!(v[1], 1u);
|
|
|
|
assert_eq!(v[2], 4u);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-03-12 17:52:30 -05:00
|
|
|
// Test on-heap from_fn.
|
|
|
|
v = from_fn(5u, square);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 5u);
|
|
|
|
assert_eq!(v[0], 0u);
|
|
|
|
assert_eq!(v[1], 1u);
|
|
|
|
assert_eq!(v[2], 4u);
|
|
|
|
assert_eq!(v[3], 9u);
|
|
|
|
assert_eq!(v[4], 16u);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-12 17:52:30 -05:00
|
|
|
fn test_from_elem() {
|
|
|
|
// Test on-stack from_elem.
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut v = from_elem(2u, 10u);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 2u);
|
|
|
|
assert_eq!(v[0], 10u);
|
|
|
|
assert_eq!(v[1], 10u);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-03-12 17:52:30 -05:00
|
|
|
// Test on-heap from_elem.
|
|
|
|
v = from_elem(6u, 20u);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v[0], 20u);
|
|
|
|
assert_eq!(v[1], 20u);
|
|
|
|
assert_eq!(v[2], 20u);
|
|
|
|
assert_eq!(v[3], 20u);
|
|
|
|
assert_eq!(v[4], 20u);
|
|
|
|
assert_eq!(v[5], 20u);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_empty() {
|
2013-06-08 20:38:47 -05:00
|
|
|
let xs: [int, ..0] = [];
|
|
|
|
assert!(xs.is_empty());
|
|
|
|
assert!(![0].is_empty());
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2013-01-08 02:24:43 -06:00
|
|
|
#[test]
|
|
|
|
fn test_len_divzero() {
|
2013-03-22 20:52:04 -05:00
|
|
|
type Z = [i8, ..0];
|
2013-01-08 02:24:43 -06:00
|
|
|
let v0 : &[Z] = &[];
|
|
|
|
let v1 : &[Z] = &[[]];
|
|
|
|
let v2 : &[Z] = &[[], []];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(sys::size_of::<Z>(), 0);
|
|
|
|
assert_eq!(v0.len(), 0);
|
|
|
|
assert_eq!(v1.len(), 1);
|
|
|
|
assert_eq!(v2.len(), 2);
|
2013-01-08 02:24:43 -06:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn test_head() {
|
2013-03-02 23:49:50 -06:00
|
|
|
let mut a = ~[11];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.head(), &11);
|
2013-03-02 23:49:50 -06:00
|
|
|
a = ~[11, 12];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.head(), &11);
|
2013-03-02 23:49:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
#[ignore(cfg(windows))]
|
|
|
|
fn test_head_empty() {
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
a.head();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_head_opt() {
|
|
|
|
let mut a = ~[];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.head_opt(), None);
|
2013-03-02 23:49:50 -06:00
|
|
|
a = ~[11];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.head_opt().unwrap(), &11);
|
2013-03-02 23:49:50 -06:00
|
|
|
a = ~[11, 12];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.head_opt().unwrap(), &11);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_tail() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut a = ~[11];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.tail(), &[]);
|
2012-06-29 18:26:56 -05:00
|
|
|
a = ~[11, 12];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.tail(), &[12]);
|
2013-03-03 09:22:40 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
#[ignore(cfg(windows))]
|
|
|
|
fn test_tail_empty() {
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
a.tail();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_tailn() {
|
|
|
|
let mut a = ~[11, 12, 13];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.tailn(0), &[11, 12, 13]);
|
2013-03-03 09:22:40 -06:00
|
|
|
a = ~[11, 12, 13];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.tailn(2), &[13]);
|
2013-03-03 09:22:40 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
#[ignore(cfg(windows))]
|
|
|
|
fn test_tailn_empty() {
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
a.tailn(2);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2013-03-03 10:06:31 -06:00
|
|
|
#[test]
|
|
|
|
fn test_init() {
|
|
|
|
let mut a = ~[11];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.init(), &[]);
|
2013-03-03 10:06:31 -06:00
|
|
|
a = ~[11, 12];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.init(), &[11]);
|
2013-03-03 10:06:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[init]
|
|
|
|
#[should_fail]
|
|
|
|
#[ignore(cfg(windows))]
|
|
|
|
fn test_init_empty() {
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
a.init();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_initn() {
|
|
|
|
let mut a = ~[11, 12, 13];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.initn(0), &[11, 12, 13]);
|
2013-03-03 10:06:31 -06:00
|
|
|
a = ~[11, 12, 13];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.initn(2), &[11]);
|
2013-03-03 10:06:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[init]
|
|
|
|
#[should_fail]
|
|
|
|
#[ignore(cfg(windows))]
|
|
|
|
fn test_initn_empty() {
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
a.initn(2);
|
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn test_last() {
|
2013-03-05 21:39:18 -06:00
|
|
|
let mut a = ~[11];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.last(), &11);
|
2013-03-05 21:39:18 -06:00
|
|
|
a = ~[11, 12];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.last(), &12);
|
2013-03-05 21:39:18 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
2013-03-07 00:02:01 -06:00
|
|
|
#[ignore(cfg(windows))]
|
2013-03-05 21:39:18 -06:00
|
|
|
fn test_last_empty() {
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
a.last();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_last_opt() {
|
|
|
|
let mut a = ~[];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.last_opt(), None);
|
2013-03-05 21:39:18 -06:00
|
|
|
a = ~[11];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.last_opt().unwrap(), &11);
|
2013-03-05 21:39:18 -06:00
|
|
|
a = ~[11, 12];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a.last_opt().unwrap(), &12);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_slice() {
|
2013-02-08 13:28:20 -06:00
|
|
|
// Test fixed length vector.
|
|
|
|
let vec_fixed = [1, 2, 3, 4];
|
2013-06-27 04:48:50 -05:00
|
|
|
let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v_a.len(), 3u);
|
|
|
|
assert_eq!(v_a[0], 2);
|
|
|
|
assert_eq!(v_a[1], 3);
|
|
|
|
assert_eq!(v_a[2], 4);
|
2013-02-08 13:28:20 -06:00
|
|
|
|
|
|
|
// Test on stack.
|
|
|
|
let vec_stack = &[1, 2, 3];
|
2013-06-27 04:48:50 -05:00
|
|
|
let v_b = vec_stack.slice(1u, 3u).to_owned();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v_b.len(), 2u);
|
|
|
|
assert_eq!(v_b[0], 2);
|
|
|
|
assert_eq!(v_b[1], 3);
|
2013-02-08 13:28:20 -06:00
|
|
|
|
|
|
|
// Test on managed heap.
|
|
|
|
let vec_managed = @[1, 2, 3, 4, 5];
|
2013-06-27 04:48:50 -05:00
|
|
|
let v_c = vec_managed.slice(0u, 3u).to_owned();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v_c.len(), 3u);
|
|
|
|
assert_eq!(v_c[0], 1);
|
|
|
|
assert_eq!(v_c[1], 2);
|
|
|
|
assert_eq!(v_c[2], 3);
|
2013-02-08 13:28:20 -06:00
|
|
|
|
|
|
|
// Test on exchange heap.
|
|
|
|
let vec_unique = ~[1, 2, 3, 4, 5, 6];
|
2013-06-27 04:48:50 -05:00
|
|
|
let v_d = vec_unique.slice(1u, 6u).to_owned();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v_d.len(), 5u);
|
|
|
|
assert_eq!(v_d[0], 2);
|
|
|
|
assert_eq!(v_d[1], 3);
|
|
|
|
assert_eq!(v_d[2], 4);
|
|
|
|
assert_eq!(v_d[3], 5);
|
|
|
|
assert_eq!(v_d[4], 6);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_pop() {
|
|
|
|
// Test on-heap pop.
|
2013-02-08 13:28:20 -06:00
|
|
|
let mut v = ~[1, 2, 3, 4, 5];
|
|
|
|
let e = v.pop();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 4u);
|
|
|
|
assert_eq!(v[0], 1);
|
|
|
|
assert_eq!(v[1], 2);
|
|
|
|
assert_eq!(v[2], 3);
|
|
|
|
assert_eq!(v[3], 4);
|
|
|
|
assert_eq!(e, 5);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2012-08-22 21:09:34 -05:00
|
|
|
#[test]
|
|
|
|
fn test_swap_remove() {
|
|
|
|
let mut v = ~[1, 2, 3, 4, 5];
|
2012-09-28 00:20:47 -05:00
|
|
|
let mut e = v.swap_remove(0);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 4);
|
|
|
|
assert_eq!(e, 1);
|
|
|
|
assert_eq!(v[0], 5);
|
2012-09-28 00:20:47 -05:00
|
|
|
e = v.swap_remove(3);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 3);
|
|
|
|
assert_eq!(e, 4);
|
|
|
|
assert_eq!(v[0], 5);
|
|
|
|
assert_eq!(v[1], 2);
|
|
|
|
assert_eq!(v[2], 3);
|
2012-08-22 21:09:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_swap_remove_noncopyable() {
|
|
|
|
// Tests that we don't accidentally run destructors twice.
|
2013-05-09 19:36:45 -05:00
|
|
|
let mut v = ~[::unstable::sync::exclusive(()),
|
|
|
|
::unstable::sync::exclusive(()),
|
|
|
|
::unstable::sync::exclusive(())];
|
2012-09-28 00:20:47 -05:00
|
|
|
let mut _e = v.swap_remove(0);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 2);
|
2012-09-28 00:20:47 -05:00
|
|
|
_e = v.swap_remove(1);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 1);
|
2012-09-28 00:20:47 -05:00
|
|
|
_e = v.swap_remove(0);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 0);
|
2012-08-22 21:09:34 -05:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn test_push() {
|
|
|
|
// Test on-stack push().
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut v = ~[];
|
2012-09-26 19:33:34 -05:00
|
|
|
v.push(1);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 1u);
|
|
|
|
assert_eq!(v[0], 1);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
// Test on-heap push().
|
2012-09-26 19:33:34 -05:00
|
|
|
v.push(2);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 2u);
|
|
|
|
assert_eq!(v[0], 1);
|
|
|
|
assert_eq!(v[1], 2);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_grow() {
|
|
|
|
// Test on-stack grow().
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut v = ~[];
|
2012-09-28 00:20:47 -05:00
|
|
|
v.grow(2u, &1);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 2u);
|
|
|
|
assert_eq!(v[0], 1);
|
|
|
|
assert_eq!(v[1], 1);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
// Test on-heap grow().
|
2012-09-28 00:20:47 -05:00
|
|
|
v.grow(3u, &2);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 5u);
|
|
|
|
assert_eq!(v[0], 1);
|
|
|
|
assert_eq!(v[1], 1);
|
|
|
|
assert_eq!(v[2], 2);
|
|
|
|
assert_eq!(v[3], 2);
|
|
|
|
assert_eq!(v[4], 2);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_grow_fn() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut v = ~[];
|
2012-09-28 00:20:47 -05:00
|
|
|
v.grow_fn(3u, square);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 3u);
|
|
|
|
assert_eq!(v[0], 0u);
|
|
|
|
assert_eq!(v[1], 1u);
|
|
|
|
assert_eq!(v[2], 4u);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_grow_set() {
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut v = ~[1, 2, 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v.grow_set(4u, &4, 5);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 5u);
|
|
|
|
assert_eq!(v[0], 1);
|
|
|
|
assert_eq!(v[1], 2);
|
|
|
|
assert_eq!(v[2], 3);
|
|
|
|
assert_eq!(v[3], 4);
|
|
|
|
assert_eq!(v[4], 5);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2012-08-29 03:21:49 -05:00
|
|
|
#[test]
|
|
|
|
fn test_truncate() {
|
|
|
|
let mut v = ~[@6,@5,@4];
|
2012-09-28 00:20:47 -05:00
|
|
|
v.truncate(1);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 1);
|
|
|
|
assert_eq!(*(v[0]), 6);
|
2012-08-29 03:21:49 -05:00
|
|
|
// If the unsafe block didn't drop things properly, we blow up here.
|
|
|
|
}
|
2013-01-24 22:08:16 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_clear() {
|
|
|
|
let mut v = ~[@6,@5,@4];
|
|
|
|
v.clear();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 0);
|
2013-01-24 22:08:16 -06:00
|
|
|
// If the unsafe block didn't drop things properly, we blow up here.
|
|
|
|
}
|
2012-08-29 03:21:49 -05:00
|
|
|
|
2012-09-01 14:11:54 -05:00
|
|
|
#[test]
|
|
|
|
fn test_dedup() {
|
2012-10-02 13:37:37 -05:00
|
|
|
fn case(a: ~[uint], b: ~[uint]) {
|
2012-12-12 17:38:50 -06:00
|
|
|
let mut v = a;
|
2012-09-28 00:20:47 -05:00
|
|
|
v.dedup();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v, b);
|
2012-09-01 14:11:54 -05:00
|
|
|
}
|
|
|
|
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];
|
2012-09-28 00:20:47 -05:00
|
|
|
v0.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
let mut v1 = ~[~1, ~2, ~2, ~3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v1.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
let mut v2 = ~[~1, ~2, ~3, ~3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v2.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
/*
|
|
|
|
* 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];
|
2012-09-28 00:20:47 -05:00
|
|
|
v0.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
let mut v1 = ~[@1, @2, @2, @3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v1.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
let mut v2 = ~[@1, @2, @3, @3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v2.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
/*
|
|
|
|
* If the @pointers were leaked or otherwise misused, valgrind and/or
|
|
|
|
* rustrt should raise errors.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn test_map() {
|
|
|
|
// Test on-stack map.
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut v = ~[1u, 2u, 3u];
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut w = map(v, square_ref);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(w.len(), 3u);
|
|
|
|
assert_eq!(w[0], 1u);
|
|
|
|
assert_eq!(w[1], 4u);
|
|
|
|
assert_eq!(w[2], 9u);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
// Test on-heap map.
|
2012-06-29 18:26:56 -05:00
|
|
|
v = ~[1u, 2u, 3u, 4u, 5u];
|
2012-01-17 19:28:21 -06:00
|
|
|
w = map(v, square_ref);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(w.len(), 5u);
|
|
|
|
assert_eq!(w[0], 1u);
|
|
|
|
assert_eq!(w[1], 4u);
|
|
|
|
assert_eq!(w[2], 9u);
|
|
|
|
assert_eq!(w[3], 16u);
|
|
|
|
assert_eq!(w[4], 25u);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-25 00:38:44 -05:00
|
|
|
fn test_map_zip() {
|
2013-03-09 15:41:43 -06:00
|
|
|
fn times(x: &int, y: &int) -> int { *x * *y }
|
2012-01-17 19:28:21 -06:00
|
|
|
let f = times;
|
2012-06-29 18:26:56 -05:00
|
|
|
let v0 = ~[1, 2, 3, 4, 5];
|
|
|
|
let v1 = ~[5, 4, 3, 2, 1];
|
2013-04-25 00:38:44 -05:00
|
|
|
let u = map_zip::<int, int, int>(v0, v1, f);
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut i = 0;
|
2013-03-28 20:39:09 -05:00
|
|
|
while i < 5 { assert!(v0[i] * v1[i] == u[i]); i += 1; }
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-01-31 19:12:29 -06:00
|
|
|
fn test_filter_mapped() {
|
2012-01-17 19:28:21 -06:00
|
|
|
// Test on-stack filter-map.
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut v = ~[1u, 2u, 3u];
|
2013-01-31 19:12:29 -06:00
|
|
|
let mut w = filter_mapped(v, square_if_odd_r);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(w.len(), 2u);
|
|
|
|
assert_eq!(w[0], 1u);
|
|
|
|
assert_eq!(w[1], 9u);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
// Test on-heap filter-map.
|
2012-06-29 18:26:56 -05:00
|
|
|
v = ~[1u, 2u, 3u, 4u, 5u];
|
2013-01-31 19:12:29 -06:00
|
|
|
w = filter_mapped(v, square_if_odd_r);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(w.len(), 3u);
|
|
|
|
assert_eq!(w[0], 1u);
|
|
|
|
assert_eq!(w[1], 9u);
|
|
|
|
assert_eq!(w[2], 25u);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-09-28 00:20:47 -05:00
|
|
|
fn halve(i: &int) -> Option<int> {
|
|
|
|
if *i % 2 == 0 {
|
2013-03-09 15:41:43 -06:00
|
|
|
Some::<int>(*i / 2)
|
2012-12-27 19:53:04 -06:00
|
|
|
} else {
|
2013-03-09 15:41:43 -06:00
|
|
|
None::<int>
|
2012-12-27 19:53:04 -06:00
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
2013-03-09 15:41:43 -06:00
|
|
|
fn halve_for_sure(i: &int) -> int { *i / 2 }
|
2012-06-29 18:26:56 -05:00
|
|
|
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];
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(filter_mapped(all_even, halve) ==
|
2013-03-06 15:58:02 -06:00
|
|
|
map(all_even, halve_for_sure));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(filter_mapped(all_odd1, halve), ~[]);
|
|
|
|
assert_eq!(filter_mapped(all_odd2, halve), ~[]);
|
|
|
|
assert_eq!(filter_mapped(mix, halve), mix_dest);
|
2013-01-31 19:12:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[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);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(w.len(), 2u);
|
|
|
|
assert_eq!(w[0], 1u);
|
|
|
|
assert_eq!(w[1], 9u);
|
2013-01-31 19:12:29 -06:00
|
|
|
|
|
|
|
// Test on-heap filter-map.
|
|
|
|
v = ~[1u, 2u, 3u, 4u, 5u];
|
|
|
|
w = filter_map(v, square_if_odd_v);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(w.len(), 3u);
|
|
|
|
assert_eq!(w[0], 1u);
|
|
|
|
assert_eq!(w[1], 9u);
|
|
|
|
assert_eq!(w[2], 25u);
|
2013-01-31 19:12:29 -06:00
|
|
|
|
|
|
|
fn halve(i: int) -> Option<int> {
|
|
|
|
if i % 2 == 0 {
|
2013-03-09 15:41:43 -06:00
|
|
|
Some::<int>(i / 2)
|
2013-01-31 19:12:29 -06:00
|
|
|
} else {
|
2013-03-09 15:41:43 -06:00
|
|
|
None::<int>
|
2013-01-31 19:12:29 -06:00
|
|
|
}
|
|
|
|
}
|
2013-03-09 15:41:43 -06:00
|
|
|
fn halve_for_sure(i: &int) -> int { *i / 2 }
|
2013-01-31 19:12:29 -06:00
|
|
|
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];
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(filter_map(all_even, halve) ==
|
2013-03-06 15:58:02 -06:00
|
|
|
map(all_even0, halve_for_sure));
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(filter_map(all_odd1, halve), ~[]);
|
|
|
|
assert_eq!(filter_map(all_odd2, halve), ~[]);
|
|
|
|
assert_eq!(filter_map(mix, halve), mix_dest);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_filter() {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(filter(~[1u, 2u, 3u], is_odd), ~[1u, 3u]);
|
|
|
|
assert_eq!(filter(~[1u, 2u, 4u, 8u, 16u], is_three), ~[]);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2013-01-14 01:10:54 -06:00
|
|
|
#[test]
|
|
|
|
fn test_retain() {
|
|
|
|
let mut v = ~[1, 2, 3, 4, 5];
|
|
|
|
v.retain(is_odd);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v, ~[1, 3, 5]);
|
2013-01-14 01:10:54 -06:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
2012-09-28 00:20:47 -05:00
|
|
|
fn test_each_permutation() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut results: ~[~[int]];
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
results = ~[];
|
2013-06-13 21:06:47 -05:00
|
|
|
for each_permutation([]) |v| { results.push(to_owned(v)); }
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(results, ~[~[]]);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
results = ~[];
|
2013-06-13 21:06:47 -05:00
|
|
|
for each_permutation([7]) |v| { results.push(to_owned(v)); }
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(results, ~[~[7]]);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
results = ~[];
|
2013-06-13 21:06:47 -05:00
|
|
|
for each_permutation([1,1]) |v| { results.push(to_owned(v)); }
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(results, ~[~[1,1],~[1,1]]);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
results = ~[];
|
2013-06-13 21:06:47 -05:00
|
|
|
for each_permutation([5,2,0]) |v| { results.push(to_owned(v)); }
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(results ==
|
2013-03-06 15:58:02 -06:00
|
|
|
~[~[5,2,0],~[5,0,2],~[2,5,0],~[2,0,5],~[0,5,2],~[0,2,5]]);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_zip_unzip() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let v1 = ~[1, 2, 3];
|
|
|
|
let v2 = ~[4, 5, 6];
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-12-12 17:38:50 -06:00
|
|
|
let z1 = zip(v1, v2);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!((1, 4), z1[0]);
|
|
|
|
assert_eq!((2, 5), z1[1]);
|
|
|
|
assert_eq!((3, 6), z1[2]);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-12-12 17:38:50 -06:00
|
|
|
let (left, right) = unzip(z1);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!((1, 4), (left[0], right[0]));
|
|
|
|
assert_eq!((2, 5), (left[1], right[1]));
|
|
|
|
assert_eq!((3, 6), (left[2], right[2]));
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:14:43 -05:00
|
|
|
fn test_position_elem() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert!(position_elem([], &1).is_none());
|
2012-01-26 10:39:45 -06:00
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
let v1 = ~[1, 2, 3, 3, 2, 5];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(position_elem(v1, &1), Some(0u));
|
|
|
|
assert_eq!(position_elem(v1, &2), Some(1u));
|
|
|
|
assert_eq!(position_elem(v1, &5), Some(5u));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(position_elem(v1, &4).is_none());
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:19:41 -05:00
|
|
|
fn test_position_between() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert!(position_between([], 0u, 0u, f).is_none());
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
2013-05-12 19:34:15 -05:00
|
|
|
let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(position_between(v, 0u, 0u, f).is_none());
|
|
|
|
assert!(position_between(v, 0u, 1u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(position_between(v, 0u, 2u, f), Some(1u));
|
|
|
|
assert_eq!(position_between(v, 0u, 3u, f), Some(1u));
|
|
|
|
assert_eq!(position_between(v, 0u, 4u, f), Some(1u));
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(position_between(v, 1u, 1u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(position_between(v, 1u, 2u, f), Some(1u));
|
|
|
|
assert_eq!(position_between(v, 1u, 3u, f), Some(1u));
|
|
|
|
assert_eq!(position_between(v, 1u, 4u, f), Some(1u));
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(position_between(v, 2u, 2u, f).is_none());
|
|
|
|
assert!(position_between(v, 2u, 3u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(position_between(v, 2u, 4u, f), Some(3u));
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(position_between(v, 3u, 3u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(position_between(v, 3u, 4u, f), Some(3u));
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(position_between(v, 4u, 4u, f).is_none());
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
|
|
|
|
2012-01-26 20:14:27 -06:00
|
|
|
#[test]
|
2012-03-18 19:19:41 -05:00
|
|
|
fn test_find_between() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert!(find_between([], 0u, 0u, f).is_none());
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
2013-05-12 19:34:15 -05:00
|
|
|
let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(find_between(v, 0u, 0u, f).is_none());
|
|
|
|
assert!(find_between(v, 0u, 1u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(find_between(v, 0u, 2u, f), Some((1, 'b')));
|
|
|
|
assert_eq!(find_between(v, 0u, 3u, f), Some((1, 'b')));
|
|
|
|
assert_eq!(find_between(v, 0u, 4u, f), Some((1, 'b')));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(find_between(v, 1u, 1u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(find_between(v, 1u, 2u, f), Some((1, 'b')));
|
|
|
|
assert_eq!(find_between(v, 1u, 3u, f), Some((1, 'b')));
|
|
|
|
assert_eq!(find_between(v, 1u, 4u, f), Some((1, 'b')));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(find_between(v, 2u, 2u, f).is_none());
|
|
|
|
assert!(find_between(v, 2u, 3u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(find_between(v, 2u, 4u, f), Some((3, 'b')));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(find_between(v, 3u, 3u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(find_between(v, 3u, 4u, f), Some((3, 'b')));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(find_between(v, 4u, 4u, f).is_none());
|
2012-01-26 20:14:27 -06:00
|
|
|
}
|
|
|
|
|
2012-01-26 10:42:50 -06:00
|
|
|
#[test]
|
|
|
|
fn test_rposition() {
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
|
|
|
fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
|
2013-05-12 19:34:15 -05:00
|
|
|
let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-06-18 21:59:48 -05:00
|
|
|
assert_eq!(rposition(v, f), Some(3u));
|
|
|
|
assert!(rposition(v, g).is_none());
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:19:41 -05:00
|
|
|
fn test_rposition_between() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert!(rposition_between([], 0u, 0u, f).is_none());
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
2013-05-12 19:34:15 -05:00
|
|
|
let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rposition_between(v, 0u, 0u, f).is_none());
|
|
|
|
assert!(rposition_between(v, 0u, 1u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rposition_between(v, 0u, 2u, f), Some(1u));
|
|
|
|
assert_eq!(rposition_between(v, 0u, 3u, f), Some(1u));
|
|
|
|
assert_eq!(rposition_between(v, 0u, 4u, f), Some(3u));
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rposition_between(v, 1u, 1u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rposition_between(v, 1u, 2u, f), Some(1u));
|
|
|
|
assert_eq!(rposition_between(v, 1u, 3u, f), Some(1u));
|
|
|
|
assert_eq!(rposition_between(v, 1u, 4u, f), Some(3u));
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rposition_between(v, 2u, 2u, f).is_none());
|
|
|
|
assert!(rposition_between(v, 2u, 3u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rposition_between(v, 2u, 4u, f), Some(3u));
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rposition_between(v, 3u, 3u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rposition_between(v, 3u, 4u, f), Some(3u));
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rposition_between(v, 4u, 4u, f).is_none());
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
2012-01-26 20:14:27 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rfind() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert!(rfind([], f).is_none());
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
|
|
|
fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
|
2013-05-12 19:34:15 -05:00
|
|
|
let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rfind(v, f), Some((3, 'b')));
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rfind(v, g).is_none());
|
2012-01-26 20:14:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:19:41 -05:00
|
|
|
fn test_rfind_between() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert!(rfind_between([], 0u, 0u, f).is_none());
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
2013-05-12 19:34:15 -05:00
|
|
|
let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rfind_between(v, 0u, 0u, f).is_none());
|
|
|
|
assert!(rfind_between(v, 0u, 1u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rfind_between(v, 0u, 2u, f), Some((1, 'b')));
|
|
|
|
assert_eq!(rfind_between(v, 0u, 3u, f), Some((1, 'b')));
|
|
|
|
assert_eq!(rfind_between(v, 0u, 4u, f), Some((3, 'b')));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rfind_between(v, 1u, 1u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rfind_between(v, 1u, 2u, f), Some((1, 'b')));
|
|
|
|
assert_eq!(rfind_between(v, 1u, 3u, f), Some((1, 'b')));
|
|
|
|
assert_eq!(rfind_between(v, 1u, 4u, f), Some((3, 'b')));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rfind_between(v, 2u, 2u, f).is_none());
|
|
|
|
assert!(rfind_between(v, 2u, 3u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rfind_between(v, 2u, 4u, f), Some((3, 'b')));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rfind_between(v, 3u, 3u, f).is_none());
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(rfind_between(v, 3u, 4u, f), Some((3, 'b')));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!(rfind_between(v, 4u, 4u, f).is_none());
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2013-01-04 15:52:18 -06:00
|
|
|
#[test]
|
|
|
|
fn test_bsearch_elem() {
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(bsearch_elem([1,2,3,4,5], &5), Some(4));
|
|
|
|
assert_eq!(bsearch_elem([1,2,3,4,5], &4), Some(3));
|
|
|
|
assert_eq!(bsearch_elem([1,2,3,4,5], &3), Some(2));
|
|
|
|
assert_eq!(bsearch_elem([1,2,3,4,5], &2), Some(1));
|
|
|
|
assert_eq!(bsearch_elem([1,2,3,4,5], &1), Some(0));
|
|
|
|
|
|
|
|
assert_eq!(bsearch_elem([2,4,6,8,10], &1), None);
|
|
|
|
assert_eq!(bsearch_elem([2,4,6,8,10], &5), None);
|
|
|
|
assert_eq!(bsearch_elem([2,4,6,8,10], &4), Some(1));
|
|
|
|
assert_eq!(bsearch_elem([2,4,6,8,10], &10), Some(4));
|
|
|
|
|
|
|
|
assert_eq!(bsearch_elem([2,4,6,8], &1), None);
|
|
|
|
assert_eq!(bsearch_elem([2,4,6,8], &5), None);
|
|
|
|
assert_eq!(bsearch_elem([2,4,6,8], &4), Some(1));
|
|
|
|
assert_eq!(bsearch_elem([2,4,6,8], &8), Some(3));
|
|
|
|
|
|
|
|
assert_eq!(bsearch_elem([2,4,6], &1), None);
|
|
|
|
assert_eq!(bsearch_elem([2,4,6], &5), None);
|
|
|
|
assert_eq!(bsearch_elem([2,4,6], &4), Some(1));
|
|
|
|
assert_eq!(bsearch_elem([2,4,6], &6), Some(2));
|
|
|
|
|
|
|
|
assert_eq!(bsearch_elem([2,4], &1), None);
|
|
|
|
assert_eq!(bsearch_elem([2,4], &5), None);
|
|
|
|
assert_eq!(bsearch_elem([2,4], &2), Some(0));
|
|
|
|
assert_eq!(bsearch_elem([2,4], &4), Some(1));
|
|
|
|
|
|
|
|
assert_eq!(bsearch_elem([2], &1), None);
|
|
|
|
assert_eq!(bsearch_elem([2], &5), None);
|
|
|
|
assert_eq!(bsearch_elem([2], &2), Some(0));
|
|
|
|
|
|
|
|
assert_eq!(bsearch_elem([], &1), None);
|
|
|
|
assert_eq!(bsearch_elem([], &5), None);
|
2013-01-08 10:44:31 -06:00
|
|
|
|
|
|
|
assert!(bsearch_elem([1,1,1,1,1], &1) != None);
|
|
|
|
assert!(bsearch_elem([1,1,1,1,2], &1) != None);
|
|
|
|
assert!(bsearch_elem([1,1,1,2,2], &1) != None);
|
|
|
|
assert!(bsearch_elem([1,1,2,2,2], &1) != None);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(bsearch_elem([1,2,2,2,2], &1), Some(0));
|
2013-01-08 10:44:31 -06:00
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(bsearch_elem([1,2,3,4,5], &6), None);
|
|
|
|
assert_eq!(bsearch_elem([1,2,3,4,5], &0), None);
|
2013-01-04 15:52:18 -06:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn reverse_and_reversed() {
|
2013-02-12 17:34:48 -06:00
|
|
|
let mut v: ~[int] = ~[10, 20];
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v[0], 10);
|
|
|
|
assert_eq!(v[1], 20);
|
2012-01-17 19:28:21 -06:00
|
|
|
reverse(v);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v[0], 20);
|
|
|
|
assert_eq!(v[1], 10);
|
2013-05-23 11:39:17 -05:00
|
|
|
let v2 = reversed::<int>([10, 20]);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v2[0], 20);
|
|
|
|
assert_eq!(v2[1], 10);
|
2012-01-17 19:28:21 -06:00
|
|
|
v[0] = 30;
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v2[0], 20);
|
2012-01-17 19:28:21 -06:00
|
|
|
// Make sure they work with 0-length vectors too.
|
|
|
|
|
2013-05-23 11:39:17 -05:00
|
|
|
let v4 = reversed::<int>([]);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v4, ~[]);
|
2013-02-12 17:34:48 -06:00
|
|
|
let mut v3: ~[int] = ~[];
|
2012-01-17 19:28:21 -06:00
|
|
|
reverse::<int>(v3);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn reversed_mut() {
|
2013-05-23 11:39:17 -05:00
|
|
|
let v2 = reversed::<int>([10, 20]);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v2[0], 20);
|
|
|
|
assert_eq!(v2[1], 10);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2012-01-26 20:13:43 -06:00
|
|
|
#[test]
|
|
|
|
fn test_split() {
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(x: &int) -> bool { *x == 3 }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2013-05-23 11:39:17 -05:00
|
|
|
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]]);
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_splitn() {
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(x: &int) -> bool { *x == 3 }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2013-05-23 11:39:17 -05:00
|
|
|
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) ==
|
2013-03-06 15:58:02 -06:00
|
|
|
~[~[1, 2], ~[4, 3, 5]]);
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rsplit() {
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(x: &int) -> bool { *x == 3 }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2013-05-23 11:39:17 -05:00
|
|
|
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) ==
|
2013-03-06 21:09:17 -06:00
|
|
|
~[~[1, 2], ~[4], ~[5]]);
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rsplitn() {
|
2012-09-28 00:20:47 -05:00
|
|
|
fn f(x: &int) -> bool { *x == 3 }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2013-05-23 11:39:17 -05:00
|
|
|
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]]);
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
2013-01-07 10:49:41 -06:00
|
|
|
#[test]
|
|
|
|
fn test_partition() {
|
2013-06-27 09:10:18 -05:00
|
|
|
assert_eq!((~[]).partition(|x: &int| *x < 3), (~[], ~[]));
|
|
|
|
assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
|
|
|
|
assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 2), (~[1], ~[2, 3]));
|
|
|
|
assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
|
2013-01-07 10:49:41 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_partitioned() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert_eq!(([]).partitioned(|x: &int| *x < 3), (~[], ~[]))
|
|
|
|
assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
|
|
|
|
assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (~[1], ~[2, 3]));
|
|
|
|
assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
|
2013-01-07 10:49:41 -06:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn test_concat() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert_eq!(concat([~[1], ~[2,3]]), ~[1, 2, 3]);
|
2013-06-14 21:56:41 -05:00
|
|
|
assert_eq!([~[1], ~[2,3]].concat_vec(), ~[1, 2, 3]);
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
|
|
assert_eq!(concat_slices([&[1], &[2,3]]), ~[1, 2, 3]);
|
2013-06-14 21:56:41 -05:00
|
|
|
assert_eq!([&[1], &[2,3]].concat_vec(), ~[1, 2, 3]);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2012-01-28 17:41:53 -06:00
|
|
|
#[test]
|
|
|
|
fn test_connect() {
|
2013-05-23 11:39:17 -05:00
|
|
|
assert_eq!(connect([], &0), ~[]);
|
|
|
|
assert_eq!(connect([~[1], ~[2, 3]], &0), ~[1, 0, 2, 3]);
|
|
|
|
assert_eq!(connect([~[1], ~[2], ~[3]], &0), ~[1, 0, 2, 0, 3]);
|
2013-06-14 21:56:41 -05:00
|
|
|
assert_eq!([~[1], ~[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
|
|
|
|
assert_eq!([~[1], ~[2], ~[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
|
|
assert_eq!(connect_slices([], &0), ~[]);
|
|
|
|
assert_eq!(connect_slices([&[1], &[2, 3]], &0), ~[1, 0, 2, 3]);
|
|
|
|
assert_eq!(connect_slices([&[1], &[2], &[3]], &0), ~[1, 0, 2, 0, 3]);
|
2013-06-14 21:56:41 -05:00
|
|
|
assert_eq!([&[1], &[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
|
|
|
|
assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
|
2012-01-28 17:41:53 -06:00
|
|
|
}
|
|
|
|
|
2012-01-23 04:41:40 -06:00
|
|
|
#[test]
|
|
|
|
fn test_windowed () {
|
2013-04-16 08:00:16 -05:00
|
|
|
fn t(n: uint, expected: &[&[int]]) {
|
|
|
|
let mut i = 0;
|
2013-05-23 11:39:17 -05:00
|
|
|
for windowed(n, [1,2,3,4,5,6]) |v| {
|
2013-04-16 08:00:16 -05:00
|
|
|
assert_eq!(v, expected[i]);
|
|
|
|
i += 1;
|
|
|
|
}
|
2012-01-23 04:41:40 -06:00
|
|
|
|
2013-04-16 08:00:16 -05:00
|
|
|
// 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, &[]);
|
2013-04-19 20:44:32 -05:00
|
|
|
t(8, &[]);
|
2012-01-23 04:41:40 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
2012-06-07 23:38:25 -05:00
|
|
|
#[ignore(cfg(windows))]
|
2012-01-23 04:41:40 -06:00
|
|
|
fn test_windowed_() {
|
2013-05-23 11:39:17 -05:00
|
|
|
for windowed (0u, [1u,2u,3u,4u,5u,6u]) |_v| {}
|
2012-01-23 04:41:40 -06:00
|
|
|
}
|
2012-03-01 01:44:52 -06:00
|
|
|
|
2012-06-22 18:31:57 -05:00
|
|
|
#[test]
|
|
|
|
fn test_unshift() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut x = ~[1, 2, 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
x.unshift(0);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(x, ~[0, 1, 2, 3]);
|
2012-06-22 18:31:57 -05:00
|
|
|
}
|
|
|
|
|
2012-11-25 07:28:16 -06:00
|
|
|
#[test]
|
|
|
|
fn test_insert() {
|
|
|
|
let mut a = ~[1, 2, 4];
|
|
|
|
a.insert(2, 3);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a, ~[1, 2, 3, 4]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
|
|
|
let mut a = ~[1, 2, 3];
|
|
|
|
a.insert(0, 0);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a, ~[0, 1, 2, 3]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
|
|
|
let mut a = ~[1, 2, 3];
|
|
|
|
a.insert(3, 4);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a, ~[1, 2, 3, 4]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
|
|
|
let mut a = ~[];
|
|
|
|
a.insert(0, 1);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a, ~[1]);
|
2012-11-25 07:28:16 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-11-26 16:48:48 -06:00
|
|
|
#[ignore(cfg(windows))]
|
2012-11-25 07:28:16 -06:00
|
|
|
#[should_fail]
|
|
|
|
fn test_insert_oob() {
|
|
|
|
let mut a = ~[1, 2, 3];
|
|
|
|
a.insert(4, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_remove() {
|
|
|
|
let mut a = ~[1, 2, 3, 4];
|
|
|
|
a.remove(2);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a, ~[1, 2, 4]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
|
|
|
let mut a = ~[1, 2, 3];
|
|
|
|
a.remove(0);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a, ~[2, 3]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
|
|
|
let mut a = ~[1];
|
|
|
|
a.remove(0);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(a, ~[]);
|
2012-11-25 07:28:16 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-11-26 16:48:48 -06:00
|
|
|
#[ignore(cfg(windows))]
|
2012-11-25 07:28:16 -06:00
|
|
|
#[should_fail]
|
|
|
|
fn test_remove_oob() {
|
|
|
|
let mut a = ~[1, 2, 3];
|
|
|
|
a.remove(3);
|
|
|
|
}
|
|
|
|
|
2012-03-29 01:10:58 -05:00
|
|
|
#[test]
|
|
|
|
fn test_capacity() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut v = ~[0u64];
|
2013-06-27 09:40:47 -05:00
|
|
|
v.reserve(10u);
|
|
|
|
assert_eq!(v.capacity(), 10u);
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut v = ~[0u32];
|
2013-06-27 09:40:47 -05:00
|
|
|
v.reserve(10u);
|
|
|
|
assert_eq!(v.capacity(), 10u);
|
2012-03-29 01:10:58 -05:00
|
|
|
}
|
2012-05-18 18:55:22 -05:00
|
|
|
|
|
|
|
#[test]
|
2013-03-21 06:36:21 -05:00
|
|
|
fn test_slice_2() {
|
2012-06-29 18:26:56 -05:00
|
|
|
let v = ~[1, 2, 3, 4, 5];
|
2013-03-21 06:36:21 -05:00
|
|
|
let v = v.slice(1u, 3u);
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v.len(), 2u);
|
|
|
|
assert_eq!(v[0], 2);
|
|
|
|
assert_eq!(v[1], 3);
|
2012-05-18 18:55:22 -05:00
|
|
|
}
|
2012-09-27 18:41:38 -05:00
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[ignore(windows)]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_from_fn_fail() {
|
|
|
|
do from_fn(100) |v| {
|
2013-02-11 21:26:38 -06:00
|
|
|
if v == 50 { fail!() }
|
2012-09-27 18:41:38 -05:00
|
|
|
(~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));
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!();
|
2012-09-27 18:41:38 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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;
|
2012-12-12 17:38:50 -06:00
|
|
|
do consume(v) |_i, _elt| {
|
2012-09-27 18:41:38 -05:00
|
|
|
if i == 2 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
i += 1;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[ignore(windows)]
|
|
|
|
#[should_fail]
|
2012-09-28 15:00:07 -05:00
|
|
|
#[allow(non_implicitly_copyable_typarams)]
|
2012-09-27 18:41:38 -05:00
|
|
|
fn test_grow_fn_fail() {
|
|
|
|
let mut v = ~[];
|
2012-09-28 00:20:47 -05:00
|
|
|
do v.grow_fn(100) |i| {
|
2012-09-27 18:41:38 -05:00
|
|
|
if i == 50 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
(~0, @0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[ignore(windows)]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_map_fail() {
|
2013-05-12 19:34:15 -05:00
|
|
|
let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
|
2012-09-27 18:41:38 -05:00
|
|
|
let mut i = 0;
|
|
|
|
do map(v) |_elt| {
|
|
|
|
if i == 2 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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;
|
2012-12-12 17:38:50 -06:00
|
|
|
do map_consume(v) |_elt| {
|
2012-09-27 18:41:38 -05:00
|
|
|
if i == 2 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
i += 0;
|
|
|
|
~[(~0, @0)]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[ignore(windows)]
|
|
|
|
#[should_fail]
|
|
|
|
#[allow(non_implicitly_copyable_typarams)]
|
2013-04-25 00:38:44 -05:00
|
|
|
fn test_map_zip_fail() {
|
2012-09-27 18:41:38 -05:00
|
|
|
let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
|
|
|
|
let mut i = 0;
|
2013-04-25 00:38:44 -05:00
|
|
|
do map_zip(v, v) |_elt1, _elt2| {
|
2012-09-27 18:41:38 -05:00
|
|
|
if i == 2 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
i += 0;
|
|
|
|
~[(~0, @0)]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[ignore(windows)]
|
|
|
|
#[should_fail]
|
|
|
|
#[allow(non_implicitly_copyable_typarams)]
|
2013-01-31 19:12:29 -06:00
|
|
|
fn test_filter_mapped_fail() {
|
2012-09-27 18:41:38 -05:00
|
|
|
let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
|
|
|
|
let mut i = 0;
|
2013-01-31 19:12:29 -06:00
|
|
|
do filter_mapped(v) |_elt| {
|
2012-09-27 18:41:38 -05:00
|
|
|
if i == 2 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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;
|
2013-01-07 23:15:25 -06:00
|
|
|
do v.filtered |_elt| {
|
2012-09-27 18:41:38 -05:00
|
|
|
if i == 2 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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;
|
|
|
|
do rposition(v) |_elt| {
|
|
|
|
if i == 2 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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;
|
2012-09-28 00:20:47 -05:00
|
|
|
for each_permutation(v) |_elt| {
|
2012-09-27 18:41:38 -05:00
|
|
|
if i == 2 {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
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| {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-01-09 10:16:31 -06:00
|
|
|
#[ignore(cfg(windows))]
|
2012-09-27 18:41:38 -05:00
|
|
|
#[should_fail]
|
|
|
|
fn test_as_mut_buf_fail() {
|
2013-02-12 17:34:48 -06:00
|
|
|
let mut v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
|
2012-09-27 18:41:38 -05:00
|
|
|
do as_mut_buf(v) |_buf, _i| {
|
2013-02-11 21:26:38 -06:00
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
}
|
2013-01-05 04:52:37 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
2013-01-09 10:16:31 -06:00
|
|
|
#[ignore(cfg(windows))]
|
2013-01-23 13:43:58 -06:00
|
|
|
fn test_copy_memory_oob() {
|
|
|
|
unsafe {
|
2013-02-12 17:34:48 -06:00
|
|
|
let mut a = [1, 2, 3, 4];
|
2013-01-23 13:43:58 -06:00
|
|
|
let b = [1, 2, 3, 4, 5];
|
|
|
|
raw::copy_memory(a, b, 5);
|
|
|
|
}
|
2013-01-05 04:52:37 -06:00
|
|
|
}
|
|
|
|
|
2013-03-01 21:07:12 -06:00
|
|
|
#[test]
|
|
|
|
fn test_total_ord() {
|
|
|
|
[1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater;
|
|
|
|
[1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less;
|
|
|
|
[1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal;
|
|
|
|
[1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
|
|
|
|
[2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
|
|
|
|
}
|
2013-04-17 18:34:53 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_iterator() {
|
|
|
|
use iterator::*;
|
|
|
|
let xs = [1, 2, 5, 10, 11];
|
|
|
|
let mut it = xs.iter();
|
2013-06-21 05:12:01 -05:00
|
|
|
assert_eq!(it.size_hint(), (Some(5), Some(5)));
|
|
|
|
assert_eq!(it.next().unwrap(), &1);
|
|
|
|
assert_eq!(it.size_hint(), (Some(4), Some(4)));
|
|
|
|
assert_eq!(it.next().unwrap(), &2);
|
|
|
|
assert_eq!(it.size_hint(), (Some(3), Some(3)));
|
|
|
|
assert_eq!(it.next().unwrap(), &5);
|
|
|
|
assert_eq!(it.size_hint(), (Some(2), Some(2)));
|
|
|
|
assert_eq!(it.next().unwrap(), &10);
|
|
|
|
assert_eq!(it.size_hint(), (Some(1), Some(1)));
|
|
|
|
assert_eq!(it.next().unwrap(), &11);
|
|
|
|
assert_eq!(it.size_hint(), (Some(0), Some(0)));
|
|
|
|
assert!(it.next().is_none());
|
2013-04-17 18:34:53 -05:00
|
|
|
}
|
2013-05-11 17:56:08 -05:00
|
|
|
|
2013-06-06 00:12:39 -05:00
|
|
|
#[test]
|
|
|
|
fn test_mut_iterator() {
|
|
|
|
use iterator::*;
|
|
|
|
let mut xs = [1, 2, 3, 4, 5];
|
|
|
|
for xs.mut_iter().advance |x| {
|
|
|
|
*x += 1;
|
|
|
|
}
|
|
|
|
assert_eq!(xs, [2, 3, 4, 5, 6])
|
|
|
|
}
|
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
#[test]
|
|
|
|
fn test_rev_iterator() {
|
|
|
|
use iterator::*;
|
|
|
|
|
|
|
|
let xs = [1, 2, 5, 10, 11];
|
|
|
|
let ys = [11, 10, 5, 2, 1];
|
|
|
|
let mut i = 0;
|
|
|
|
for xs.rev_iter().advance |&x| {
|
|
|
|
assert_eq!(x, ys[i]);
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
assert_eq!(i, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mut_rev_iterator() {
|
|
|
|
use iterator::*;
|
2013-06-07 23:07:55 -05:00
|
|
|
let mut xs = [1u, 2, 3, 4, 5];
|
2013-06-07 21:39:52 -05:00
|
|
|
for xs.mut_rev_iter().enumerate().advance |(i,x)| {
|
|
|
|
*x += i;
|
|
|
|
}
|
|
|
|
assert_eq!(xs, [5, 5, 5, 5, 5])
|
|
|
|
}
|
|
|
|
|
2013-06-18 01:52:14 -05:00
|
|
|
#[test]
|
|
|
|
fn test_move_from() {
|
|
|
|
let mut a = [1,2,3,4,5];
|
|
|
|
let b = ~[6,7,8];
|
|
|
|
assert_eq!(a.move_from(b, 0, 3), 3);
|
|
|
|
assert_eq!(a, [6,7,8,4,5]);
|
|
|
|
let mut a = [7,2,8,1];
|
|
|
|
let b = ~[3,1,4,1,5,9];
|
|
|
|
assert_eq!(a.move_from(b, 0, 6), 4);
|
|
|
|
assert_eq!(a, [3,1,4,1]);
|
|
|
|
let mut a = [1,2,3,4];
|
|
|
|
let b = ~[5,6,7,8,9,0];
|
|
|
|
assert_eq!(a.move_from(b, 2, 3), 1);
|
|
|
|
assert_eq!(a, [7,2,3,4]);
|
|
|
|
let mut a = [1,2,3,4,5];
|
|
|
|
let b = ~[5,6,7,8,9,0];
|
|
|
|
assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2);
|
|
|
|
assert_eq!(a, [1,2,6,7,5]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_copy_from() {
|
|
|
|
let mut a = [1,2,3,4,5];
|
|
|
|
let b = [6,7,8];
|
|
|
|
assert_eq!(a.copy_from(b), 3);
|
|
|
|
assert_eq!(a, [6,7,8,4,5]);
|
|
|
|
let mut c = [7,2,8,1];
|
|
|
|
let d = [3,1,4,1,5,9];
|
|
|
|
assert_eq!(c.copy_from(d), 4);
|
|
|
|
assert_eq!(c, [3,1,4,1]);
|
|
|
|
}
|
|
|
|
|
2013-02-13 17:52:58 -06:00
|
|
|
#[test]
|
|
|
|
fn test_reverse_part() {
|
|
|
|
let mut values = [1,2,3,4,5];
|
2013-06-26 18:37:19 -05:00
|
|
|
reverse(values.mut_slice(1, 4));
|
2013-05-15 19:35:43 -05:00
|
|
|
assert_eq!(values, [1,4,3,2,5]);
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_permutations0() {
|
|
|
|
let values = [];
|
|
|
|
let mut v : ~[~[int]] = ~[];
|
|
|
|
for each_permutation(values) |p| {
|
2013-05-15 19:35:43 -05:00
|
|
|
v.push(p.to_owned());
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
2013-05-15 19:35:43 -05:00
|
|
|
assert_eq!(v, ~[~[]]);
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_permutations1() {
|
|
|
|
let values = [1];
|
|
|
|
let mut v : ~[~[int]] = ~[];
|
|
|
|
for each_permutation(values) |p| {
|
2013-05-15 19:35:43 -05:00
|
|
|
v.push(p.to_owned());
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
2013-05-15 19:35:43 -05:00
|
|
|
assert_eq!(v, ~[~[1]]);
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_permutations2() {
|
|
|
|
let values = [1,2];
|
|
|
|
let mut v : ~[~[int]] = ~[];
|
|
|
|
for each_permutation(values) |p| {
|
2013-05-15 19:35:43 -05:00
|
|
|
v.push(p.to_owned());
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
2013-05-15 19:35:43 -05:00
|
|
|
assert_eq!(v, ~[~[1,2],~[2,1]]);
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_permutations3() {
|
|
|
|
let values = [1,2,3];
|
|
|
|
let mut v : ~[~[int]] = ~[];
|
|
|
|
for each_permutation(values) |p| {
|
2013-05-15 19:35:43 -05:00
|
|
|
v.push(p.to_owned());
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
2013-05-15 19:35:43 -05:00
|
|
|
assert_eq!(v, ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]]);
|
2013-02-13 17:52:58 -06:00
|
|
|
}
|
2013-06-17 02:05:51 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_vec_zero() {
|
|
|
|
use num::Zero;
|
|
|
|
macro_rules! t (
|
2013-06-27 10:45:24 -05:00
|
|
|
($ty:ty) => {{
|
2013-06-17 02:05:51 -05:00
|
|
|
let v: $ty = Zero::zero();
|
|
|
|
assert!(v.is_empty());
|
|
|
|
assert!(v.is_zero());
|
2013-06-27 10:45:24 -05:00
|
|
|
}}
|
2013-06-17 02:05:51 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
t!(&[int]);
|
|
|
|
t!(@[int]);
|
|
|
|
t!(~[int]);
|
|
|
|
}
|
2013-06-18 01:20:53 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_bytes_set_memory() {
|
|
|
|
use vec::bytes::MutableByteVector;
|
|
|
|
let mut values = [1u8,2,3,4,5];
|
|
|
|
values.mut_slice(0,5).set_memory(0xAB);
|
|
|
|
assert_eq!(values, [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
|
|
|
|
values.mut_slice(2,4).set_memory(0xFF);
|
|
|
|
assert_eq!(values, [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
|
|
|
|
}
|
2013-04-18 07:15:40 -05:00
|
|
|
}
|