2011-06-16 18:08:26 -05:00
|
|
|
// Interior vector utility functions.
|
|
|
|
|
2011-09-12 18:13:28 -05:00
|
|
|
import option::{some, none};
|
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-10-10 06:32:50 -05:00
|
|
|
fn vec_len<T>(&&v: [T]) -> uint;
|
2011-06-16 18:08:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
native "rust" mod rustrt {
|
2011-09-12 05:39:38 -05:00
|
|
|
fn vec_reserve_shared<T>(&v: [mutable? T], n: uint);
|
2011-08-25 03:18:02 -05:00
|
|
|
fn vec_from_buf_shared<T>(ptr: *T, count: uint) -> [T];
|
2011-06-16 18:08:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Reserves space for `n` elements in the given vector.
|
2011-09-12 05:39:38 -05:00
|
|
|
fn reserve<@T>(&v: [mutable? T], n: uint) {
|
2011-10-12 15:31:41 -05:00
|
|
|
rustrt::vec_reserve_shared(v, n);
|
2011-06-16 18:08:26 -05:00
|
|
|
}
|
|
|
|
|
2011-09-24 17:10:03 -05:00
|
|
|
pure fn len<T>(v: [mutable? T]) -> uint { unchecked { rusti::vec_len(v) } }
|
2011-06-16 19:06:24 -05:00
|
|
|
|
2011-08-19 17:16:48 -05:00
|
|
|
type init_op<T> = fn(uint) -> T;
|
2011-06-16 19:47:28 -05:00
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn init_fn<@T>(op: init_op<T>, n_elts: uint) -> [T] {
|
2011-08-19 17:16:48 -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;
|
2011-08-19 17:16:48 -05:00
|
|
|
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-09-12 04:27:30 -05:00
|
|
|
fn init_fn_mut<@T>(op: init_op<T>, n_elts: uint) -> [mutable T] {
|
2011-08-19 17:16:48 -05:00
|
|
|
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;
|
2011-08-19 17:16:48 -05:00
|
|
|
while i < n_elts { v += [mutable op(i)]; i += 1u; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn init_elt<@T>(t: T, n_elts: uint) -> [T] {
|
2011-08-19 17:16:48 -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;
|
2011-08-19 17:16:48 -05:00
|
|
|
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-09-12 04:27:30 -05:00
|
|
|
fn init_elt_mut<@T>(t: T, n_elts: uint) -> [mutable T] {
|
2011-08-19 17:16:48 -05:00
|
|
|
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;
|
2011-08-19 17:16:48 -05:00
|
|
|
while i < n_elts { v += [mutable t]; i += 1u; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret v;
|
|
|
|
}
|
|
|
|
|
2011-08-30 18:22:21 -05:00
|
|
|
// FIXME: Possible typestate postcondition:
|
|
|
|
// len(result) == len(v) (needs issue #586)
|
2011-09-12 04:27:30 -05:00
|
|
|
fn to_mut<@T>(v: [T]) -> [mutable T] {
|
2011-08-19 17:16:48 -05:00
|
|
|
let vres = [mutable];
|
|
|
|
for t: T in v { vres += [mutable t]; }
|
2011-07-16 18:59:17 -05:00
|
|
|
ret vres;
|
|
|
|
}
|
|
|
|
|
2011-08-30 18:22:21 -05:00
|
|
|
// Same comment as from_mut
|
2011-09-12 04:27:30 -05:00
|
|
|
fn from_mut<@T>(v: [mutable T]) -> [T] {
|
2011-08-19 17:16:48 -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-09-12 04:27:30 -05:00
|
|
|
pure fn 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-09-12 04:27:30 -05:00
|
|
|
pure fn 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-09-12 04:27:30 -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-09-12 04:27:30 -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-09-12 04:27:30 -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-08-19 17:16:48 -05:00
|
|
|
ret some(v[len(v) - 1u]);
|
2011-06-17 21:16:03 -05:00
|
|
|
}
|
|
|
|
|
2011-08-30 19:17:42 -05:00
|
|
|
/// Returns the last element of a non-empty vector `v`.
|
2011-09-12 04:27:30 -05:00
|
|
|
fn last_total<@T>(v: [mutable? T]) : is_not_empty(v) -> T {
|
2011-08-30 19:17:42 -05:00
|
|
|
ret v[len(v) - 1u];
|
|
|
|
}
|
|
|
|
|
2011-06-17 21:16:03 -05:00
|
|
|
/// Returns a copy of the elements from [`start`..`end`) from `v`.
|
2011-09-12 04:27:30 -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-08-19 17:16:48 -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;
|
2011-08-19 17:16:48 -05:00
|
|
|
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-09-12 04:27:30 -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-19 17:16:48 -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;
|
2011-08-19 17:16:48 -05:00
|
|
|
while i < end { result += [mutable v[i]]; i += 1u; }
|
2011-06-17 21:16:03 -05:00
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Mutators
|
|
|
|
|
2011-09-12 05:39:38 -05:00
|
|
|
fn shift<@T>(&v: [mutable? T]) -> T {
|
2011-08-12 12:56:57 -05:00
|
|
|
let ln = len::<T>(v);
|
2011-08-11 17:50:27 -05:00
|
|
|
assert (ln > 0u);
|
2011-08-19 17:16:48 -05:00
|
|
|
let e = v[0];
|
2011-08-12 12:56:57 -05:00
|
|
|
v = slice::<T>(v, 1u, ln);
|
2011-08-11 17:50:27 -05:00
|
|
|
ret e;
|
|
|
|
}
|
|
|
|
|
2011-07-04 23:20:18 -05:00
|
|
|
// TODO: Write this, unsafely, in a way that's not O(n).
|
2011-09-12 05:39:38 -05:00
|
|
|
fn pop<@T>(&v: [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-08-19 17:16:48 -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-09-12 05:39:38 -05:00
|
|
|
fn grow<@T>(&v: [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;
|
2011-08-19 17:16:48 -05:00
|
|
|
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-09-12 05:39:38 -05:00
|
|
|
fn grow_mut<@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;
|
2011-08-19 17:16:48 -05:00
|
|
|
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-09-12 05:39:38 -05:00
|
|
|
fn grow_fn<@T>(&v: [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;
|
2011-08-19 17:16:48 -05:00
|
|
|
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-09-12 05:39:38 -05:00
|
|
|
fn grow_set<@T>(&v: [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-08-19 17:16:48 -05:00
|
|
|
v[index] = val;
|
2011-06-18 18:41:09 -05:00
|
|
|
}
|
2011-06-18 18:29:45 -05:00
|
|
|
|
2011-07-05 00:48:42 -05:00
|
|
|
|
|
|
|
// Functional utilities
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn map<@T, @U>(f: block(T) -> U, v: [mutable? T]) -> [U] {
|
2011-08-19 17:16:48 -05:00
|
|
|
let result = [];
|
2011-07-05 00:48:42 -05:00
|
|
|
reserve(result, len(v));
|
2011-08-15 23:54:52 -05:00
|
|
|
for elem: T in v {
|
2011-07-27 07:19:39 -05:00
|
|
|
let elem2 = elem; // satisfies alias checker
|
2011-08-19 17:16:48 -05:00
|
|
|
result += [f(elem2)];
|
2011-07-05 00:48:42 -05:00
|
|
|
}
|
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn map2<@T, @U, @V>(f: block(T, U) -> V, v0: [T], v1: [U]) -> [V] {
|
2011-08-12 12:56:57 -05:00
|
|
|
let v0_len = len::<T>(v0);
|
|
|
|
if v0_len != len::<U>(v1) { fail; }
|
2011-08-19 17:16:48 -05:00
|
|
|
let u: [V] = [];
|
2011-08-11 23:00:11 -05:00
|
|
|
let i = 0u;
|
2011-08-19 17:16:48 -05:00
|
|
|
while i < v0_len { u += [f({ v0[i] }, { v1[i] })]; i += 1u; }
|
2011-08-11 23:00:11 -05:00
|
|
|
ret u;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn filter_map<@T, @U>(f: block(T) -> option::t<U>, v: [mutable? T]) -> [U] {
|
2011-08-19 17:16:48 -05:00
|
|
|
let result = [];
|
2011-08-15 23:54:52 -05:00
|
|
|
for elem: T in v {
|
2011-07-27 07:19:39 -05:00
|
|
|
let elem2 = elem; // satisfies alias checker
|
|
|
|
alt f(elem2) {
|
|
|
|
none. {/* no-op */ }
|
2011-08-19 17:16:48 -05:00
|
|
|
some(result_elem) { result += [result_elem]; }
|
2011-07-05 19:22:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2011-09-23 21:10:48 -05:00
|
|
|
fn filter<@T>(f: block(T) -> bool, v: [mutable? T]) -> [T] {
|
|
|
|
let result = [];
|
|
|
|
for elem: T in v {
|
|
|
|
let elem2 = elem; // satisfies alias checker
|
|
|
|
if f(elem2) {
|
|
|
|
result += [elem2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret result;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -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; }
|
2011-08-19 17:16:48 -05:00
|
|
|
let first = v[0];
|
2011-07-27 07:19:39 -05:00
|
|
|
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-09-12 04:27:30 -05:00
|
|
|
fn any<T>(f: block(T) -> bool, v: [T]) -> bool {
|
2011-08-15 23:54:52 -05:00
|
|
|
for elem: T in v { if f(elem) { ret true; } }
|
2011-07-05 01:52:47 -05:00
|
|
|
ret false;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn all<T>(f: block(T) -> bool, v: [T]) -> bool {
|
2011-08-15 23:54:52 -05:00
|
|
|
for elem: T in v { if !f(elem) { ret false; } }
|
2011-07-05 01:52:47 -05:00
|
|
|
ret true;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn member<T>(x: T, v: [T]) -> bool {
|
2011-08-15 23:54:52 -05:00
|
|
|
for elt: T in v { if x == elt { ret true; } }
|
2011-07-08 09:27:55 -05:00
|
|
|
ret false;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn count<T>(x: T, v: [mutable? T]) -> uint {
|
2011-07-27 07:19:39 -05:00
|
|
|
let cnt = 0u;
|
2011-08-15 23:54:52 -05:00
|
|
|
for elt: T in v { if x == elt { cnt += 1u; } }
|
2011-07-12 19:00:25 -05:00
|
|
|
ret cnt;
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn find<@T>(f: block(T) -> bool, v: [T]) -> option::t<T> {
|
2011-08-15 23:54:52 -05:00
|
|
|
for elt: T in v { if f(elt) { ret some(elt); } }
|
2011-08-12 13:47:44 -05:00
|
|
|
ret none;
|
2011-07-08 09:27:55 -05:00
|
|
|
}
|
2011-07-05 00:48:42 -05:00
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn position<@T>(x: T, v: [T]) -> option::t<uint> {
|
2011-08-11 23:00:11 -05:00
|
|
|
let i: uint = 0u;
|
2011-08-19 17:16:48 -05:00
|
|
|
while i < len(v) { if x == v[i] { ret some::<uint>(i); } i += 1u; }
|
2011-08-12 12:56:57 -05:00
|
|
|
ret none;
|
2011-08-11 23:00:11 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn position_pred<T>(f: fn(T) -> bool, v: [T]) -> option::t<uint> {
|
2011-08-11 23:00:11 -05:00
|
|
|
let i: uint = 0u;
|
2011-08-19 17:16:48 -05:00
|
|
|
while i < len(v) { if f(v[i]) { ret some::<uint>(i); } i += 1u; }
|
2011-08-12 12:56:57 -05:00
|
|
|
ret none;
|
2011-08-11 23:00:11 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
pure fn same_length<T, U>(xs: [T], ys: [U]) -> bool {
|
2011-09-24 17:10:03 -05:00
|
|
|
vec::len(xs) == vec::len(ys)
|
2011-08-30 18:22:21 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: if issue #586 gets implemented, could have a postcondition
|
|
|
|
// saying the two result lists have the same length -- or, could
|
|
|
|
// return a nominal record with a constraint saying that, instead of
|
|
|
|
// returning a tuple (contingent on issue #869)
|
2011-09-12 04:27:30 -05:00
|
|
|
fn unzip<@T, @U>(v: [(T, U)]) -> ([T], [U]) {
|
2011-08-19 17:16:48 -05:00
|
|
|
let as = [], bs = [];
|
|
|
|
for (a, b) in v { as += [a]; bs += [b]; }
|
2011-08-15 07:32:58 -05:00
|
|
|
ret (as, bs);
|
2011-07-16 19:35:20 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn zip<@T, @U>(v: [T], u: [U]) : same_length(v, u) -> [(T, U)] {
|
2011-08-19 17:16:48 -05:00
|
|
|
let zipped = [];
|
2011-08-15 07:32:58 -05:00
|
|
|
let sz = len(v), i = 0u;
|
2011-07-26 07:06:02 -05:00
|
|
|
assert (sz == len(u));
|
2011-08-19 17:16:48 -05:00
|
|
|
while i < sz { zipped += [(v[i], u[i])]; i += 1u; }
|
2011-08-15 07:32:58 -05:00
|
|
|
ret zipped;
|
2011-07-16 19:35:20 -05:00
|
|
|
}
|
|
|
|
|
2011-08-11 23:07:09 -05:00
|
|
|
// Swaps two elements in a vector
|
2011-09-12 04:27:30 -05:00
|
|
|
fn swap<@T>(v: [mutable T], a: uint, b: uint) {
|
2011-08-19 17:16:48 -05:00
|
|
|
let t: T = v[a];
|
|
|
|
v[a] = v[b];
|
|
|
|
v[b] = t;
|
2011-08-11 23:07:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// In place vector reversal
|
2011-09-12 04:27:30 -05:00
|
|
|
fn reverse<@T>(v: [mutable T]) {
|
2011-08-11 23:07:09 -05:00
|
|
|
let i: uint = 0u;
|
2011-08-12 12:56:57 -05:00
|
|
|
let ln = len::<T>(v);
|
2011-08-11 23:07:09 -05:00
|
|
|
while i < ln / 2u { swap(v, i, ln - i - 1u); i += 1u; }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Functional vector reversal. Returns a reversed copy of v.
|
2011-09-12 04:27:30 -05:00
|
|
|
fn reversed<@T>(v: [T]) -> [T] {
|
2011-08-19 17:16:48 -05:00
|
|
|
let rs: [T] = [];
|
2011-08-12 12:56:57 -05:00
|
|
|
let i = len::<T>(v);
|
2011-08-11 23:07:09 -05:00
|
|
|
if i == 0u { ret rs; } else { i -= 1u; }
|
2011-08-19 17:16:48 -05:00
|
|
|
while i != 0u { rs += [v[i]]; i -= 1u; }
|
|
|
|
rs += [v[0]];
|
2011-08-11 23:07:09 -05:00
|
|
|
ret rs;
|
|
|
|
}
|
|
|
|
|
2011-08-30 18:22:21 -05:00
|
|
|
// Generating vecs.
|
2011-09-02 17:34:58 -05:00
|
|
|
fn enum_chars(start: u8, end: u8) : u8::le(start, end) -> [char] {
|
2011-08-30 18:22:21 -05:00
|
|
|
let i = start;
|
|
|
|
let r = [];
|
2011-09-02 17:34:58 -05:00
|
|
|
while i <= end { r += [i as char]; i += 1u as u8; }
|
2011-08-30 18:22:21 -05:00
|
|
|
ret r;
|
|
|
|
}
|
|
|
|
|
2011-09-02 17:34:58 -05:00
|
|
|
fn enum_uints(start: uint, end: uint) : uint::le(start, end) -> [uint] {
|
2011-08-30 18:22:21 -05:00
|
|
|
let i = start;
|
|
|
|
let r = [];
|
2011-09-02 17:34:58 -05:00
|
|
|
while i <= end { r += [i]; i += 1u; }
|
2011-08-30 18:22:21 -05:00
|
|
|
ret r;
|
|
|
|
}
|
|
|
|
|
2011-09-29 19:31:11 -05:00
|
|
|
fn eachi<@T>(f: block(T, uint) -> (), v: [mutable? T]) {
|
|
|
|
let i = 0u;
|
|
|
|
let l = len(v);
|
|
|
|
while (i < l) {
|
|
|
|
let elem = v[i]; // Satisfy alias checker
|
|
|
|
f(elem, i);
|
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-19 18:14:38 -05:00
|
|
|
// Iterate over a list with with the indexes
|
2011-09-12 04:27:30 -05:00
|
|
|
iter iter2<@T>(v: [T]) -> (uint, T) {
|
2011-08-19 18:14:38 -05:00
|
|
|
let i = 0u;
|
2011-09-02 17:34:58 -05:00
|
|
|
for x in v { put (i, x); i += 1u; }
|
2011-08-19 18:14:38 -05:00
|
|
|
}
|
2011-08-11 23:07:09 -05:00
|
|
|
|
2011-06-16 19:06:24 -05:00
|
|
|
mod unsafe {
|
2011-09-02 17:34:58 -05:00
|
|
|
type vec_repr = {mutable fill: uint, mutable alloc: uint, data: u8};
|
2011-07-10 04:05:52 -05:00
|
|
|
|
2011-10-12 15:31:41 -05:00
|
|
|
unsafe fn from_buf<@T>(ptr: *T, elts: uint) -> [T] {
|
2011-08-25 03:18:02 -05:00
|
|
|
ret rustrt::vec_from_buf_shared(ptr, elts);
|
2011-07-10 04:05:52 -05:00
|
|
|
}
|
2011-07-11 19:26:34 -05:00
|
|
|
|
2011-10-12 15:31:41 -05:00
|
|
|
unsafe fn set_len<@T>(&v: [T], new_len: uint) {
|
2011-09-02 15:44:01 -05:00
|
|
|
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
2011-08-25 03:18:02 -05:00
|
|
|
(**repr).fill = new_len * sys::size_of::<T>();
|
2011-07-11 19:26:34 -05:00
|
|
|
}
|
2011-08-25 03:18:02 -05:00
|
|
|
|
2011-10-12 15:31:41 -05:00
|
|
|
unsafe fn to_ptr<@T>(v: [T]) -> *T {
|
2011-09-02 15:44:01 -05:00
|
|
|
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
2011-08-25 03:18:02 -05:00
|
|
|
ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-12 15:31:41 -05:00
|
|
|
unsafe fn to_ptr<@T>(v: [T]) -> *T { ret unsafe::to_ptr(v); }
|
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:
|