2012-03-15 20:58:14 -05:00
|
|
|
#[doc = "Vectors"];
|
|
|
|
|
2011-12-13 18:25:51 -06:00
|
|
|
import option::{some, none};
|
|
|
|
import ptr::addr_of;
|
2012-06-04 19:26:17 -05:00
|
|
|
import libc::size_t;
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-06-13 18:14:01 -05:00
|
|
|
export append;
|
2012-06-28 15:52:13 -05:00
|
|
|
export append_one;
|
2012-03-10 02:04:09 -06:00
|
|
|
export init_op;
|
|
|
|
export is_empty;
|
|
|
|
export is_not_empty;
|
|
|
|
export same_length;
|
|
|
|
export reserve;
|
2012-03-29 00:49:28 -05:00
|
|
|
export reserve_at_least;
|
2012-03-29 01:10:58 -05:00
|
|
|
export capacity;
|
2012-03-10 02:04:09 -06:00
|
|
|
export len;
|
2012-03-12 17:52:30 -05:00
|
|
|
export from_fn;
|
|
|
|
export from_elem;
|
2012-03-10 02:04:09 -06:00
|
|
|
export to_mut;
|
|
|
|
export from_mut;
|
|
|
|
export head;
|
|
|
|
export tail;
|
2012-03-10 02:44:13 -06:00
|
|
|
export tailn;
|
2012-03-10 02:04:09 -06:00
|
|
|
export init;
|
|
|
|
export last;
|
|
|
|
export last_opt;
|
|
|
|
export slice;
|
2012-05-18 18:55:22 -05:00
|
|
|
export view;
|
2012-03-10 02:04:09 -06:00
|
|
|
export split;
|
|
|
|
export splitn;
|
|
|
|
export rsplit;
|
|
|
|
export rsplitn;
|
|
|
|
export shift;
|
|
|
|
export pop;
|
2012-06-27 17:21:50 -05:00
|
|
|
export push, push_all, push_all_move;
|
2012-03-10 02:04:09 -06:00
|
|
|
export grow;
|
|
|
|
export grow_fn;
|
|
|
|
export grow_set;
|
|
|
|
export map;
|
2012-05-18 12:40:54 -05:00
|
|
|
export mapi;
|
2012-03-10 02:04:09 -06:00
|
|
|
export map2;
|
2012-03-13 09:55:45 -05:00
|
|
|
export flat_map;
|
2012-03-10 02:04:09 -06:00
|
|
|
export filter_map;
|
|
|
|
export filter;
|
|
|
|
export concat;
|
|
|
|
export connect;
|
|
|
|
export foldl;
|
|
|
|
export foldr;
|
|
|
|
export any;
|
|
|
|
export any2;
|
|
|
|
export all;
|
2012-05-17 14:01:45 -05:00
|
|
|
export alli;
|
2012-03-10 02:04:09 -06:00
|
|
|
export all2;
|
|
|
|
export contains;
|
|
|
|
export count;
|
|
|
|
export find;
|
2012-03-18 19:19:41 -05:00
|
|
|
export find_between;
|
2012-03-10 02:04:09 -06:00
|
|
|
export rfind;
|
2012-03-18 19:19:41 -05:00
|
|
|
export rfind_between;
|
2012-03-18 19:14:43 -05:00
|
|
|
export position_elem;
|
2012-03-10 02:04:09 -06:00
|
|
|
export position;
|
2012-03-18 19:19:41 -05:00
|
|
|
export position_between;
|
2012-03-18 19:14:43 -05:00
|
|
|
export position_elem;
|
2012-03-10 02:04:09 -06:00
|
|
|
export rposition;
|
2012-03-18 19:19:41 -05:00
|
|
|
export rposition_between;
|
2012-03-10 02:04:09 -06:00
|
|
|
export unzip;
|
|
|
|
export zip;
|
|
|
|
export swap;
|
|
|
|
export reverse;
|
|
|
|
export reversed;
|
2012-04-06 13:01:43 -05:00
|
|
|
export iter, iter_between, each, eachi;
|
2012-03-10 02:04:09 -06:00
|
|
|
export iter2;
|
|
|
|
export iteri;
|
|
|
|
export riter;
|
|
|
|
export riteri;
|
|
|
|
export permute;
|
|
|
|
export windowed;
|
|
|
|
export as_buf;
|
|
|
|
export as_mut_buf;
|
2012-04-20 19:37:17 -05:00
|
|
|
export unpack_slice;
|
2012-06-02 21:03:28 -05:00
|
|
|
export unpack_const_slice;
|
2012-03-10 02:04:09 -06:00
|
|
|
export unsafe;
|
|
|
|
export u8;
|
2012-03-17 20:02:45 -05:00
|
|
|
export extensions;
|
2012-03-10 02:04:09 -06:00
|
|
|
|
2011-12-13 18:25:51 -06:00
|
|
|
#[abi = "cdecl"]
|
|
|
|
native mod rustrt {
|
2012-06-01 21:47:04 -05:00
|
|
|
fn vec_reserve_shared(++t: *sys::type_desc,
|
|
|
|
++v: **unsafe::vec_repr,
|
|
|
|
++n: libc::size_t);
|
|
|
|
fn vec_from_buf_shared(++t: *sys::type_desc,
|
|
|
|
++ptr: *(),
|
|
|
|
++count: libc::size_t) -> *unsafe::vec_repr;
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-06-14 13:38:45 -05:00
|
|
|
#[abi = "rust-intrinsic"]
|
|
|
|
native mod rusti {
|
|
|
|
fn move_val_init<T>(&dst: T, -src: T);
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "A function used to initialize the elements of a vector"]
|
2012-01-23 16:59:00 -06:00
|
|
|
type init_op<T> = fn(uint) -> T;
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Returns true if a vector contains no elements"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn is_empty<T>(v: [const T]/&) -> bool {
|
|
|
|
unpack_const_slice(v) {|_p, len| len == 0u}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Returns true if a vector contains some elements"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn is_not_empty<T>(v: [const T]/&) -> bool {
|
|
|
|
unpack_const_slice(v) {|_p, len| len > 0u}
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Returns true if two vectors have the same length"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn same_length<T, U>(xs: [const T]/&, ys: [const U]/&) -> bool {
|
|
|
|
len(xs) == len(ys)
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-03-29 00:36:23 -05:00
|
|
|
Reserves capacity for exactly `n` elements in the given vector.
|
2011-12-13 18:25:51 -06:00
|
|
|
|
|
|
|
If the capacity for `v` is already equal to or greater than the requested
|
|
|
|
capacity, then no action is taken.
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
# Arguments
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
* v - A vector
|
|
|
|
* n - The number of elements to reserve space for
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn reserve<T>(&v: [const T]/~, n: uint) {
|
2012-03-29 01:18:36 -05:00
|
|
|
// Only make the (slow) call into the runtime if we have to
|
|
|
|
if capacity(v) < n {
|
2012-06-01 21:47:04 -05:00
|
|
|
let ptr = ptr::addr_of(v) as **unsafe::vec_repr;
|
2012-06-04 19:26:17 -05:00
|
|
|
rustrt::vec_reserve_shared(sys::get_type_desc::<T>(),
|
|
|
|
ptr, n as size_t);
|
2012-03-29 01:18:36 -05:00
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-29 00:49:28 -05:00
|
|
|
#[doc = "
|
|
|
|
Reserves capacity for at least `n` elements in the given vector.
|
|
|
|
|
|
|
|
This function will over-allocate in order to amortize the allocation costs
|
|
|
|
in scenarios where the caller may need to repeatedly reserve additional
|
|
|
|
space.
|
|
|
|
|
|
|
|
If the capacity for `v` is already equal to or greater than the requested
|
|
|
|
capacity, then no action is taken.
|
|
|
|
|
|
|
|
# Arguments
|
|
|
|
|
|
|
|
* v - A vector
|
|
|
|
* n - The number of elements to reserve space for
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn reserve_at_least<T>(&v: [const T]/~, n: uint) {
|
2012-03-29 00:49:28 -05:00
|
|
|
reserve(v, uint::next_power_of_two(n));
|
|
|
|
}
|
|
|
|
|
2012-03-29 01:10:58 -05:00
|
|
|
#[doc = "
|
|
|
|
Returns the number of elements the vector can hold without reallocating
|
|
|
|
"]
|
2012-03-29 10:57:34 -05:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn capacity<T>(&&v: [const T]/~) -> uint {
|
2012-06-24 22:18:18 -05:00
|
|
|
unsafe {
|
|
|
|
let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
|
|
|
(**repr).alloc / sys::size_of::<T>()
|
|
|
|
}
|
2012-03-29 01:10:58 -05:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Returns the length of a vector"]
|
2012-03-02 22:06:08 -06:00
|
|
|
#[inline(always)]
|
2012-06-24 22:18:18 -05:00
|
|
|
pure fn len<T>(&&v: [const T]/&) -> uint {
|
2012-06-02 21:03:28 -05:00
|
|
|
unpack_const_slice(v) {|_p, len| len}
|
2012-03-21 08:55:36 -05:00
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Creates and initializes an immutable vector.
|
|
|
|
|
|
|
|
Creates an immutable vector of size `n_elts` and initializes the elements
|
|
|
|
to the value returned by the function `op`.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn from_fn<T>(n_elts: uint, op: init_op<T>) -> [T]/~ {
|
|
|
|
let mut v = []/~;
|
2012-05-25 10:14:49 -05:00
|
|
|
unchecked{reserve(v, n_elts);}
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i: uint = 0u;
|
2012-06-25 12:55:29 -05:00
|
|
|
while i < n_elts unsafe { push(v, op(i)); i += 1u; }
|
2011-12-13 18:25:51 -06:00
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Creates and initializes an immutable vector.
|
|
|
|
|
|
|
|
Creates an immutable vector of size `n_elts` and initializes the elements
|
|
|
|
to the value `t`.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn from_elem<T: copy>(n_elts: uint, t: T) -> [T]/~ {
|
|
|
|
let mut v = []/~;
|
2012-05-25 10:14:49 -05:00
|
|
|
unchecked{reserve(v, n_elts)}
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i: uint = 0u;
|
2012-06-13 18:14:01 -05:00
|
|
|
unsafe { // because push is impure
|
|
|
|
while i < n_elts { push(v, t); i += 1u; }
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2012-03-26 20:35:18 -05:00
|
|
|
#[doc = "Produces a mut vector from an immutable vector."]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn to_mut<T>(+v: [T]/~) -> [mut T]/~ {
|
2012-06-24 22:18:18 -05:00
|
|
|
unsafe { ::unsafe::transmute(v) }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-26 20:35:18 -05:00
|
|
|
#[doc = "Produces an immutable vector from a mut vector."]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn from_mut<T>(+v: [mut T]/~) -> [T]/~ {
|
2012-06-24 22:18:18 -05:00
|
|
|
unsafe { ::unsafe::transmute(v) }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Accessors
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Returns the first element of a vector"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn head<T: copy>(v: [const T]/&) -> T { v[0] }
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "Returns a vector containing all but the first element of a slice"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn tail<T: copy>(v: [const T]/&) -> [T]/~ {
|
2011-12-13 18:25:51 -06:00
|
|
|
ret slice(v, 1u, len(v));
|
|
|
|
}
|
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "Returns a vector containing all but the first `n` \
|
|
|
|
elements of a slice"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn tailn<T: copy>(v: [const T]/&, n: uint) -> [T]/~ {
|
2012-01-06 03:23:55 -06:00
|
|
|
slice(v, n, len(v))
|
|
|
|
}
|
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "Returns a vector containing all but the last element of a slice"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn init<T: copy>(v: [const T]/&) -> [T]/~ {
|
2011-12-13 18:25:51 -06:00
|
|
|
assert len(v) != 0u;
|
|
|
|
slice(v, 0u, len(v) - 1u)
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-06-02 21:03:28 -05:00
|
|
|
Returns the last element of the slice `v`, failing if the slice is empty.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn last<T: copy>(v: [const T]/&) -> T {
|
2012-03-08 17:24:27 -06:00
|
|
|
if len(v) == 0u { fail "last_unsafe: empty vector" }
|
|
|
|
v[len(v) - 1u]
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-06-02 21:03:28 -05:00
|
|
|
Returns `some(x)` where `x` is the last element of the slice `v`,
|
|
|
|
or `none` if the vector is empty.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn last_opt<T: copy>(v: [const T]/&) -> option<T> {
|
|
|
|
if len(v) == 0u { ret none; }
|
2012-03-08 17:24:27 -06:00
|
|
|
some(v[len(v) - 1u])
|
2012-03-08 14:08:47 -06:00
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Returns a copy of the elements from [`start`..`end`) from `v`."]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn slice<T: copy>(v: [const T]/&, start: uint, end: uint) -> [T]/~ {
|
2011-12-13 18:25:51 -06:00
|
|
|
assert (start <= end);
|
|
|
|
assert (end <= len(v));
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut result = []/~;
|
2012-06-25 19:08:06 -05:00
|
|
|
unchecked {
|
|
|
|
push_all(result, view(v, start, end));
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2012-05-18 18:55:22 -05:00
|
|
|
#[doc = "Return a slice that points into another slice."]
|
2012-06-25 19:08:06 -05:00
|
|
|
pure fn view<T: copy>(v: [const T]/&, start: uint, end: uint) -> [T]/&a {
|
2012-05-18 18:55:22 -05:00
|
|
|
assert (start <= end);
|
|
|
|
assert (end <= len(v));
|
|
|
|
unpack_slice(v) {|p, _len|
|
|
|
|
unsafe {
|
|
|
|
::unsafe::reinterpret_cast(
|
|
|
|
(ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 20:13:43 -06:00
|
|
|
Split the vector `v` by applying each element against the predicate `f`.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn split<T: copy>(v: [T]/&, f: fn(T) -> bool) -> [[T]/~]/~ {
|
2012-01-26 20:13:43 -06:00
|
|
|
let ln = len(v);
|
2012-06-25 22:00:46 -05:00
|
|
|
if (ln == 0u) { ret []/~ }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut start = 0u;
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut result = []/~;
|
2012-01-26 20:13:43 -06:00
|
|
|
while start < ln {
|
2012-03-18 19:19:41 -05:00
|
|
|
alt position_between(v, start, ln, f) {
|
2012-01-26 20:13:43 -06:00
|
|
|
none { break }
|
|
|
|
some(i) {
|
|
|
|
push(result, slice(v, start, i));
|
|
|
|
start = i + 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
push(result, slice(v, start, ln));
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 20:13:43 -06:00
|
|
|
Split the vector `v` by applying each element against the predicate `f` up
|
|
|
|
to `n` times.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn splitn<T: copy>(v: [T]/&, n: uint, f: fn(T) -> bool) -> [[T]/~]/~ {
|
2012-01-26 20:13:43 -06:00
|
|
|
let ln = len(v);
|
2012-06-25 22:00:46 -05:00
|
|
|
if (ln == 0u) { ret []/~ }
|
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-25 22:00:46 -05:00
|
|
|
let mut result = []/~;
|
2012-01-26 20:13:43 -06:00
|
|
|
while start < ln && count > 0u {
|
2012-03-18 19:19:41 -05:00
|
|
|
alt position_between(v, start, ln, f) {
|
2012-01-26 20:13:43 -06:00
|
|
|
none { break }
|
|
|
|
some(i) {
|
|
|
|
push(result, slice(v, start, i));
|
|
|
|
// Make sure to skip the separator.
|
|
|
|
start = i + 1u;
|
|
|
|
count -= 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
push(result, slice(v, start, ln));
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 20:13:43 -06:00
|
|
|
Reverse split the vector `v` by applying each element against the predicate
|
|
|
|
`f`.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn rsplit<T: copy>(v: [T]/&, f: fn(T) -> bool) -> [[T]/~]/~ {
|
2012-01-26 20:13:43 -06:00
|
|
|
let ln = len(v);
|
2012-06-25 22:00:46 -05:00
|
|
|
if (ln == 0u) { ret []/~ }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut end = ln;
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut result = []/~;
|
2012-01-26 20:13:43 -06:00
|
|
|
while end > 0u {
|
2012-03-18 19:19:41 -05:00
|
|
|
alt rposition_between(v, 0u, end, f) {
|
2012-01-26 20:13:43 -06:00
|
|
|
none { break }
|
|
|
|
some(i) {
|
|
|
|
push(result, slice(v, i + 1u, end));
|
|
|
|
end = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
push(result, slice(v, 0u, end));
|
|
|
|
reversed(result)
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 20:13:43 -06:00
|
|
|
Reverse split the vector `v` by applying each element against the predicate
|
|
|
|
`f` up to `n times.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn rsplitn<T: copy>(v: [T]/&, n: uint, f: fn(T) -> bool) -> [[T]/~]/~ {
|
2012-01-26 20:13:43 -06:00
|
|
|
let ln = len(v);
|
2012-06-25 22:00:46 -05:00
|
|
|
if (ln == 0u) { ret []/~ }
|
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-06-25 22:00:46 -05:00
|
|
|
let mut result = []/~;
|
2012-01-26 20:13:43 -06:00
|
|
|
while end > 0u && count > 0u {
|
2012-03-18 19:19:41 -05:00
|
|
|
alt rposition_between(v, 0u, end, f) {
|
2012-01-26 20:13:43 -06:00
|
|
|
none { break }
|
|
|
|
some(i) {
|
|
|
|
push(result, slice(v, i + 1u, end));
|
|
|
|
// Make sure to skip the separator.
|
|
|
|
end = i;
|
|
|
|
count -= 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
push(result, slice(v, 0u, end));
|
|
|
|
reversed(result)
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
|
|
|
// Mutators
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Removes the first element from a vector and return it"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn shift<T>(&v: [T]/~) -> T {
|
2011-12-13 18:25:51 -06:00
|
|
|
let ln = len::<T>(v);
|
|
|
|
assert (ln > 0u);
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut vv = []/~;
|
2012-06-07 14:18:34 -05:00
|
|
|
v <-> vv;
|
|
|
|
|
|
|
|
unsafe {
|
2012-06-14 21:32:55 -05:00
|
|
|
let mut rr;
|
|
|
|
{
|
|
|
|
let vv = unsafe::to_ptr(vv);
|
2012-06-26 13:13:02 -05:00
|
|
|
rr <- *vv;
|
2012-06-14 21:32:55 -05:00
|
|
|
|
|
|
|
for uint::range(1u, ln) {|i|
|
|
|
|
let r <- *ptr::offset(vv, i);
|
|
|
|
push(v, r);
|
|
|
|
}
|
2012-06-07 14:18:34 -05:00
|
|
|
}
|
2012-06-14 21:32:55 -05:00
|
|
|
unsafe::set_len(vv, 0u);
|
2012-06-07 14:18:34 -05:00
|
|
|
|
2012-06-14 21:32:55 -05:00
|
|
|
rr
|
2012-06-07 14:18:34 -05:00
|
|
|
}
|
2012-03-18 18:16:47 -05:00
|
|
|
}
|
|
|
|
|
2012-06-22 18:31:57 -05:00
|
|
|
#[doc = "Prepend an element to the vector"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn unshift<T>(&v: [T]/~, +x: T) {
|
|
|
|
let mut vv = [x]/~;
|
2012-06-22 18:31:57 -05:00
|
|
|
v <-> vv;
|
|
|
|
while len(vv) > 0 {
|
|
|
|
push(v, shift(vv));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Remove the last element from a vector and return it"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn pop<T>(&v: [const T]/~) -> T {
|
2011-12-13 18:25:51 -06:00
|
|
|
let ln = len(v);
|
2012-02-01 05:08:44 -06:00
|
|
|
assert ln > 0u;
|
|
|
|
let valptr = ptr::mut_addr_of(v[ln - 1u]);
|
2012-06-24 22:18:18 -05:00
|
|
|
unsafe {
|
|
|
|
let val <- *valptr;
|
|
|
|
unsafe::set_len(v, ln - 1u);
|
|
|
|
val
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Append an element to a vector"]
|
2012-06-13 18:14:01 -05:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn push<T>(&v: [const T]/~, +initval: T) {
|
2012-06-13 18:14:01 -05:00
|
|
|
unsafe {
|
2012-06-14 13:38:45 -05:00
|
|
|
let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
|
|
|
let fill = (**repr).fill;
|
|
|
|
if (**repr).alloc > fill {
|
|
|
|
let sz = sys::size_of::<T>();
|
|
|
|
(**repr).fill += sz;
|
|
|
|
let p = ptr::addr_of((**repr).data);
|
|
|
|
let p = ptr::offset(p, fill) as *mut T;
|
|
|
|
rusti::move_val_init(*p, initval);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
push_slow(v, initval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
fn push_slow<T>(&v: [const T]/~, +initval: T) {
|
2012-06-14 13:38:45 -05:00
|
|
|
unsafe {
|
|
|
|
let ln = v.len();
|
2012-06-13 18:14:01 -05:00
|
|
|
reserve_at_least(v, ln + 1u);
|
2012-06-14 13:38:45 -05:00
|
|
|
let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
|
|
|
let fill = (**repr).fill;
|
|
|
|
let sz = sys::size_of::<T>();
|
|
|
|
(**repr).fill += sz;
|
|
|
|
let p = ptr::addr_of((**repr).data);
|
|
|
|
let p = ptr::offset(p, fill) as *mut T;
|
|
|
|
rusti::move_val_init(*p, initval);
|
2012-06-13 18:14:01 -05:00
|
|
|
}
|
2011-12-19 11:48:30 -06:00
|
|
|
}
|
|
|
|
|
2012-06-27 13:32:22 -05:00
|
|
|
// Unchecked vector indexing
|
|
|
|
#[inline(always)]
|
|
|
|
unsafe fn ref<T: copy>(v: [const T]/&, i: uint) -> T {
|
|
|
|
unpack_slice(v) {|p, _len|
|
|
|
|
*ptr::offset(p, i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-13 18:14:01 -05:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn push_all<T: copy>(&v: [const T]/~, rhs: [const T]/&) {
|
2012-06-25 18:22:22 -05:00
|
|
|
reserve(v, v.len() + rhs.len());
|
2012-06-25 22:00:46 -05:00
|
|
|
|
2012-06-13 18:14:01 -05:00
|
|
|
for uint::range(0u, rhs.len()) {|i|
|
2012-06-27 13:32:22 -05:00
|
|
|
push(v, unsafe { ref(rhs, i) })
|
2012-06-13 18:14:01 -05:00
|
|
|
}
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-06-27 17:21:50 -05:00
|
|
|
#[inline(always)]
|
|
|
|
fn push_all_move<T>(&v: [const T]/~, -rhs: [const T]/~) {
|
|
|
|
reserve(v, v.len() + rhs.len());
|
|
|
|
unsafe {
|
|
|
|
unpack_slice(rhs) {|p, len|
|
|
|
|
for uint::range(0, len) {|i|
|
|
|
|
let x <- *ptr::offset(p, i);
|
|
|
|
push(v, x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unsafe::set_len(rhs, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-13 18:25:51 -06:00
|
|
|
// Appending
|
2012-06-13 18:14:01 -05:00
|
|
|
#[inline(always)]
|
2012-06-27 18:08:22 -05:00
|
|
|
pure fn append<T: copy>(+lhs: [T]/~, rhs: [const T]/&) -> [T]/~ {
|
|
|
|
let mut v <- lhs;
|
2012-06-27 13:32:22 -05:00
|
|
|
unchecked {
|
|
|
|
push_all(v, rhs);
|
2012-06-13 18:14:01 -05:00
|
|
|
}
|
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2012-06-28 15:52:13 -05:00
|
|
|
#[inline(always)]
|
|
|
|
pure fn append_one<T>(+lhs: [T]/~, +x: T) -> [T]/~ {
|
|
|
|
let mut v <- lhs;
|
|
|
|
unchecked { push(v, x); }
|
|
|
|
v
|
|
|
|
}
|
|
|
|
|
2012-06-13 18:14:01 -05:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn append_mut<T: copy>(lhs: [mut T]/&, rhs: [const T]/&) -> [mut T]/~ {
|
|
|
|
let mut v = [mut]/~;
|
2012-06-13 18:14:01 -05:00
|
|
|
let mut i = 0u;
|
|
|
|
while i < lhs.len() {
|
|
|
|
unsafe { // This is impure, but it appears pure to the caller.
|
|
|
|
push(v, lhs[i]);
|
|
|
|
}
|
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
i = 0u;
|
|
|
|
while i < rhs.len() {
|
|
|
|
unsafe { // This is impure, but it appears pure to the caller.
|
|
|
|
push(v, rhs[i]);
|
|
|
|
}
|
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
ret v;
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Expands a vector in place, initializing the new elements to a given value
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
# Arguments
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
* v - The vector to grow
|
|
|
|
* n - The number of elements to add
|
|
|
|
* initval - The value for the new elements
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn grow<T: copy>(&v: [const T]/~, n: uint, initval: T) {
|
2012-03-29 00:49:28 -05:00
|
|
|
reserve_at_least(v, len(v) + n);
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i: uint = 0u;
|
2012-06-13 18:14:01 -05:00
|
|
|
|
|
|
|
while i < n { push(v, initval); i += 1u; }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
|
|
|
Expands a vector in place, initializing the new elements to the result of
|
|
|
|
a function
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-01-18 14:18:26 -06:00
|
|
|
Function `init_op` is called `n` times with the values [0..`n`)
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
# Arguments
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
* 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
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn grow_fn<T>(&v: [const T]/~, n: uint, op: init_op<T>) {
|
2012-03-29 00:49:28 -05:00
|
|
|
reserve_at_least(v, len(v) + n);
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i: uint = 0u;
|
2012-06-13 18:14:01 -05:00
|
|
|
while i < n { push(v, op(i)); i += 1u; }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06: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.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-14 13:38:45 -05:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn grow_set<T: copy>(&v: [mut T]/~, index: uint, initval: T, val: T) {
|
2012-03-01 01:44:52 -06:00
|
|
|
if index >= len(v) { grow(v, index - len(v) + 1u, initval); }
|
2011-12-13 18:25:51 -06:00
|
|
|
v[index] = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Functional utilities
|
|
|
|
|
2012-03-15 20:58:14 -05:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Apply a function to each element of a vector and return the results
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn map<T, U>(v: [T]/&, f: fn(T) -> U) -> [U]/~ {
|
|
|
|
let mut result = []/~;
|
2012-05-25 10:14:49 -05:00
|
|
|
unchecked{reserve(result, len(v));}
|
2012-06-13 18:14:01 -05:00
|
|
|
for each(v) {|elem| unsafe { push(result, f(elem)); } }
|
2011-12-13 18:25:51 -06:00
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2012-05-18 12:40:54 -05:00
|
|
|
#[doc = "
|
|
|
|
Apply a function to each element of a vector and return the results
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn mapi<T, U>(v: [T]/&, f: fn(uint, T) -> U) -> [U]/~ {
|
|
|
|
let mut result = []/~;
|
2012-05-25 10:14:49 -05:00
|
|
|
unchecked{reserve(result, len(v));}
|
2012-06-25 12:55:29 -05:00
|
|
|
for eachi(v) {|i, elem| unsafe { push(result, f(i, elem)); } }
|
2012-05-18 12:40:54 -05:00
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2012-03-15 20:58:14 -05:00
|
|
|
#[doc = "
|
2012-04-13 14:22:35 -05:00
|
|
|
Apply a function to each element of a vector and return a concatenation
|
2012-03-15 20:58:14 -05:00
|
|
|
of each result vector
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn flat_map<T, U>(v: [T]/&, f: fn(T) -> [U]/~) -> [U]/~ {
|
|
|
|
let mut result = []/~;
|
2012-06-27 17:21:50 -05:00
|
|
|
for each(v) {|elem| unchecked{ push_all_move(result, f(elem)); } }
|
2012-03-02 16:36:22 -06:00
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Apply a function to each pair of elements and return the results
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn map2<T: copy, U: copy, V>(v0: [T]/&, v1: [U]/&,
|
2012-06-25 22:00:46 -05:00
|
|
|
f: fn(T, U) -> V) -> [V]/~ {
|
2011-12-13 18:25:51 -06:00
|
|
|
let v0_len = len(v0);
|
|
|
|
if v0_len != len(v1) { fail; }
|
2012-06-25 22:00:46 -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 {
|
|
|
|
unsafe { push(u, f(copy v0[i], copy v1[i])) };
|
|
|
|
i += 1u;
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
ret u;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
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.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn filter_map<T, U: copy>(v: [T]/&, f: fn(T) -> option<U>)
|
2012-06-25 22:00:46 -05:00
|
|
|
-> [U]/~ {
|
|
|
|
let mut result = []/~;
|
2012-03-27 08:14:12 -05:00
|
|
|
for each(v) {|elem|
|
2012-03-17 20:17:27 -05:00
|
|
|
alt f(elem) {
|
2012-01-19 03:03:57 -06:00
|
|
|
none {/* no-op */ }
|
2012-06-13 18:14:01 -05:00
|
|
|
some(result_elem) { unsafe { push(result, result_elem); } }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -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.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn filter<T: copy>(v: [T]/&, f: fn(T) -> bool) -> [T]/~ {
|
|
|
|
let mut result = []/~;
|
2012-03-27 08:14:12 -05:00
|
|
|
for each(v) {|elem|
|
2012-06-13 18:14:01 -05:00
|
|
|
if f(elem) { unsafe { push(result, elem); } }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
|
|
|
Concatenate a vector of vectors.
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
Flattens a vector of vectors of T into a single vector of T.
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn concat<T: copy>(v: [[T]/~]/&) -> [T]/~ {
|
|
|
|
let mut r = []/~;
|
2012-06-13 18:14:01 -05:00
|
|
|
for each(v) {|inner| unsafe { push_all(r, inner); } }
|
2012-03-14 14:16:46 -05:00
|
|
|
ret r;
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-28 17:41:53 -06:00
|
|
|
Concatenate a vector of vectors, placing a given separator between each
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn connect<T: copy>(v: [[T]/~]/&, sep: T) -> [T]/~ {
|
|
|
|
let mut r: [T]/~ = []/~;
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut first = true;
|
2012-03-27 08:14:12 -05:00
|
|
|
for each(v) {|inner|
|
2012-06-13 18:14:01 -05:00
|
|
|
if first { first = false; } else { unsafe { push(r, sep); } }
|
2012-06-27 17:21:50 -05:00
|
|
|
unchecked { push_all(r, inner) };
|
2012-01-28 17:41:53 -06:00
|
|
|
}
|
2012-03-14 14:16:46 -05:00
|
|
|
ret r;
|
2012-01-28 17:41:53 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Reduce a vector from left to right"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn foldl<T: copy, U>(z: T, v: [U]/&, p: fn(T, U) -> T) -> T {
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut accum = z;
|
2011-12-13 18:25:51 -06:00
|
|
|
iter(v) { |elt|
|
|
|
|
accum = p(accum, elt);
|
|
|
|
}
|
|
|
|
ret accum;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Reduce a vector from right to left"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn foldr<T, U: copy>(v: [T]/&, z: U, p: fn(T, U) -> U) -> U {
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut accum = z;
|
2011-12-13 18:25:51 -06:00
|
|
|
riter(v) { |elt|
|
|
|
|
accum = p(elt, accum);
|
|
|
|
}
|
|
|
|
ret accum;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Return true if a predicate matches any elements
|
|
|
|
|
|
|
|
If the vector contains no elements then false is returned.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn any<T>(v: [T]/&, f: fn(T) -> bool) -> bool {
|
2012-03-27 08:14:12 -05:00
|
|
|
for each(v) {|elem| if f(elem) { ret true; } }
|
2011-12-13 18:25:51 -06:00
|
|
|
ret false;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-19 11:46:09 -06:00
|
|
|
Return true if a predicate matches any elements in both vectors.
|
|
|
|
|
|
|
|
If the vectors contains no elements then false is returned.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn any2<T, U>(v0: [T]/&, v1: [U]/&,
|
2012-05-25 10:14:49 -05:00
|
|
|
f: fn(T, U) -> bool) -> bool {
|
2011-12-19 11:46:09 -06:00
|
|
|
let v0_len = len(v0);
|
|
|
|
let v1_len = len(v1);
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = 0u;
|
2011-12-19 11:46:09 -06:00
|
|
|
while i < v0_len && i < v1_len {
|
|
|
|
if f(v0[i], v1[i]) { ret true; };
|
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
ret false;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Return true if a predicate matches all elements
|
|
|
|
|
|
|
|
If the vector contains no elements then true is returned.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn all<T>(v: [T]/&, f: fn(T) -> bool) -> bool {
|
2012-03-27 08:14:12 -05:00
|
|
|
for each(v) {|elem| if !f(elem) { ret false; } }
|
2011-12-13 18:25:51 -06:00
|
|
|
ret true;
|
|
|
|
}
|
|
|
|
|
2012-05-15 16:51:33 -05:00
|
|
|
#[doc = "
|
|
|
|
Return true if a predicate matches all elements
|
|
|
|
|
|
|
|
If the vector contains no elements then true is returned.
|
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn alli<T>(v: [T]/&, f: fn(uint, T) -> bool) -> bool {
|
2012-05-15 16:51:33 -05:00
|
|
|
for eachi(v) {|i, elem| if !f(i, elem) { ret false; } }
|
|
|
|
ret true;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-19 11:46:09 -06:00
|
|
|
Return true if a predicate matches all elements in both vectors.
|
|
|
|
|
|
|
|
If the vectors are not the same size then false is returned.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn all2<T, U>(v0: [T]/&, v1: [U]/&,
|
2012-05-25 10:14:49 -05:00
|
|
|
f: fn(T, U) -> bool) -> bool {
|
2011-12-19 11:46:09 -06:00
|
|
|
let v0_len = len(v0);
|
|
|
|
if v0_len != len(v1) { ret false; }
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = 0u;
|
2011-12-19 11:46:09 -06:00
|
|
|
while i < v0_len { if !f(v0[i], v1[i]) { ret false; }; i += 1u; }
|
|
|
|
ret true;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Return true if a vector contains an element with the given value"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn contains<T>(v: [T]/&, x: T) -> bool {
|
2012-03-27 08:14:12 -05:00
|
|
|
for each(v) {|elt| if x == elt { ret true; } }
|
2011-12-13 18:25:51 -06:00
|
|
|
ret false;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Returns the number of elements that are equal to a given value"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn count<T>(v: [T]/&, x: T) -> uint {
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut cnt = 0u;
|
2012-03-27 08:14:12 -05:00
|
|
|
for each(v) {|elt| if x == elt { cnt += 1u; } }
|
2011-12-13 18:25:51 -06:00
|
|
|
ret cnt;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 20:14:27 -06:00
|
|
|
Search for the first element that matches a given predicate
|
2011-12-13 18:25:51 -06:00
|
|
|
|
|
|
|
Apply function `f` to each element of `v`, starting from the first.
|
|
|
|
When function `f` returns true then an option containing the element
|
|
|
|
is returned. If `f` matches no elements then none is returned.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn find<T: copy>(v: [T]/&, f: fn(T) -> bool) -> option<T> {
|
2012-03-18 19:19:41 -05:00
|
|
|
find_between(v, 0u, len(v), f)
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 20:14:27 -06: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.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn find_between<T: copy>(v: [T]/&, start: uint, end: uint,
|
2012-02-29 20:13:29 -06:00
|
|
|
f: fn(T) -> bool) -> option<T> {
|
2012-03-18 19:19:41 -05:00
|
|
|
option::map(position_between(v, start, end, f)) { |i| v[i] }
|
2012-01-26 20:14:27 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 20:14:27 -06: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-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn rfind<T: copy>(v: [T]/&, f: fn(T) -> bool) -> option<T> {
|
2012-03-18 19:19:41 -05:00
|
|
|
rfind_between(v, 0u, len(v), f)
|
2012-01-26 20:14:27 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 20:14:27 -06: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
|
|
|
|
the element is returned. If `f` matches no elements then none is returned.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn rfind_between<T: copy>(v: [T]/&, start: uint, end: uint,
|
2012-05-25 10:14:49 -05:00
|
|
|
f: fn(T) -> bool) -> option<T> {
|
2012-03-18 19:19:41 -05:00
|
|
|
option::map(rposition_between(v, start, end, f)) { |i| v[i] }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Find the first index containing a matching value"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn position_elem<T>(v: [T]/&, x: T) -> option<uint> {
|
2012-01-26 10:39:45 -06:00
|
|
|
position(v) { |y| x == y }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 10:42:50 -06:00
|
|
|
Find the first index matching some predicate
|
|
|
|
|
|
|
|
Apply function `f` to each element of `v`. When function `f` returns true
|
|
|
|
then an option containing the index is returned. If `f` matches no elements
|
|
|
|
then none is returned.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn position<T>(v: [T]/&, f: fn(T) -> bool) -> option<uint> {
|
2012-03-18 19:19:41 -05:00
|
|
|
position_between(v, 0u, len(v), f)
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 10:42:50 -06: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.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn position_between<T>(v: [T]/&, start: uint, end: uint,
|
2012-05-25 10:14:49 -05:00
|
|
|
f: fn(T) -> bool) -> option<uint> {
|
2012-01-26 10:42:50 -06:00
|
|
|
assert start <= end;
|
|
|
|
assert end <= len(v);
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = start;
|
2012-01-26 10:42:50 -06:00
|
|
|
while i < end { if f(v[i]) { ret some::<uint>(i); } i += 1u; }
|
2011-12-13 18:25:51 -06:00
|
|
|
ret none;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Find the last index containing a matching value"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn rposition_elem<T>(v: [T]/&, x: T) -> option<uint> {
|
2012-01-26 10:42:50 -06:00
|
|
|
rposition(v) { |y| x == y }
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 10:42:50 -06:00
|
|
|
Find the last index matching some predicate
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-01-26 10:42:50 -06:00
|
|
|
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.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn rposition<T>(v: [T]/&, f: fn(T) -> bool) -> option<uint> {
|
2012-03-18 19:19:41 -05:00
|
|
|
rposition_between(v, 0u, len(v), f)
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-01-26 10:42:50 -06: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.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn rposition_between<T>(v: [T]/&, start: uint, end: uint,
|
2012-05-25 10:14:49 -05:00
|
|
|
f: fn(T) -> bool) -> option<uint> {
|
2012-01-26 10:42:50 -06:00
|
|
|
assert start <= end;
|
|
|
|
assert end <= len(v);
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = end;
|
2012-01-26 10:42:50 -06:00
|
|
|
while i > start {
|
|
|
|
if f(v[i - 1u]) { ret some::<uint>(i - 1u); }
|
|
|
|
i -= 1u;
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
ret none;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: if issue #586 gets implemented, could have a postcondition
|
|
|
|
// saying the two result lists have the same length -- or, could
|
|
|
|
// return a nominal record with a constraint saying that, instead of
|
|
|
|
// returning a tuple (contingent on issue #869)
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Convert a vector of pairs into a pair of vectors
|
|
|
|
|
|
|
|
Returns a tuple containing two vectors where the i-th element of the first
|
|
|
|
vector contains the first element of the i-th tuple of the input vector,
|
|
|
|
and the i-th element of the second vector contains the second element
|
|
|
|
of the i-th tuple of the input vector.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn unzip<T: copy, U: copy>(v: [(T, U)]/&) -> ([T]/~, [U]/~) {
|
|
|
|
let mut as = []/~, bs = []/~;
|
2012-06-27 17:21:50 -05:00
|
|
|
for each(v) {|p|
|
|
|
|
let (a, b) = p;
|
|
|
|
unchecked {
|
|
|
|
vec::push(as, a);
|
|
|
|
vec::push(bs, b);
|
|
|
|
}
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
ret (as, bs);
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Convert two vectors to a vector of pairs
|
|
|
|
|
|
|
|
Returns a vector of tuples, where the i-th tuple contains contains the
|
|
|
|
i-th elements from each of the input vectors.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn zip<T: copy, U: copy>(v: [const T]/&, u: [const U]/&) -> [(T, U)]/~ {
|
|
|
|
let mut zipped = []/~;
|
2012-03-06 22:48:40 -06:00
|
|
|
let sz = len(v);
|
|
|
|
let mut i = 0u;
|
2012-02-22 04:44:11 -06:00
|
|
|
assert sz == len(u);
|
2012-06-27 17:21:50 -05:00
|
|
|
while i < sz unchecked { vec::push(zipped, (v[i], u[i])); i += 1u; }
|
2011-12-13 18:25:51 -06:00
|
|
|
ret zipped;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Swaps two elements in a vector
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
# Arguments
|
|
|
|
|
|
|
|
* v The input vector
|
|
|
|
* a - The index of the first element
|
|
|
|
* b - The index of the second element
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn swap<T>(&&v: [mut T]/~, a: uint, b: uint) {
|
2011-12-13 18:25:51 -06:00
|
|
|
v[a] <-> v[b];
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Reverse the order of elements in a vector, in place"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn reverse<T>(v: [mut T]/~) {
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i: uint = 0u;
|
2011-12-13 18:25:51 -06:00
|
|
|
let ln = len::<T>(v);
|
|
|
|
while i < ln / 2u { v[i] <-> v[ln - i - 1u]; i += 1u; }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Returns a vector with the order of elements reversed"]
|
2012-06-27 17:21:50 -05:00
|
|
|
pure fn reversed<T: copy>(v: [const T]/&) -> [T]/~ {
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut rs: [T]/~ = []/~;
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = len::<T>(v);
|
2011-12-13 18:25:51 -06:00
|
|
|
if i == 0u { ret rs; } else { i -= 1u; }
|
2012-06-27 17:21:50 -05:00
|
|
|
unchecked {
|
|
|
|
while i != 0u { vec::push(rs, v[i]); i -= 1u; }
|
|
|
|
vec::push(rs, v[0]);
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
ret rs;
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2012-06-02 21:03:28 -05:00
|
|
|
Iterates over a slice
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
Iterates over slice `v` and, for each element, calls function `f` with the
|
2011-12-13 18:25:51 -06:00
|
|
|
element's value.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-03-02 22:06:08 -06:00
|
|
|
#[inline(always)]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn iter<T>(v: [T]/&, f: fn(T)) {
|
2012-03-11 17:02:55 -05:00
|
|
|
iter_between(v, 0u, vec::len(v), f)
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Function: iter_between
|
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
Iterates over a slice
|
2012-03-11 17:02:55 -05:00
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
Iterates over slice `v` and, for each element, calls function `f` with the
|
2012-03-11 17:02:55 -05:00
|
|
|
element's value.
|
|
|
|
|
|
|
|
*/
|
|
|
|
#[inline(always)]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn iter_between<T>(v: [T]/&, start: uint, end: uint, f: fn(T)) {
|
|
|
|
unpack_slice(v) { |base_ptr, len|
|
|
|
|
assert start <= end;
|
|
|
|
assert end <= len;
|
|
|
|
unsafe {
|
|
|
|
let mut n = end;
|
|
|
|
let mut p = ptr::offset(base_ptr, start);
|
|
|
|
while n > start {
|
|
|
|
f(*p);
|
|
|
|
p = ptr::offset(p, 1u);
|
|
|
|
n -= 1u;
|
|
|
|
}
|
2012-03-02 22:06:08 -06:00
|
|
|
}
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-27 05:45:42 -05:00
|
|
|
#[doc = "
|
|
|
|
Iterates over a vector, with option to break
|
2012-05-14 17:28:48 -05:00
|
|
|
|
|
|
|
Return true to continue, false to break.
|
2012-03-27 05:45:42 -05:00
|
|
|
"]
|
|
|
|
#[inline(always)]
|
2012-06-24 22:18:18 -05:00
|
|
|
pure fn each<T>(v: [const T]/&, f: fn(T) -> bool) {
|
2012-04-25 19:18:06 -05:00
|
|
|
vec::unpack_slice(v) {|p, n|
|
|
|
|
let mut n = n;
|
|
|
|
let mut p = p;
|
|
|
|
while n > 0u {
|
2012-06-24 22:18:18 -05:00
|
|
|
unsafe {
|
|
|
|
if !f(*p) { break; }
|
|
|
|
p = ptr::offset(p, 1u);
|
|
|
|
}
|
2012-04-25 19:18:06 -05:00
|
|
|
n -= 1u;
|
|
|
|
}
|
2012-03-27 05:45:42 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc = "
|
|
|
|
Iterates over a vector's elements and indices
|
2012-05-14 17:28:48 -05:00
|
|
|
|
|
|
|
Return true to continue, false to break.
|
2012-03-27 05:45:42 -05:00
|
|
|
"]
|
|
|
|
#[inline(always)]
|
2012-06-24 22:18:18 -05:00
|
|
|
pure fn eachi<T>(v: [const T]/&, f: fn(uint, T) -> bool) {
|
2012-04-25 19:18:06 -05:00
|
|
|
vec::unpack_slice(v) {|p, n|
|
|
|
|
let mut i = 0u;
|
|
|
|
let mut p = p;
|
|
|
|
while i < n {
|
2012-06-24 22:18:18 -05:00
|
|
|
unsafe {
|
|
|
|
if !f(i, *p) { break; }
|
|
|
|
p = ptr::offset(p, 1u);
|
|
|
|
}
|
2012-04-25 19:18:06 -05:00
|
|
|
i += 1u;
|
|
|
|
}
|
2012-03-27 05:45:42 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-18 17:41:03 -05:00
|
|
|
#[doc = "
|
|
|
|
Iterates over two vectors simultaneously
|
|
|
|
|
|
|
|
# Failure
|
|
|
|
|
|
|
|
Both vectors must have the same length
|
|
|
|
"]
|
2012-03-02 22:06:08 -06:00
|
|
|
#[inline]
|
2012-06-02 21:03:28 -05:00
|
|
|
fn iter2<U, T>(v1: [U]/&, v2: [T]/&, f: fn(U, T)) {
|
2012-03-18 17:41:03 -05:00
|
|
|
assert len(v1) == len(v2);
|
2012-05-26 02:32:08 -05:00
|
|
|
for uint::range(0u, len(v1)) {|i|
|
2012-03-18 17:41:03 -05:00
|
|
|
f(v1[i], v2[i])
|
|
|
|
}
|
2012-01-04 04:32:26 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Iterates over a vector's elements and indexes
|
|
|
|
|
|
|
|
Iterates over vector `v` and, for each element, calls function `f` with the
|
|
|
|
element's value and index.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-03-02 22:06:08 -06:00
|
|
|
#[inline(always)]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn iteri<T>(v: [T]/&, f: fn(uint, T)) {
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = 0u;
|
|
|
|
let l = len(v);
|
2011-12-13 18:25:51 -06:00
|
|
|
while i < l { f(i, v[i]); i += 1u; }
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Iterates over a vector in reverse
|
|
|
|
|
|
|
|
Iterates over vector `v` and, for each element, calls function `f` with the
|
|
|
|
element's value.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn riter<T>(v: [T]/&, f: fn(T)) {
|
2011-12-16 08:55:42 -06:00
|
|
|
riteri(v) { |_i, v| f(v) }
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc ="
|
2011-12-13 18:25:51 -06:00
|
|
|
Iterates over a vector's elements and indexes in reverse
|
|
|
|
|
|
|
|
Iterates over vector `v` and, for each element, calls function `f` with the
|
|
|
|
element's value and index.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-02 21:03:28 -05:00
|
|
|
pure fn riteri<T>(v: [T]/&, f: fn(uint, T)) {
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut i = len(v);
|
2011-12-13 18:25:51 -06:00
|
|
|
while 0u < i {
|
|
|
|
i -= 1u;
|
|
|
|
f(i, v[i]);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
|
|
|
Iterate over all permutations of vector `v`.
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
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).
|
2011-12-13 18:25:51 -06:00
|
|
|
|
|
|
|
The total number of permutations produced is `len(v)!`. If `v` contains
|
|
|
|
repeated elements, then some permutations are repeated.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn permute<T: copy>(v: [T]/&, put: fn([T]/~)) {
|
2012-06-27 17:21:50 -05:00
|
|
|
let ln = len(v);
|
|
|
|
if ln == 0u {
|
|
|
|
put([]/~);
|
|
|
|
} else {
|
|
|
|
let mut i = 0u;
|
|
|
|
while i < ln {
|
|
|
|
let elt = v[i];
|
|
|
|
let mut rest = slice(v, 0u, i);
|
|
|
|
unchecked {
|
|
|
|
push_all(rest, view(v, i+1u, ln));
|
2012-06-28 00:49:05 -05:00
|
|
|
permute(rest) {|permutation|
|
|
|
|
put(append([elt]/~, permutation))
|
|
|
|
}
|
2012-06-27 17:21:50 -05:00
|
|
|
}
|
|
|
|
i += 1u;
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn windowed<TT: copy>(nn: uint, xx: [TT]/&) -> [[TT]/~]/~ {
|
|
|
|
let mut ww = []/~;
|
2012-05-25 10:14:49 -05:00
|
|
|
assert 1u <= nn;
|
|
|
|
vec::iteri (xx, {|ii, _x|
|
|
|
|
let len = vec::len(xx);
|
2012-06-27 17:21:50 -05:00
|
|
|
if ii+nn <= len unchecked {
|
|
|
|
vec::push(ww, vec::slice(xx, ii, ii+nn));
|
2012-05-25 10:14:49 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
ret ww;
|
2012-01-23 04:41:40 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
|
|
|
Work with the buffer of a vector.
|
2012-02-07 20:55:02 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
Allows for unsafe manipulation of vector contents, which is useful for native
|
|
|
|
interop.
|
|
|
|
"]
|
2012-06-24 22:18:18 -05:00
|
|
|
fn as_buf<E,T>(v: [E]/&, f: fn(*E) -> T) -> T {
|
2012-06-02 21:03:28 -05:00
|
|
|
unpack_slice(v) { |buf, _len| f(buf) }
|
2012-02-07 20:55:02 -06:00
|
|
|
}
|
|
|
|
|
2012-06-24 22:18:18 -05:00
|
|
|
fn as_mut_buf<E,T>(v: [mut E]/&, f: fn(*mut E) -> T) -> T {
|
2012-06-02 21:03:28 -05:00
|
|
|
unpack_mut_slice(v) { |buf, _len| f(buf) }
|
2012-03-02 19:20:00 -06:00
|
|
|
}
|
|
|
|
|
2012-04-20 19:37:17 -05:00
|
|
|
#[doc = "
|
|
|
|
Work with the buffer and length of a slice.
|
|
|
|
"]
|
2012-04-25 19:18:06 -05:00
|
|
|
#[inline(always)]
|
2012-06-11 20:58:28 -05:00
|
|
|
pure fn unpack_slice<T,U>(s: [const T]/&,
|
2012-06-24 22:18:18 -05:00
|
|
|
f: fn(*T, uint) -> U) -> U {
|
|
|
|
unsafe {
|
|
|
|
let v : *(*T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
|
|
|
|
let (buf,len) = *v;
|
|
|
|
f(buf, len / sys::size_of::<T>())
|
|
|
|
}
|
2012-04-20 19:37:17 -05:00
|
|
|
}
|
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "
|
|
|
|
Work with the buffer and length of a slice.
|
|
|
|
"]
|
|
|
|
#[inline(always)]
|
|
|
|
pure fn unpack_const_slice<T,U>(s: [const T]/&,
|
2012-06-24 22:18:18 -05:00
|
|
|
f: fn(*const T, uint) -> U) -> U {
|
|
|
|
unsafe {
|
|
|
|
let v : *(*const T,uint) =
|
|
|
|
::unsafe::reinterpret_cast(ptr::addr_of(s));
|
|
|
|
let (buf,len) = *v;
|
|
|
|
f(buf, len / sys::size_of::<T>())
|
|
|
|
}
|
2012-06-02 21:03:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[doc = "
|
|
|
|
Work with the buffer and length of a slice.
|
|
|
|
"]
|
|
|
|
#[inline(always)]
|
|
|
|
pure fn unpack_mut_slice<T,U>(s: [mut T]/&,
|
2012-06-24 22:18:18 -05:00
|
|
|
f: fn(*mut T, uint) -> U) -> U {
|
|
|
|
unsafe {
|
|
|
|
let v : *(*const T,uint) =
|
|
|
|
::unsafe::reinterpret_cast(ptr::addr_of(s));
|
|
|
|
let (buf,len) = *v;
|
|
|
|
f(buf, len / sys::size_of::<T>())
|
|
|
|
}
|
2012-06-02 21:03:28 -05:00
|
|
|
}
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
impl extensions<T: copy> for [T]/~ {
|
2012-06-13 18:14:01 -05:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn +(rhs: [T]/&) -> [T]/~ {
|
2012-06-13 18:14:01 -05:00
|
|
|
append(self, rhs)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
impl extensions<T: copy> for [mut T]/~ {
|
2012-06-13 18:14:01 -05:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn +(rhs: [mut T]/&) -> [mut T]/~ {
|
2012-06-13 18:14:01 -05:00
|
|
|
append_mut(self, rhs)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "Extension methods for vectors"]
|
2012-06-02 21:03:28 -05:00
|
|
|
impl extensions/&<T> for [const T]/& {
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "Returns true if a vector contains no elements"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn is_empty() -> bool { is_empty(self) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "Returns true if a vector contains some elements"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn is_not_empty() -> bool { is_not_empty(self) }
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "Returns the length of a vector"]
|
|
|
|
#[inline]
|
|
|
|
pure fn len() -> uint { len(self) }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc = "Extension methods for vectors"]
|
|
|
|
impl extensions/&<T: copy> for [const T]/& {
|
|
|
|
#[doc = "Returns the first element of a vector"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn head() -> T { head(self) }
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "Returns all but the last elemnt of a vector"]
|
|
|
|
#[inline]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn init() -> [T]/~ { init(self) }
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "
|
|
|
|
Returns the last element of a `v`, failing if the vector is empty.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn last() -> T { last(self) }
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "Returns a copy of the elements from [`start`..`end`) from `v`."]
|
|
|
|
#[inline]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn slice(start: uint, end: uint) -> [T]/~ { slice(self, start, end) }
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "Returns all but the first element of a vector"]
|
|
|
|
#[inline]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn tail() -> [T]/~ { tail(self) }
|
2012-06-02 21:03:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[doc = "Extension methods for vectors"]
|
|
|
|
impl extensions/&<T> for [T]/& {
|
|
|
|
#[doc = "Reduce a vector from right to left"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn foldr<U: copy>(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "
|
|
|
|
Iterates over a vector
|
|
|
|
|
|
|
|
Iterates over vector `v` and, for each element, calls function `f` with
|
|
|
|
the element's value.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn iter(f: fn(T)) { iter(self, f) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "
|
|
|
|
Iterates over a vector's elements and indexes
|
|
|
|
|
|
|
|
Iterates over vector `v` and, for each element, calls function `f` with
|
|
|
|
the element's value and index.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn iteri(f: fn(uint, T)) { iteri(self, f) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "
|
|
|
|
Find the first index matching some predicate
|
|
|
|
|
|
|
|
Apply function `f` to each element of `v`. When function `f` returns true
|
|
|
|
then an option containing the index is returned. If `f` matches no
|
|
|
|
elements then none is returned.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn position(f: fn(T) -> bool) -> option<uint> { position(self, f) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "Find the first index containing a matching value"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn position_elem(x: T) -> option<uint> { position_elem(self, x) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "
|
|
|
|
Iterates over a vector in reverse
|
|
|
|
|
|
|
|
Iterates over vector `v` and, for each element, calls function `f` with
|
|
|
|
the element's value.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn riter(f: fn(T)) { riter(self, f) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc ="
|
|
|
|
Iterates over a vector's elements and indexes in reverse
|
|
|
|
|
|
|
|
Iterates over vector `v` and, for each element, calls function `f` with
|
|
|
|
the element's value and index.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn riteri(f: fn(uint, T)) { riteri(self, f) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "
|
|
|
|
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]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn rposition(f: fn(T) -> bool) -> option<uint> { rposition(self, f) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "Find the last index containing a matching value"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn rposition_elem(x: T) -> option<uint> { rposition_elem(self, x) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "
|
2012-04-11 23:45:18 -05:00
|
|
|
Apply a function to each element of a vector and return the results
|
2012-03-17 20:02:45 -05:00
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn map<U>(f: fn(T) -> U) -> [U]/~ { map(self, f) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "
|
2012-05-04 14:33:04 -05:00
|
|
|
Apply a function to the index and value of each element in the vector
|
|
|
|
and return the results
|
|
|
|
"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn mapi<U>(f: fn(uint, T) -> U) -> [U]/~ {
|
2012-05-18 12:40:54 -05:00
|
|
|
mapi(self, f)
|
2012-05-04 14:33:04 -05:00
|
|
|
}
|
2012-05-15 16:51:33 -05:00
|
|
|
#[doc = "Returns true if the function returns true for all elements.
|
|
|
|
|
|
|
|
If the vector is empty, true is returned."]
|
2012-05-25 10:14:49 -05:00
|
|
|
pure fn alli(f: fn(uint, T) -> bool) -> bool {
|
2012-05-15 16:51:33 -05:00
|
|
|
alli(self, f)
|
|
|
|
}
|
2012-05-04 14:33:04 -05:00
|
|
|
#[doc = "
|
2012-04-11 23:45:18 -05:00
|
|
|
Apply a function to each element of a vector and return a concatenation
|
|
|
|
of each result vector
|
2012-03-17 20:02:45 -05:00
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn flat_map<U>(f: fn(T) -> [U]/~) -> [U]/~ { flat_map(self, f) }
|
2012-03-17 20:02:45 -05:00
|
|
|
#[doc = "
|
|
|
|
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]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn filter_map<U: copy>(f: fn(T) -> option<U>) -> [U]/~ {
|
2012-03-17 20:02:45 -05:00
|
|
|
filter_map(self, f)
|
|
|
|
}
|
2012-02-14 02:10:47 -06:00
|
|
|
}
|
2012-02-07 20:55:02 -06:00
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "Extension methods for vectors"]
|
|
|
|
impl extensions/&<T: copy> for [T]/& {
|
|
|
|
#[doc = "
|
|
|
|
Construct a new vector from the elements of a vector for which some
|
|
|
|
predicate holds.
|
|
|
|
|
|
|
|
Apply function `f` to each element of `v` and return a vector containing
|
|
|
|
only those elements for which `f` returned true.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn filter(f: fn(T) -> bool) -> [T]/~ { filter(self, f) }
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "
|
|
|
|
Search for the first element that matches a given predicate
|
|
|
|
|
|
|
|
Apply function `f` to each element of `v`, starting from the first.
|
|
|
|
When function `f` returns true then an option containing the element
|
|
|
|
is returned. If `f` matches no elements then none is returned.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn find(f: fn(T) -> bool) -> option<T> { find(self, f) }
|
2012-06-02 21:03:28 -05:00
|
|
|
#[doc = "
|
|
|
|
Search for the last element that matches a given predicate
|
|
|
|
|
|
|
|
Apply function `f` to each element of `v` in reverse order. When function
|
|
|
|
`f` returns true then an option containing the element is returned. If `f`
|
|
|
|
matches no elements then none is returned.
|
|
|
|
"]
|
|
|
|
#[inline]
|
2012-06-04 09:59:02 -05:00
|
|
|
pure fn rfind(f: fn(T) -> bool) -> option<T> { rfind(self, f) }
|
2012-06-02 21:03:28 -05:00
|
|
|
}
|
|
|
|
|
2012-03-15 20:58:14 -05:00
|
|
|
#[doc = "Unsafe operations"]
|
2011-12-13 18:25:51 -06:00
|
|
|
mod unsafe {
|
2012-04-13 01:38:53 -05:00
|
|
|
// FIXME: This should have crate visibility (#1893 blocks that)
|
2012-03-15 20:58:14 -05:00
|
|
|
#[doc = "The internal representation of a vector"]
|
2012-05-21 20:35:35 -05:00
|
|
|
type vec_repr = {
|
|
|
|
box_header: (uint, uint, uint, uint),
|
|
|
|
mut fill: uint,
|
|
|
|
mut alloc: uint,
|
|
|
|
data: u8
|
|
|
|
};
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Constructs a vector from an unsafe pointer to a buffer
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
# Arguments
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
* ptr - An unsafe pointer to a buffer of `T`
|
|
|
|
* elts - The number of elements in the buffer
|
|
|
|
"]
|
2012-03-02 22:06:08 -06:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
unsafe fn from_buf<T>(ptr: *T, elts: uint) -> [T]/~ {
|
2012-06-01 21:47:04 -05:00
|
|
|
ret ::unsafe::reinterpret_cast(
|
|
|
|
rustrt::vec_from_buf_shared(sys::get_type_desc::<T>(),
|
|
|
|
ptr as *(),
|
2012-06-04 19:26:17 -05:00
|
|
|
elts as size_t));
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06:00
|
|
|
Sets the length of a vector
|
|
|
|
|
2012-06-03 09:34:52 -05:00
|
|
|
This will explicitly set the size of the vector, without actually
|
2011-12-13 18:25:51 -06:00
|
|
|
modifing its buffers, so it is up to the caller to ensure that
|
|
|
|
the vector is actually the specified size.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-03-02 22:06:08 -06:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
unsafe fn set_len<T>(&&v: [const T]/~, new_len: uint) {
|
2011-12-13 18:25:51 -06:00
|
|
|
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
|
|
|
(**repr).fill = new_len * sys::size_of::<T>();
|
|
|
|
}
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "
|
2011-12-13 18:25:51 -06: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.
|
2012-03-06 21:09:32 -06:00
|
|
|
"]
|
2012-03-02 22:06:08 -06:00
|
|
|
#[inline(always)]
|
2012-06-25 22:00:46 -05:00
|
|
|
unsafe fn to_ptr<T>(v: [const T]/~) -> *T {
|
2011-12-13 18:25:51 -06:00
|
|
|
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
|
|
|
ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
|
|
|
|
}
|
2012-04-25 19:18:06 -05:00
|
|
|
|
|
|
|
|
|
|
|
#[doc = "
|
|
|
|
Form a slice from a pointer and length (as a number of units, not bytes).
|
|
|
|
"]
|
|
|
|
#[inline(always)]
|
|
|
|
unsafe fn form_slice<T,U>(p: *T, len: uint, f: fn([T]/&) -> U) -> U {
|
|
|
|
let pair = (p, len * sys::size_of::<T>());
|
2012-06-14 20:18:52 -05:00
|
|
|
let v : *([T]/&blk) =
|
2012-04-30 12:37:58 -05:00
|
|
|
::unsafe::reinterpret_cast(ptr::addr_of(pair));
|
2012-04-25 19:18:06 -05:00
|
|
|
f(*v)
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2012-03-15 20:58:14 -05:00
|
|
|
#[doc = "Operations on `[u8]`"]
|
2012-01-06 09:36:56 -06:00
|
|
|
mod u8 {
|
|
|
|
export cmp;
|
|
|
|
export lt, le, eq, ne, ge, gt;
|
|
|
|
export hash;
|
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Bytewise string comparison"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn cmp(&&a: [u8]/~, &&b: [u8]/~) -> int {
|
2012-01-06 09:36:56 -06:00
|
|
|
let a_len = len(a);
|
|
|
|
let b_len = len(b);
|
2012-03-12 22:04:27 -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 {
|
|
|
|
libc::memcmp(unsafe::to_ptr(a) as *libc::c_void,
|
|
|
|
unsafe::to_ptr(b) as *libc::c_void, n) as int
|
|
|
|
};
|
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-03-06 21:09:32 -06:00
|
|
|
#[doc = "Bytewise less than or equal"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn lt(&&a: [u8]/~, &&b: [u8]/~) -> bool { cmp(a, b) < 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Bytewise less than or equal"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn le(&&a: [u8]/~, &&b: [u8]/~) -> bool { cmp(a, b) <= 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Bytewise equality"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn eq(&&a: [u8]/~, &&b: [u8]/~) -> bool { unsafe { cmp(a, b) == 0 } }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Bytewise inequality"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn ne(&&a: [u8]/~, &&b: [u8]/~) -> bool { unsafe { cmp(a, b) != 0 } }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc ="Bytewise greater than or equal"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn ge(&&a: [u8]/~, &&b: [u8]/~) -> bool { cmp(a, b) >= 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "Bytewise greater than"]
|
2012-06-25 22:00:46 -05:00
|
|
|
pure fn gt(&&a: [u8]/~, &&b: [u8]/~) -> bool { cmp(a, b) > 0 }
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-03-06 21:09:32 -06:00
|
|
|
#[doc = "String hash function"]
|
2012-06-25 22:00:46 -05:00
|
|
|
fn hash(&&s: [u8]/~) -> uint {
|
2012-04-13 01:38:53 -05:00
|
|
|
/* Seems to have been tragically copy/pasted from str.rs,
|
|
|
|
or vice versa. But I couldn't figure out how to abstract
|
|
|
|
it out. -- tjc */
|
2012-01-06 09:36:56 -06:00
|
|
|
|
2012-03-06 22:48:40 -06:00
|
|
|
let mut u: uint = 5381u;
|
2012-01-06 09:36:56 -06:00
|
|
|
vec::iter(s, { |c| u *= 33u; u += c as uint; });
|
|
|
|
ret u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
// ___________________________________________________________________________
|
|
|
|
// ITERATION TRAIT METHODS
|
|
|
|
//
|
|
|
|
// This cannot be used with iter-trait.rs because of the region pointer
|
|
|
|
// required in the slice.
|
2012-06-11 20:58:28 -05:00
|
|
|
impl extensions/&<A> of iter::base_iter<A> for [const A]/& {
|
2012-06-02 21:03:28 -05:00
|
|
|
fn each(blk: fn(A) -> bool) { each(self, blk) }
|
|
|
|
fn size_hint() -> option<uint> { some(len(self)) }
|
|
|
|
fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
|
|
|
|
fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
|
|
|
|
fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
|
|
|
|
fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
|
|
|
|
iter::foldl(self, b0, blk)
|
|
|
|
}
|
|
|
|
fn contains(x: A) -> bool { iter::contains(self, x) }
|
|
|
|
fn count(x: A) -> uint { iter::count(self, x) }
|
|
|
|
}
|
2012-06-11 20:58:28 -05:00
|
|
|
impl extensions/&<A:copy> for [const A]/& {
|
2012-06-25 22:00:46 -05:00
|
|
|
fn filter_to_vec(pred: fn(A) -> bool) -> [A]/~ {
|
2012-06-02 21:03:28 -05:00
|
|
|
iter::filter_to_vec(self, pred)
|
|
|
|
}
|
2012-06-25 22:00:46 -05:00
|
|
|
fn map_to_vec<B>(op: fn(A) -> B) -> [B]/~ { iter::map_to_vec(self, op) }
|
|
|
|
fn to_vec() -> [A]/~ { iter::to_vec(self) }
|
2012-06-02 21:03:28 -05:00
|
|
|
|
2012-06-14 20:18:52 -05:00
|
|
|
// FIXME--bug in resolve prevents this from working (#2611)
|
2012-06-25 22:00:46 -05:00
|
|
|
// fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> [B]/~ {
|
2012-06-02 21:03:28 -05:00
|
|
|
// iter::flat_map_to_vec(self, op)
|
|
|
|
// }
|
|
|
|
|
|
|
|
fn min() -> A { iter::min(self) }
|
|
|
|
fn max() -> A { iter::max(self) }
|
|
|
|
}
|
|
|
|
// ___________________________________________________________________________
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
|
|
|
|
fn square(n: uint) -> uint { ret n * n; }
|
|
|
|
|
|
|
|
fn square_ref(&&n: uint) -> uint { ret n * n; }
|
|
|
|
|
|
|
|
pure fn is_three(&&n: uint) -> bool { ret n == 3u; }
|
|
|
|
|
|
|
|
pure fn is_odd(&&n: uint) -> bool { ret n % 2u == 1u; }
|
|
|
|
|
|
|
|
pure fn is_equal(&&x: uint, &&y:uint) -> bool { ret x == y; }
|
|
|
|
|
2012-02-01 18:49:36 -06:00
|
|
|
fn square_if_odd(&&n: uint) -> option<uint> {
|
2012-01-17 19:28:21 -06:00
|
|
|
ret if n % 2u == 1u { some(n * n) } else { none };
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add(&&x: uint, &&y: uint) -> uint { ret x + y; }
|
|
|
|
|
|
|
|
#[test]
|
2012-06-24 22:18:18 -05:00
|
|
|
fn test_unsafe_ptrs() {
|
|
|
|
unsafe {
|
|
|
|
// Test on-stack copy-from-buf.
|
2012-06-25 22:00:46 -05:00
|
|
|
let a = [1, 2, 3]/~;
|
2012-06-24 22:18:18 -05:00
|
|
|
let mut ptr = unsafe::to_ptr(a);
|
|
|
|
let b = unsafe::from_buf(ptr, 3u);
|
|
|
|
assert (len(b) == 3u);
|
|
|
|
assert (b[0] == 1);
|
|
|
|
assert (b[1] == 2);
|
|
|
|
assert (b[2] == 3);
|
|
|
|
|
|
|
|
// Test on-heap copy-from-buf.
|
2012-06-25 22:00:46 -05:00
|
|
|
let c = [1, 2, 3, 4, 5]/~;
|
2012-06-24 22:18:18 -05:00
|
|
|
ptr = unsafe::to_ptr(c);
|
|
|
|
let d = unsafe::from_buf(ptr, 5u);
|
|
|
|
assert (len(d) == 5u);
|
|
|
|
assert (d[0] == 1);
|
|
|
|
assert (d[1] == 2);
|
|
|
|
assert (d[2] == 3);
|
|
|
|
assert (d[3] == 4);
|
|
|
|
assert (d[4] == 5);
|
|
|
|
}
|
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);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(v) == 3u);
|
|
|
|
assert (v[0] == 0u);
|
|
|
|
assert (v[1] == 1u);
|
|
|
|
assert (v[2] == 4u);
|
|
|
|
|
2012-03-12 17:52:30 -05:00
|
|
|
// Test on-heap from_fn.
|
|
|
|
v = from_fn(5u, square);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(v) == 5u);
|
|
|
|
assert (v[0] == 0u);
|
|
|
|
assert (v[1] == 1u);
|
|
|
|
assert (v[2] == 4u);
|
|
|
|
assert (v[3] == 9u);
|
|
|
|
assert (v[4] == 16u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
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);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(v) == 2u);
|
|
|
|
assert (v[0] == 10u);
|
|
|
|
assert (v[1] == 10u);
|
|
|
|
|
2012-03-12 17:52:30 -05:00
|
|
|
// Test on-heap from_elem.
|
|
|
|
v = from_elem(6u, 20u);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (v[0] == 20u);
|
|
|
|
assert (v[1] == 20u);
|
|
|
|
assert (v[2] == 20u);
|
|
|
|
assert (v[3] == 20u);
|
|
|
|
assert (v[4] == 20u);
|
|
|
|
assert (v[5] == 20u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_empty() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert (is_empty::<int>([]/~));
|
|
|
|
assert (!is_empty([0]/~));
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_is_not_empty() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert (is_not_empty([0]/~));
|
|
|
|
assert (!is_not_empty::<int>([]/~));
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_head() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let a = [11, 12]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (head(a) == 11);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_tail() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut a = [11]/~;
|
|
|
|
assert (tail(a) == []/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
a = [11, 12]/~;
|
|
|
|
assert (tail(a) == [12]/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_last() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut n = last_opt([]/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (n == none);
|
2012-06-25 22:00:46 -05:00
|
|
|
n = last_opt([1, 2, 3]/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (n == some(3));
|
2012-06-25 22:00:46 -05:00
|
|
|
n = last_opt([1, 2, 3, 4, 5]/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (n == some(5));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_slice() {
|
|
|
|
// Test on-stack -> on-stack slice.
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = slice([1, 2, 3]/~, 1u, 3u);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(v) == 2u);
|
|
|
|
assert (v[0] == 2);
|
|
|
|
assert (v[1] == 3);
|
|
|
|
|
|
|
|
// Test on-heap -> on-stack slice.
|
2012-06-25 22:00:46 -05:00
|
|
|
v = slice([1, 2, 3, 4, 5]/~, 0u, 3u);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(v) == 3u);
|
|
|
|
assert (v[0] == 1);
|
|
|
|
assert (v[1] == 2);
|
|
|
|
assert (v[2] == 3);
|
|
|
|
|
|
|
|
// Test on-heap -> on-heap slice.
|
2012-06-25 22:00:46 -05:00
|
|
|
v = slice([1, 2, 3, 4, 5, 6]/~, 1u, 6u);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(v) == 5u);
|
|
|
|
assert (v[0] == 2);
|
|
|
|
assert (v[1] == 3);
|
|
|
|
assert (v[2] == 4);
|
|
|
|
assert (v[3] == 5);
|
|
|
|
assert (v[4] == 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_pop() {
|
|
|
|
// Test on-stack pop.
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [1, 2, 3]/~;
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut e = pop(v);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(v) == 2u);
|
|
|
|
assert (v[0] == 1);
|
|
|
|
assert (v[1] == 2);
|
|
|
|
assert (e == 3);
|
|
|
|
|
|
|
|
// Test on-heap pop.
|
2012-06-25 22:00:46 -05:00
|
|
|
v = [1, 2, 3, 4, 5]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
e = pop(v);
|
|
|
|
assert (len(v) == 4u);
|
|
|
|
assert (v[0] == 1);
|
|
|
|
assert (v[1] == 2);
|
|
|
|
assert (v[2] == 3);
|
|
|
|
assert (v[3] == 4);
|
|
|
|
assert (e == 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_push() {
|
|
|
|
// Test on-stack push().
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = []/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
push(v, 1);
|
|
|
|
assert (len(v) == 1u);
|
|
|
|
assert (v[0] == 1);
|
|
|
|
|
|
|
|
// Test on-heap push().
|
|
|
|
push(v, 2);
|
|
|
|
assert (len(v) == 2u);
|
|
|
|
assert (v[0] == 1);
|
|
|
|
assert (v[1] == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_grow() {
|
|
|
|
// Test on-stack grow().
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = []/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
grow(v, 2u, 1);
|
|
|
|
assert (len(v) == 2u);
|
|
|
|
assert (v[0] == 1);
|
|
|
|
assert (v[1] == 1);
|
|
|
|
|
|
|
|
// Test on-heap grow().
|
|
|
|
grow(v, 3u, 2);
|
|
|
|
assert (len(v) == 5u);
|
|
|
|
assert (v[0] == 1);
|
|
|
|
assert (v[1] == 1);
|
|
|
|
assert (v[2] == 2);
|
|
|
|
assert (v[3] == 2);
|
|
|
|
assert (v[4] == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_grow_fn() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = []/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
grow_fn(v, 3u, square);
|
|
|
|
assert (len(v) == 3u);
|
|
|
|
assert (v[0] == 0u);
|
|
|
|
assert (v[1] == 1u);
|
|
|
|
assert (v[2] == 4u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_grow_set() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [mut 1, 2, 3]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
grow_set(v, 4u, 4, 5);
|
|
|
|
assert (len(v) == 5u);
|
|
|
|
assert (v[0] == 1);
|
|
|
|
assert (v[1] == 2);
|
|
|
|
assert (v[2] == 3);
|
|
|
|
assert (v[3] == 4);
|
|
|
|
assert (v[4] == 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_map() {
|
|
|
|
// Test on-stack map.
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [1u, 2u, 3u]/~;
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut w = map(v, square_ref);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(w) == 3u);
|
|
|
|
assert (w[0] == 1u);
|
|
|
|
assert (w[1] == 4u);
|
|
|
|
assert (w[2] == 9u);
|
|
|
|
|
|
|
|
// Test on-heap map.
|
2012-06-25 22:00:46 -05:00
|
|
|
v = [1u, 2u, 3u, 4u, 5u]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
w = map(v, square_ref);
|
|
|
|
assert (len(w) == 5u);
|
|
|
|
assert (w[0] == 1u);
|
|
|
|
assert (w[1] == 4u);
|
|
|
|
assert (w[2] == 9u);
|
|
|
|
assert (w[3] == 16u);
|
|
|
|
assert (w[4] == 25u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_map2() {
|
|
|
|
fn times(&&x: int, &&y: int) -> int { ret x * y; }
|
|
|
|
let f = times;
|
2012-06-25 22:00:46 -05:00
|
|
|
let v0 = [1, 2, 3, 4, 5]/~;
|
|
|
|
let v1 = [5, 4, 3, 2, 1]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
let u = map2::<int, int, int>(v0, v1, f);
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut i = 0;
|
2012-01-17 19:28:21 -06:00
|
|
|
while i < 5 { assert (v0[i] * v1[i] == u[i]); i += 1; }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_filter_map() {
|
|
|
|
// Test on-stack filter-map.
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [1u, 2u, 3u]/~;
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut w = filter_map(v, square_if_odd);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (len(w) == 2u);
|
|
|
|
assert (w[0] == 1u);
|
|
|
|
assert (w[1] == 9u);
|
|
|
|
|
|
|
|
// Test on-heap filter-map.
|
2012-06-25 22:00:46 -05:00
|
|
|
v = [1u, 2u, 3u, 4u, 5u]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
w = filter_map(v, square_if_odd);
|
|
|
|
assert (len(w) == 3u);
|
|
|
|
assert (w[0] == 1u);
|
|
|
|
assert (w[1] == 9u);
|
|
|
|
assert (w[2] == 25u);
|
|
|
|
|
2012-02-01 18:49:36 -06:00
|
|
|
fn halve(&&i: int) -> option<int> {
|
2012-01-17 19:28:21 -06:00
|
|
|
if i % 2 == 0 {
|
|
|
|
ret option::some::<int>(i / 2);
|
|
|
|
} else { ret option::none::<int>; }
|
|
|
|
}
|
|
|
|
fn halve_for_sure(&&i: int) -> int { ret i / 2; }
|
2012-06-25 22:00:46 -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]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (filter_map(all_even, halve) == map(all_even, halve_for_sure));
|
2012-06-25 22:00:46 -05:00
|
|
|
assert (filter_map(all_odd1, halve) == []/~);
|
|
|
|
assert (filter_map(all_odd2, halve) == []/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (filter_map(mix, halve) == mix_dest);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_filter() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert filter([1u, 2u, 3u]/~, is_odd) == [1u, 3u]/~;
|
|
|
|
assert filter([1u, 2u, 4u, 8u, 16u]/~, is_three) == []/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_foldl() {
|
|
|
|
// Test on-stack fold.
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [1u, 2u, 3u]/~;
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut sum = foldl(0u, v, add);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (sum == 6u);
|
|
|
|
|
|
|
|
// Test on-heap fold.
|
2012-06-25 22:00:46 -05:00
|
|
|
v = [1u, 2u, 3u, 4u, 5u]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
sum = foldl(0u, v, add);
|
|
|
|
assert (sum == 15u);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_foldl2() {
|
|
|
|
fn sub(&&a: int, &&b: int) -> int {
|
|
|
|
a - b
|
|
|
|
}
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [1, 2, 3, 4]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
let sum = foldl(0, v, sub);
|
|
|
|
assert sum == -10;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_foldr() {
|
|
|
|
fn sub(&&a: int, &&b: int) -> int {
|
|
|
|
a - b
|
|
|
|
}
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [1, 2, 3, 4]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
let sum = foldr(v, 0, sub);
|
|
|
|
assert sum == -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_iter_empty() {
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut i = 0;
|
2012-06-25 22:00:46 -05:00
|
|
|
iter::<int>([]/~, { |_v| i += 1 });
|
2012-01-17 19:28:21 -06:00
|
|
|
assert i == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_iter_nonempty() {
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut i = 0;
|
2012-06-25 22:00:46 -05:00
|
|
|
iter([1, 2, 3]/~, { |v| i += v });
|
2012-01-17 19:28:21 -06:00
|
|
|
assert i == 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_iteri() {
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut i = 0;
|
2012-06-25 22:00:46 -05:00
|
|
|
iteri([1, 2, 3]/~, { |j, v|
|
2012-01-17 19:28:21 -06:00
|
|
|
if i == 0 { assert v == 1; }
|
|
|
|
assert j + 1u == v as uint;
|
|
|
|
i += v;
|
|
|
|
});
|
|
|
|
assert i == 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_riter_empty() {
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut i = 0;
|
2012-06-25 22:00:46 -05:00
|
|
|
riter::<int>([]/~, { |_v| i += 1 });
|
2012-01-17 19:28:21 -06:00
|
|
|
assert i == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_riter_nonempty() {
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut i = 0;
|
2012-06-25 22:00:46 -05:00
|
|
|
riter([1, 2, 3]/~, { |v|
|
2012-01-17 19:28:21 -06:00
|
|
|
if i == 0 { assert v == 3; }
|
|
|
|
i += v
|
|
|
|
});
|
|
|
|
assert i == 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_riteri() {
|
2012-03-22 10:39:41 -05:00
|
|
|
let mut i = 0;
|
2012-06-25 22:00:46 -05:00
|
|
|
riteri([0, 1, 2]/~, { |j, v|
|
2012-01-17 19:28:21 -06:00
|
|
|
if i == 0 { assert v == 2; }
|
|
|
|
assert j == v as uint;
|
|
|
|
i += v;
|
|
|
|
});
|
|
|
|
assert i == 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_permute() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut results: [[int]/~]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
results = []/~;
|
2012-06-28 01:09:51 -05:00
|
|
|
permute([]/~) {|v| vec::push(results, v); }
|
2012-06-25 22:00:46 -05:00
|
|
|
assert results == [[]/~]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
results = []/~;
|
|
|
|
permute([7]/~) {|v| results += [v]/~; }
|
|
|
|
assert results == [[7]/~]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
results = []/~;
|
|
|
|
permute([1,1]/~) {|v| results += [v]/~; }
|
|
|
|
assert results == [[1,1]/~,[1,1]/~]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
results = []/~;
|
|
|
|
permute([5,2,0]/~) {|v| results += [v]/~; }
|
|
|
|
assert results ==
|
|
|
|
[[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_any_and_all() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert (any([1u, 2u, 3u]/~, is_three));
|
|
|
|
assert (!any([0u, 1u, 2u]/~, is_three));
|
|
|
|
assert (any([1u, 2u, 3u, 4u, 5u]/~, is_three));
|
|
|
|
assert (!any([1u, 2u, 4u, 5u, 6u]/~, is_three));
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert (all([3u, 3u, 3u]/~, is_three));
|
|
|
|
assert (!all([3u, 3u, 2u]/~, is_three));
|
|
|
|
assert (all([3u, 3u, 3u, 3u, 3u]/~, is_three));
|
|
|
|
assert (!all([3u, 3u, 0u, 1u, 2u]/~, is_three));
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_any2_and_all2() {
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert (any2([2u, 4u, 6u]/~, [2u, 4u, 6u]/~, is_equal));
|
|
|
|
assert (any2([1u, 2u, 3u]/~, [4u, 5u, 3u]/~, is_equal));
|
|
|
|
assert (!any2([1u, 2u, 3u]/~, [4u, 5u, 6u]/~, is_equal));
|
|
|
|
assert (any2([2u, 4u, 6u]/~, [2u, 4u]/~, is_equal));
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert (all2([2u, 4u, 6u]/~, [2u, 4u, 6u]/~, is_equal));
|
|
|
|
assert (!all2([1u, 2u, 3u]/~, [4u, 5u, 3u]/~, is_equal));
|
|
|
|
assert (!all2([1u, 2u, 3u]/~, [4u, 5u, 6u]/~, is_equal));
|
|
|
|
assert (!all2([2u, 4u, 6u]/~, [2u, 4u]/~, is_equal));
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_zip_unzip() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let v1 = [1, 2, 3]/~;
|
|
|
|
let v2 = [4, 5, 6]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
let z1 = zip(v1, v2);
|
|
|
|
|
|
|
|
assert ((1, 4) == z1[0]);
|
|
|
|
assert ((2, 5) == z1[1]);
|
|
|
|
assert ((3, 6) == z1[2]);
|
|
|
|
|
|
|
|
let (left, right) = unzip(z1);
|
|
|
|
|
|
|
|
assert ((1, 4) == (left[0], right[0]));
|
|
|
|
assert ((2, 5) == (left[1], right[1]));
|
|
|
|
assert ((3, 6) == (left[2], right[2]));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:14:43 -05:00
|
|
|
fn test_position_elem() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert position_elem([]/~, 1) == none;
|
2012-01-26 10:39:45 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
let v1 = [1, 2, 3, 3, 2, 5]/~;
|
2012-03-18 19:14:43 -05:00
|
|
|
assert position_elem(v1, 1) == some(0u);
|
|
|
|
assert position_elem(v1, 2) == some(1u);
|
|
|
|
assert position_elem(v1, 5) == some(5u);
|
|
|
|
assert position_elem(v1, 4) == none;
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-01-26 10:39:45 -06:00
|
|
|
fn test_position() {
|
2012-01-17 19:28:21 -06:00
|
|
|
fn less_than_three(&&i: int) -> bool { ret i < 3; }
|
|
|
|
fn is_eighteen(&&i: int) -> bool { ret i == 18; }
|
2012-01-26 10:39:45 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert position([]/~, less_than_three) == none;
|
2012-01-26 10:39:45 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
let v1 = [5, 4, 3, 2, 1]/~;
|
2012-01-26 10:39:45 -06:00
|
|
|
assert position(v1, less_than_three) == some(3u);
|
|
|
|
assert position(v1, is_eighteen) == none;
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:19:41 -05:00
|
|
|
fn test_position_between() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert position_between([]/~, 0u, 0u, f) == none;
|
2012-01-26 10:42:50 -06:00
|
|
|
|
|
|
|
fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]/~;
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert position_between(v, 0u, 0u, f) == none;
|
|
|
|
assert position_between(v, 0u, 1u, f) == none;
|
|
|
|
assert position_between(v, 0u, 2u, f) == some(1u);
|
|
|
|
assert position_between(v, 0u, 3u, f) == some(1u);
|
|
|
|
assert position_between(v, 0u, 4u, f) == some(1u);
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert position_between(v, 1u, 1u, f) == none;
|
|
|
|
assert position_between(v, 1u, 2u, f) == some(1u);
|
|
|
|
assert position_between(v, 1u, 3u, f) == some(1u);
|
|
|
|
assert position_between(v, 1u, 4u, f) == some(1u);
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert position_between(v, 2u, 2u, f) == none;
|
|
|
|
assert position_between(v, 2u, 3u, f) == none;
|
|
|
|
assert position_between(v, 2u, 4u, f) == some(3u);
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert position_between(v, 3u, 3u, f) == none;
|
|
|
|
assert position_between(v, 3u, 4u, f) == some(3u);
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert position_between(v, 4u, 4u, f) == none;
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
|
|
|
|
2012-01-26 20:14:27 -06:00
|
|
|
#[test]
|
|
|
|
fn test_find() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert find([]/~, f) == none;
|
2012-01-26 20:14:27 -06: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' }
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]/~;
|
2012-01-26 20:14:27 -06:00
|
|
|
|
|
|
|
assert find(v, f) == some((1, 'b'));
|
|
|
|
assert find(v, g) == none;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:19:41 -05:00
|
|
|
fn test_find_between() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert find_between([]/~, 0u, 0u, f) == none;
|
2012-01-26 20:14:27 -06:00
|
|
|
|
|
|
|
fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]/~;
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert find_between(v, 0u, 0u, f) == none;
|
|
|
|
assert find_between(v, 0u, 1u, f) == none;
|
|
|
|
assert find_between(v, 0u, 2u, f) == some((1, 'b'));
|
|
|
|
assert find_between(v, 0u, 3u, f) == some((1, 'b'));
|
|
|
|
assert find_between(v, 0u, 4u, f) == some((1, 'b'));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert find_between(v, 1u, 1u, f) == none;
|
|
|
|
assert find_between(v, 1u, 2u, f) == some((1, 'b'));
|
|
|
|
assert find_between(v, 1u, 3u, f) == some((1, 'b'));
|
|
|
|
assert find_between(v, 1u, 4u, f) == some((1, 'b'));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert find_between(v, 2u, 2u, f) == none;
|
|
|
|
assert find_between(v, 2u, 3u, f) == none;
|
|
|
|
assert find_between(v, 2u, 4u, f) == some((3, 'b'));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert find_between(v, 3u, 3u, f) == none;
|
|
|
|
assert find_between(v, 3u, 4u, f) == some((3, 'b'));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert find_between(v, 4u, 4u, f) == none;
|
2012-01-26 20:14:27 -06:00
|
|
|
}
|
|
|
|
|
2012-01-26 10:42:50 -06:00
|
|
|
#[test]
|
|
|
|
fn test_rposition() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert find([]/~, f) == none;
|
2012-01-26 10:42:50 -06: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' }
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]/~;
|
2012-01-26 10:42:50 -06:00
|
|
|
|
|
|
|
assert position(v, f) == some(1u);
|
|
|
|
assert position(v, g) == none;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:19:41 -05:00
|
|
|
fn test_rposition_between() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert rposition_between([]/~, 0u, 0u, f) == none;
|
2012-01-26 10:42:50 -06:00
|
|
|
|
|
|
|
fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]/~;
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rposition_between(v, 0u, 0u, f) == none;
|
|
|
|
assert rposition_between(v, 0u, 1u, f) == none;
|
|
|
|
assert rposition_between(v, 0u, 2u, f) == some(1u);
|
|
|
|
assert rposition_between(v, 0u, 3u, f) == some(1u);
|
|
|
|
assert rposition_between(v, 0u, 4u, f) == some(3u);
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rposition_between(v, 1u, 1u, f) == none;
|
|
|
|
assert rposition_between(v, 1u, 2u, f) == some(1u);
|
|
|
|
assert rposition_between(v, 1u, 3u, f) == some(1u);
|
|
|
|
assert rposition_between(v, 1u, 4u, f) == some(3u);
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rposition_between(v, 2u, 2u, f) == none;
|
|
|
|
assert rposition_between(v, 2u, 3u, f) == none;
|
|
|
|
assert rposition_between(v, 2u, 4u, f) == some(3u);
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rposition_between(v, 3u, 3u, f) == none;
|
|
|
|
assert rposition_between(v, 3u, 4u, f) == some(3u);
|
2012-01-26 10:42:50 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rposition_between(v, 4u, 4u, f) == none;
|
2012-01-26 10:42:50 -06:00
|
|
|
}
|
2012-01-26 20:14:27 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rfind() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert rfind([]/~, f) == none;
|
2012-01-26 20:14:27 -06: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' }
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]/~;
|
2012-01-26 20:14:27 -06:00
|
|
|
|
|
|
|
assert rfind(v, f) == some((3, 'b'));
|
|
|
|
assert rfind(v, g) == none;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-03-18 19:19:41 -05:00
|
|
|
fn test_rfind_between() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert rfind_between([]/~, 0u, 0u, f) == none;
|
2012-01-26 20:14:27 -06:00
|
|
|
|
|
|
|
fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' }
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]/~;
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rfind_between(v, 0u, 0u, f) == none;
|
|
|
|
assert rfind_between(v, 0u, 1u, f) == none;
|
|
|
|
assert rfind_between(v, 0u, 2u, f) == some((1, 'b'));
|
|
|
|
assert rfind_between(v, 0u, 3u, f) == some((1, 'b'));
|
|
|
|
assert rfind_between(v, 0u, 4u, f) == some((3, 'b'));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rfind_between(v, 1u, 1u, f) == none;
|
|
|
|
assert rfind_between(v, 1u, 2u, f) == some((1, 'b'));
|
|
|
|
assert rfind_between(v, 1u, 3u, f) == some((1, 'b'));
|
|
|
|
assert rfind_between(v, 1u, 4u, f) == some((3, 'b'));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rfind_between(v, 2u, 2u, f) == none;
|
|
|
|
assert rfind_between(v, 2u, 3u, f) == none;
|
|
|
|
assert rfind_between(v, 2u, 4u, f) == some((3, 'b'));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rfind_between(v, 3u, 3u, f) == none;
|
|
|
|
assert rfind_between(v, 3u, 4u, f) == some((3, 'b'));
|
2012-01-26 20:14:27 -06:00
|
|
|
|
2012-03-18 19:19:41 -05:00
|
|
|
assert rfind_between(v, 4u, 4u, f) == none;
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn reverse_and_reversed() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let v: [mut int]/~ = [mut 10, 20]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (v[0] == 10);
|
|
|
|
assert (v[1] == 20);
|
|
|
|
reverse(v);
|
|
|
|
assert (v[0] == 20);
|
|
|
|
assert (v[1] == 10);
|
2012-06-25 22:00:46 -05:00
|
|
|
let v2 = reversed::<int>([10, 20]/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (v2[0] == 20);
|
|
|
|
assert (v2[1] == 10);
|
|
|
|
v[0] = 30;
|
|
|
|
assert (v2[0] == 20);
|
|
|
|
// Make sure they work with 0-length vectors too.
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
let v4 = reversed::<int>([]/~);
|
|
|
|
assert (v4 == []/~);
|
|
|
|
let v3: [mut int]/~ = [mut]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
reverse::<int>(v3);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn reversed_mut() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let v2 = reversed::<int>([mut 10, 20]/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
assert (v2[0] == 20);
|
|
|
|
assert (v2[1] == 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_init() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let v = init([1, 2, 3]/~);
|
|
|
|
assert v == [1, 2]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2012-01-26 20:13:43 -06:00
|
|
|
#[test]
|
|
|
|
fn test_split() {
|
|
|
|
fn f(&&x: int) -> bool { x == 3 }
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert split([]/~, f) == []/~;
|
|
|
|
assert split([1, 2]/~, f) == [[1, 2]/~]/~;
|
|
|
|
assert split([3, 1, 2]/~, f) == [[]/~, [1, 2]/~]/~;
|
|
|
|
assert split([1, 2, 3]/~, f) == [[1, 2]/~, []/~]/~;
|
|
|
|
assert split([1, 2, 3, 4, 3, 5]/~, f) == [[1, 2]/~, [4]/~, [5]/~]/~;
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_splitn() {
|
|
|
|
fn f(&&x: int) -> bool { x == 3 }
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert splitn([]/~, 1u, f) == []/~;
|
|
|
|
assert splitn([1, 2]/~, 1u, f) == [[1, 2]/~]/~;
|
|
|
|
assert splitn([3, 1, 2]/~, 1u, f) == [[]/~, [1, 2]/~]/~;
|
|
|
|
assert splitn([1, 2, 3]/~, 1u, f) == [[1, 2]/~, []/~]/~;
|
|
|
|
assert splitn([1, 2, 3, 4, 3, 5]/~, 1u, f) ==
|
|
|
|
[[1, 2]/~, [4, 3, 5]/~]/~;
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rsplit() {
|
|
|
|
fn f(&&x: int) -> bool { x == 3 }
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert rsplit([]/~, f) == []/~;
|
|
|
|
assert rsplit([1, 2]/~, f) == [[1, 2]/~]/~;
|
|
|
|
assert rsplit([1, 2, 3]/~, f) == [[1, 2]/~, []/~]/~;
|
|
|
|
assert rsplit([1, 2, 3, 4, 3, 5]/~, f) == [[1, 2]/~, [4]/~, [5]/~]/~;
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rsplitn() {
|
|
|
|
fn f(&&x: int) -> bool { x == 3 }
|
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert rsplitn([]/~, 1u, f) == []/~;
|
|
|
|
assert rsplitn([1, 2]/~, 1u, f) == [[1, 2]/~]/~;
|
|
|
|
assert rsplitn([1, 2, 3]/~, 1u, f) == [[1, 2]/~, []/~]/~;
|
|
|
|
assert rsplitn([1, 2, 3, 4, 3, 5]/~, 1u, f) ==
|
|
|
|
[[1, 2, 3, 4]/~, [5]/~]/~;
|
2012-01-26 20:13:43 -06:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
2012-02-18 18:34:42 -06:00
|
|
|
#[should_fail]
|
2012-06-07 23:38:25 -05:00
|
|
|
#[ignore(cfg(windows))]
|
2012-01-17 19:28:21 -06:00
|
|
|
fn test_init_empty() {
|
2012-06-25 22:00:46 -05:00
|
|
|
init::<int>([]/~);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_concat() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert concat([[1]/~, [2,3]/~]/~) == [1, 2, 3]/~;
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2012-01-28 17:41:53 -06:00
|
|
|
#[test]
|
|
|
|
fn test_connect() {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert connect([]/~, 0) == []/~;
|
|
|
|
assert connect([[1]/~, [2, 3]/~]/~, 0) == [1, 0, 2, 3]/~;
|
|
|
|
assert connect([[1]/~, [2]/~, [3]/~]/~, 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 () {
|
2012-06-25 22:00:46 -05:00
|
|
|
assert [[1u,2u,3u]/~,[2u,3u,4u]/~,[3u,4u,5u]/~,[4u,5u,6u]/~]/~
|
2012-06-27 17:21:50 -05:00
|
|
|
== windowed (3u, [1u,2u,3u,4u,5u,6u]/~);
|
2012-01-23 04:41:40 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert [[1u,2u,3u,4u]/~,[2u,3u,4u,5u]/~,[3u,4u,5u,6u]/~]/~
|
2012-06-27 17:21:50 -05:00
|
|
|
== windowed (4u, [1u,2u,3u,4u,5u,6u]/~);
|
2012-01-23 04:41:40 -06:00
|
|
|
|
2012-06-25 22:00:46 -05:00
|
|
|
assert []/~ == windowed (7u, [1u,2u,3u,4u,5u,6u]/~);
|
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_() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let _x = windowed (0u, [1u,2u,3u,4u,5u,6u]/~);
|
2012-01-23 04:41:40 -06:00
|
|
|
}
|
2012-03-01 01:44:52 -06:00
|
|
|
|
|
|
|
#[test]
|
2012-06-24 22:18:18 -05:00
|
|
|
fn to_mut_no_copy() {
|
|
|
|
unsafe {
|
2012-06-25 22:00:46 -05:00
|
|
|
let x = [1, 2, 3]/~;
|
2012-06-24 22:18:18 -05:00
|
|
|
let addr = unsafe::to_ptr(x);
|
|
|
|
let x_mut = to_mut(x);
|
|
|
|
let addr_mut = unsafe::to_ptr(x_mut);
|
|
|
|
assert addr == addr_mut;
|
|
|
|
}
|
2012-03-01 01:44:52 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-06-24 22:18:18 -05:00
|
|
|
fn from_mut_no_copy() {
|
|
|
|
unsafe {
|
2012-06-25 22:00:46 -05:00
|
|
|
let x = [mut 1, 2, 3]/~;
|
2012-06-24 22:18:18 -05:00
|
|
|
let addr = unsafe::to_ptr(x);
|
|
|
|
let x_imm = from_mut(x);
|
|
|
|
let addr_imm = unsafe::to_ptr(x_imm);
|
|
|
|
assert addr == addr_imm;
|
|
|
|
}
|
2012-03-01 01:44:52 -06:00
|
|
|
}
|
2012-03-18 18:16:47 -05:00
|
|
|
|
2012-06-22 18:31:57 -05:00
|
|
|
#[test]
|
|
|
|
fn test_unshift() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut x = [1, 2, 3]/~;
|
2012-06-22 18:31:57 -05:00
|
|
|
unshift(x, 0);
|
2012-06-25 22:00:46 -05:00
|
|
|
assert x == [0, 1, 2, 3]/~;
|
2012-06-22 18:31:57 -05:00
|
|
|
}
|
|
|
|
|
2012-03-29 01:10:58 -05:00
|
|
|
#[test]
|
|
|
|
fn test_capacity() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [0u64]/~;
|
2012-03-29 01:10:58 -05:00
|
|
|
reserve(v, 10u);
|
|
|
|
assert capacity(v) == 10u;
|
2012-06-25 22:00:46 -05:00
|
|
|
let mut v = [0u32]/~;
|
2012-03-29 01:10:58 -05:00
|
|
|
reserve(v, 10u);
|
|
|
|
assert capacity(v) == 10u;
|
|
|
|
}
|
2012-05-18 18:55:22 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_view() {
|
2012-06-25 22:00:46 -05:00
|
|
|
let v = [1, 2, 3, 4, 5]/~;
|
2012-05-18 18:55:22 -05:00
|
|
|
let v = view(v, 1u, 3u);
|
|
|
|
assert(len(v) == 2u);
|
|
|
|
assert(v[0] == 2);
|
|
|
|
assert(v[1] == 3);
|
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2011-12-13 18:25:51 -06:00
|
|
|
// Local Variables:
|
|
|
|
// mode: rust;
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// End:
|