2011-06-16 18:08:26 -05:00
|
|
|
// Interior vector utility functions.
|
|
|
|
|
|
|
|
import option::none;
|
|
|
|
import option::some;
|
2011-06-19 20:02:37 -05:00
|
|
|
import uint::next_power_of_two;
|
2011-07-11 19:26:34 -05:00
|
|
|
import ptr::addr_of;
|
2011-06-16 18:08:26 -05:00
|
|
|
|
|
|
|
native "rust-intrinsic" mod rusti {
|
2011-08-04 19:24:54 -05:00
|
|
|
fn ivec_len[T](v: &[T]) -> uint;
|
2011-06-16 18:08:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
native "rust" mod rustrt {
|
2011-08-04 19:24:54 -05:00
|
|
|
fn ivec_reserve_shared[T](v: &mutable [mutable? T], n: uint);
|
|
|
|
fn ivec_on_heap[T](v: &[T]) -> uint;
|
|
|
|
fn ivec_to_ptr[T](v: &[T]) -> *T;
|
|
|
|
fn ivec_copy_from_buf_shared[T](v: &mutable [mutable? T], ptr: *T,
|
2011-07-27 07:19:39 -05:00
|
|
|
count: uint);
|
2011-06-16 18:08:26 -05:00
|
|
|
}
|
|
|
|
|
2011-08-11 19:02:13 -05:00
|
|
|
fn from_vec[@T](v: &vec[mutable? T]) -> [T] {
|
2011-08-04 19:24:54 -05:00
|
|
|
let iv = ~[];
|
2011-07-29 15:46:53 -05:00
|
|
|
for e in v {
|
|
|
|
iv += ~[e];
|
|
|
|
}
|
|
|
|
ret iv;
|
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn to_vec[@T](iv: &[T]) -> vec[T] {
|
2011-07-29 15:46:53 -05:00
|
|
|
let v: vec[T] = [];
|
|
|
|
for e in iv {
|
|
|
|
v += [e];
|
|
|
|
}
|
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2011-06-16 18:08:26 -05:00
|
|
|
/// Reserves space for `n` elements in the given vector.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn reserve[@T](v: &mutable [mutable? T], n: uint) {
|
2011-07-06 00:55:41 -05:00
|
|
|
rustrt::ivec_reserve_shared(v, n);
|
2011-06-16 18:08:26 -05:00
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn on_heap[T](v: &[T]) -> bool { ret rustrt::ivec_on_heap(v) != 0u; }
|
2011-06-16 18:08:26 -05:00
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn to_ptr[T](v: &[T]) -> *T { ret rustrt::ivec_to_ptr(v); }
|
2011-06-16 19:06:24 -05:00
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn len[T](v: &[mutable? T]) -> uint { ret rusti::ivec_len(v); }
|
2011-06-16 19:06:24 -05:00
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
type init_op[T] = fn(uint) -> T ;
|
2011-06-16 19:47:28 -05:00
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn init_fn[@T](op: &init_op[T], n_elts: uint) -> [T] {
|
2011-07-27 07:19:39 -05:00
|
|
|
let v = ~[];
|
2011-06-16 19:47:28 -05:00
|
|
|
reserve(v, n_elts);
|
2011-07-27 07:19:39 -05:00
|
|
|
let i: uint = 0u;
|
|
|
|
while i < n_elts { v += ~[op(i)]; i += 1u; }
|
2011-06-16 19:47:28 -05:00
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2011-06-17 21:16:03 -05:00
|
|
|
// TODO: Remove me once we have slots.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn init_fn_mut[@T](op: &init_op[T], n_elts: uint) -> [mutable T] {
|
|
|
|
let v = ~[mutable];
|
2011-06-17 21:16:03 -05:00
|
|
|
reserve(v, n_elts);
|
2011-07-27 07:19:39 -05:00
|
|
|
let i: uint = 0u;
|
|
|
|
while i < n_elts { v += ~[mutable op(i)]; i += 1u; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn init_elt[@T](t: &T, n_elts: uint) -> [T] {
|
2011-07-27 07:19:39 -05:00
|
|
|
let v = ~[];
|
2011-06-17 21:16:03 -05:00
|
|
|
reserve(v, n_elts);
|
2011-07-27 07:19:39 -05:00
|
|
|
let i: uint = 0u;
|
|
|
|
while i < n_elts { v += ~[t]; i += 1u; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Remove me once we have slots.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn init_elt_mut[@T](t: &T, n_elts: uint) -> [mutable T] {
|
|
|
|
let v = ~[mutable];
|
2011-06-17 21:16:03 -05:00
|
|
|
reserve(v, n_elts);
|
2011-07-27 07:19:39 -05:00
|
|
|
let i: uint = 0u;
|
|
|
|
while i < n_elts { v += ~[mutable t]; i += 1u; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn to_mut[@T](v: &[T]) -> [mutable T] {
|
|
|
|
let vres = ~[mutable];
|
2011-07-27 07:19:39 -05:00
|
|
|
for t: T in v { vres += ~[mutable t]; }
|
2011-07-16 18:59:17 -05:00
|
|
|
ret vres;
|
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn from_mut[@T](v: &[mutable T]) -> [T] {
|
2011-07-27 07:19:39 -05:00
|
|
|
let vres = ~[];
|
|
|
|
for t: T in v { vres += ~[t]; }
|
2011-07-16 18:59:17 -05:00
|
|
|
ret vres;
|
|
|
|
}
|
|
|
|
|
2011-07-14 17:32:37 -05:00
|
|
|
// Predicates
|
2011-08-04 19:24:54 -05:00
|
|
|
pred is_empty[T](v: &[mutable? T]) -> bool {
|
2011-07-14 17:32:37 -05:00
|
|
|
// FIXME: This would be easier if we could just call len
|
2011-07-29 11:26:50 -05:00
|
|
|
for t: T in v { ret false; }
|
2011-07-14 17:32:37 -05:00
|
|
|
ret true;
|
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
pred is_not_empty[T](v: &[mutable? T]) -> bool { ret !is_empty(v); }
|
2011-06-17 21:16:03 -05:00
|
|
|
|
|
|
|
// Accessors
|
|
|
|
|
2011-07-14 17:40:43 -05:00
|
|
|
/// Returns the first element of a vector
|
2011-08-04 19:24:54 -05:00
|
|
|
fn head[@T](v: &[mutable? T]) : is_not_empty(v) -> T { ret v.(0); }
|
2011-07-14 17:40:43 -05:00
|
|
|
|
|
|
|
/// Returns all but the first element of a vector
|
2011-08-04 19:24:54 -05:00
|
|
|
fn tail[@T](v: &[mutable? T]) : is_not_empty(v) -> [mutable? T] {
|
2011-07-27 07:48:34 -05:00
|
|
|
ret slice(v, 1u, len(v));
|
|
|
|
}
|
2011-07-14 17:40:43 -05:00
|
|
|
|
2011-06-17 21:16:03 -05:00
|
|
|
/// Returns the last element of `v`.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn last[@T](v: &[mutable? T]) -> option::t[T] {
|
2011-07-27 07:19:39 -05:00
|
|
|
if len(v) == 0u { ret none; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret some(v.(len(v) - 1u));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns a copy of the elements from [`start`..`end`) from `v`.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn slice[@T](v: &[mutable? T], start: uint, end: uint) -> [T] {
|
2011-06-17 21:16:03 -05:00
|
|
|
assert (start <= end);
|
|
|
|
assert (end <= len(v));
|
2011-07-27 07:19:39 -05:00
|
|
|
let result = ~[];
|
2011-06-17 21:16:03 -05:00
|
|
|
reserve(result, end - start);
|
2011-07-27 07:19:39 -05:00
|
|
|
let i = start;
|
|
|
|
while i < end { result += ~[v.(i)]; i += 1u; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Remove me once we have slots.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn slice_mut[@T](v: &[mutable? T], start: uint, end: uint) -> [mutable T] {
|
2011-06-17 21:16:03 -05:00
|
|
|
assert (start <= end);
|
|
|
|
assert (end <= len(v));
|
2011-08-04 19:24:54 -05:00
|
|
|
let result = ~[mutable];
|
2011-06-17 21:16:03 -05:00
|
|
|
reserve(result, end - start);
|
2011-07-27 07:19:39 -05:00
|
|
|
let i = start;
|
|
|
|
while i < end { result += ~[mutable v.(i)]; i += 1u; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Mutators
|
|
|
|
|
2011-08-11 17:50:27 -05:00
|
|
|
fn shift[@T](v: &mutable [mutable? T]) -> T {
|
|
|
|
let ln = len[T](v);
|
|
|
|
assert (ln > 0u);
|
|
|
|
let e = v.(0);
|
|
|
|
v = slice[T](v, 1u, ln);
|
|
|
|
ret e;
|
|
|
|
}
|
|
|
|
|
2011-07-04 23:20:18 -05:00
|
|
|
// TODO: Write this, unsafely, in a way that's not O(n).
|
2011-08-04 19:24:54 -05:00
|
|
|
fn pop[@T](v: &mutable [mutable? T]) -> T {
|
2011-07-27 07:19:39 -05:00
|
|
|
let ln = len(v);
|
2011-07-04 23:20:18 -05:00
|
|
|
assert (ln > 0u);
|
|
|
|
ln -= 1u;
|
2011-07-27 07:19:39 -05:00
|
|
|
let e = v.(ln);
|
2011-07-04 23:20:18 -05:00
|
|
|
v = slice(v, 0u, ln);
|
|
|
|
ret e;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: More.
|
2011-06-17 21:16:03 -05:00
|
|
|
|
|
|
|
|
2011-06-18 18:29:45 -05:00
|
|
|
// Appending
|
|
|
|
|
|
|
|
/// Expands the given vector in-place by appending `n` copies of `initval`.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn grow[@T](v: &mutable [T], n: uint, initval: &T) {
|
2011-06-19 20:02:37 -05:00
|
|
|
reserve(v, next_power_of_two(len(v) + n));
|
2011-07-27 07:19:39 -05:00
|
|
|
let i: uint = 0u;
|
|
|
|
while i < n { v += ~[initval]; i += 1u; }
|
2011-06-18 18:29:45 -05:00
|
|
|
}
|
|
|
|
|
2011-06-18 18:41:09 -05:00
|
|
|
// TODO: Remove me once we have slots.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn grow_mut[@T](v: &mutable [mutable T], n: uint, initval: &T) {
|
2011-06-19 20:02:37 -05:00
|
|
|
reserve(v, next_power_of_two(len(v) + n));
|
2011-07-27 07:19:39 -05:00
|
|
|
let i: uint = 0u;
|
|
|
|
while i < n { v += ~[mutable initval]; i += 1u; }
|
2011-06-18 18:41:09 -05:00
|
|
|
}
|
|
|
|
|
2011-06-18 18:29:45 -05:00
|
|
|
/// Calls `f` `n` times and appends the results of these calls to the given
|
|
|
|
/// vector.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn grow_fn[@T](v: &mutable [T], n: uint, init_fn: fn(uint) -> T ) {
|
2011-06-19 20:02:37 -05:00
|
|
|
reserve(v, next_power_of_two(len(v) + n));
|
2011-07-27 07:19:39 -05:00
|
|
|
let i: uint = 0u;
|
|
|
|
while i < n { v += ~[init_fn(i)]; i += 1u; }
|
2011-06-18 18:29:45 -05:00
|
|
|
}
|
|
|
|
|
2011-06-18 18:41:09 -05:00
|
|
|
/// 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.
|
2011-08-04 19:24:54 -05:00
|
|
|
fn grow_set[@T](v: &mutable [mutable T], index: uint, initval: &T, val: &T) {
|
2011-07-27 07:19:39 -05:00
|
|
|
if index >= len(v) { grow_mut(v, index - len(v) + 1u, initval); }
|
2011-06-18 18:41:09 -05:00
|
|
|
v.(index) = val;
|
|
|
|
}
|
2011-06-18 18:29:45 -05:00
|
|
|
|
2011-07-05 00:48:42 -05:00
|
|
|
|
|
|
|
// Functional utilities
|
|
|
|
|
2011-08-12 13:47:44 -05:00
|
|
|
fn map[@T, @U](f: &block(&T) -> U , v: &[mutable? T]) -> [U] {
|
2011-07-27 07:19:39 -05:00
|
|
|
let result = ~[];
|
2011-07-05 00:48:42 -05:00
|
|
|
reserve(result, len(v));
|
2011-07-27 07:19:39 -05:00
|
|
|
for elem: T in v {
|
|
|
|
let elem2 = elem; // satisfies alias checker
|
2011-07-05 00:48:42 -05:00
|
|
|
result += ~[f(elem2)];
|
|
|
|
}
|
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2011-08-11 23:00:11 -05:00
|
|
|
fn map2[@T, @U, @V](f: &block(&T, &U) -> V, v0: &[T], v1: &[U])
|
|
|
|
-> [V] {
|
|
|
|
let v0_len = len[T](v0);
|
|
|
|
if v0_len != len[U](v1) { fail; }
|
|
|
|
let u: [V] = ~[];
|
|
|
|
let i = 0u;
|
|
|
|
while i < v0_len { u += ~[f({ v0.(i) }, { v1.(i) })]; i += 1u; }
|
|
|
|
ret u;
|
|
|
|
}
|
|
|
|
|
2011-08-12 13:47:44 -05:00
|
|
|
fn filter_map[@T, @U](f: &block(&T) -> option::t[U],
|
|
|
|
v: &[mutable? T]) -> [U] {
|
2011-07-27 07:19:39 -05:00
|
|
|
let result = ~[];
|
|
|
|
for elem: T in v {
|
|
|
|
let elem2 = elem; // satisfies alias checker
|
|
|
|
alt f(elem2) {
|
|
|
|
none. {/* no-op */ }
|
|
|
|
some(result_elem) { result += ~[result_elem]; }
|
2011-07-05 19:22:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2011-08-12 13:47:44 -05:00
|
|
|
fn foldl[@T, @U](p: &block(&U, &T) -> U , z: &U, v: &[mutable? T]) -> U {
|
2011-07-27 07:19:39 -05:00
|
|
|
let sz = len(v);
|
|
|
|
if sz == 0u { ret z; }
|
|
|
|
let first = v.(0);
|
|
|
|
let rest = slice(v, 1u, sz);
|
2011-08-12 13:47:44 -05:00
|
|
|
ret p(foldl(p, z, rest), first);
|
2011-07-05 20:29:18 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 13:47:44 -05:00
|
|
|
fn any[T](f: &block(&T) -> bool , v: &[T]) -> bool {
|
2011-07-27 07:19:39 -05:00
|
|
|
for elem: T in v { if f(elem) { ret true; } }
|
2011-07-05 01:52:47 -05:00
|
|
|
ret false;
|
|
|
|
}
|
|
|
|
|
2011-08-12 13:47:44 -05:00
|
|
|
fn all[T](f: &block(&T) -> bool , v: &[T]) -> bool {
|
2011-07-27 07:19:39 -05:00
|
|
|
for elem: T in v { if !f(elem) { ret false; } }
|
2011-07-05 01:52:47 -05:00
|
|
|
ret true;
|
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn member[T](x: &T, v: &[T]) -> bool {
|
2011-07-27 07:19:39 -05:00
|
|
|
for elt: T in v { if x == elt { ret true; } }
|
2011-07-08 09:27:55 -05:00
|
|
|
ret false;
|
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn count[T](x: &T, v: &[mutable? T]) -> uint {
|
2011-07-27 07:19:39 -05:00
|
|
|
let cnt = 0u;
|
|
|
|
for elt: T in v { if x == elt { cnt += 1u; } }
|
2011-07-12 19:00:25 -05:00
|
|
|
ret cnt;
|
|
|
|
}
|
|
|
|
|
2011-08-12 13:47:44 -05:00
|
|
|
fn find[@T](f: &block(&T) -> bool , v: &[T]) -> option::t[T] {
|
|
|
|
for elt: T in v { if f(elt) { ret some(elt); } }
|
|
|
|
ret none;
|
2011-07-08 09:27:55 -05:00
|
|
|
}
|
2011-07-05 00:48:42 -05:00
|
|
|
|
2011-08-11 23:00:11 -05:00
|
|
|
fn position[@T](x: &T, v: &[T]) -> option::t[uint] {
|
|
|
|
let i: uint = 0u;
|
|
|
|
while i < len(v) { if x == v.(i) { ret some[uint](i); } i += 1u; }
|
|
|
|
ret none[uint];
|
|
|
|
}
|
|
|
|
|
|
|
|
fn position_pred[T](f: fn(&T) -> bool , v: &[T]) -> option::t[uint] {
|
|
|
|
let i: uint = 0u;
|
|
|
|
while i < len(v) { if f(v.(i)) { ret some[uint](i); } i += 1u; }
|
|
|
|
ret none[uint];
|
|
|
|
}
|
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn unzip[@T, @U](v: &[{_0: T, _1: U}]) -> {_0: [T], _1: [U]} {
|
2011-07-27 07:19:39 -05:00
|
|
|
let sz = len(v);
|
|
|
|
if sz == 0u {
|
|
|
|
ret {_0: ~[], _1: ~[]};
|
2011-07-16 19:35:20 -05:00
|
|
|
} else {
|
2011-07-27 07:19:39 -05:00
|
|
|
let rest = slice(v, 1u, sz);
|
|
|
|
let tl = unzip(rest);
|
|
|
|
let a = ~[v.(0)._0];
|
|
|
|
let b = ~[v.(0)._1];
|
|
|
|
ret {_0: a + tl._0, _1: b + tl._1};
|
2011-07-16 19:35:20 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME make the lengths being equal a constraint
|
2011-08-04 19:24:54 -05:00
|
|
|
fn zip[@T, @U](v: &[T], u: &[U]) -> [{_0: T, _1: U}] {
|
2011-07-27 07:19:39 -05:00
|
|
|
let sz = len(v);
|
2011-07-26 07:06:02 -05:00
|
|
|
assert (sz == len(u));
|
2011-07-27 07:19:39 -05:00
|
|
|
if sz == 0u {
|
2011-07-16 19:35:20 -05:00
|
|
|
ret ~[];
|
|
|
|
} else {
|
2011-07-27 07:19:39 -05:00
|
|
|
let rest = zip(slice(v, 1u, sz), slice(u, 1u, sz));
|
|
|
|
ret ~[{_0: v.(0), _1: u.(0)}] + rest;
|
2011-07-16 19:35:20 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-16 19:06:24 -05:00
|
|
|
mod unsafe {
|
2011-07-27 07:19:39 -05:00
|
|
|
type ivec_repr =
|
|
|
|
{mutable fill: uint,
|
|
|
|
mutable alloc: uint,
|
|
|
|
heap_part: *mutable ivec_heap_part};
|
|
|
|
type ivec_heap_part = {mutable fill: uint};
|
2011-07-11 19:26:34 -05:00
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn copy_from_buf[T](v: &mutable [T], ptr: *T, count: uint) {
|
2011-07-06 00:55:41 -05:00
|
|
|
ret rustrt::ivec_copy_from_buf_shared(v, ptr, count);
|
2011-06-16 19:06:24 -05:00
|
|
|
}
|
2011-07-10 04:05:52 -05:00
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn from_buf[T](ptr: *T, bytes: uint) -> [T] {
|
2011-07-27 07:19:39 -05:00
|
|
|
let v = ~[];
|
2011-07-10 04:05:52 -05:00
|
|
|
copy_from_buf(v, ptr, bytes);
|
|
|
|
ret v;
|
|
|
|
}
|
2011-07-11 19:26:34 -05:00
|
|
|
|
2011-08-04 19:24:54 -05:00
|
|
|
fn set_len[T](v: &mutable [T], new_len: uint) {
|
2011-07-27 07:19:39 -05:00
|
|
|
let new_fill = new_len * sys::size_of[T]();
|
|
|
|
let stack_part: *mutable ivec_repr =
|
2011-07-11 19:26:34 -05:00
|
|
|
::unsafe::reinterpret_cast(addr_of(v));
|
2011-07-27 07:19:39 -05:00
|
|
|
if (*stack_part).fill == 0u {
|
|
|
|
(*(*stack_part).heap_part).fill = new_fill; // On heap.
|
2011-07-11 19:26:34 -05:00
|
|
|
} else {
|
2011-07-27 07:19:39 -05:00
|
|
|
(*stack_part).fill = new_fill; // On stack.
|
2011-07-11 19:26:34 -05:00
|
|
|
}
|
|
|
|
}
|
2011-06-16 19:06:24 -05:00
|
|
|
}
|
|
|
|
|
2011-07-14 17:32:37 -05:00
|
|
|
// Local Variables:
|
|
|
|
// mode: rust;
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
2011-07-29 20:38:22 -05:00
|
|
|
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
2011-07-14 17:32:37 -05:00
|
|
|
// End:
|