Do some cleanup in stdlib.
This commit is contained in:
parent
169f1e5b5a
commit
5adaa6f956
4 changed files with 69 additions and 69 deletions
|
@ -1,11 +1,6 @@
|
|||
|
||||
import option::some;
|
||||
import option::none;
|
||||
|
||||
|
||||
// FIXME: It would probably be more appealing to define this as
|
||||
// type list[T] = rec(T hd, option[@list[T]] tl), but at the moment
|
||||
// our recursion rules do not permit that.
|
||||
tag list[T] { cons(T, @list[T]); nil; }
|
||||
|
||||
fn from_vec[@T](v: vec[T]) -> list[T] {
|
||||
|
@ -48,31 +43,41 @@ fn has[@T](ls_: &list[T], elt: &T) -> bool {
|
|||
while true {
|
||||
alt ls {
|
||||
cons(hd, tl) { if elt == hd { ret true; } else { ls = *tl; } }
|
||||
nil. { ret false; }
|
||||
nil. { break; }
|
||||
}
|
||||
}
|
||||
ret false; // Typestate checker doesn't understand infinite loops
|
||||
|
||||
ret false;
|
||||
}
|
||||
|
||||
fn length[@T](ls: &list[T]) -> uint {
|
||||
fn count[T](t: &T, u: &uint) -> uint { ret u + 1u; }
|
||||
ret foldl[T, uint](ls, 0u, bind count[T](_, _));
|
||||
ret foldl(ls, 0u, count);
|
||||
}
|
||||
|
||||
fn cdr[@T](ls: &list[T]) -> list[T] { alt ls { cons(_, tl) { ret *tl; } } }
|
||||
fn cdr[@T](ls: &list[T]) -> list[T] {
|
||||
alt ls {
|
||||
cons(_, tl) { ret *tl; }
|
||||
nil. { fail "list empty" }
|
||||
}
|
||||
}
|
||||
|
||||
fn car[@T](ls: &list[T]) -> T { alt ls { cons(hd, _) { ret hd; } } }
|
||||
fn car[@T](ls: &list[T]) -> T {
|
||||
alt ls {
|
||||
cons(hd, _) { ret hd; }
|
||||
nil. { fail "list empty" }
|
||||
}
|
||||
}
|
||||
|
||||
fn append[@T](l: &list[T], m: &list[T]) -> list[T] {
|
||||
alt l {
|
||||
nil. { ret m; }
|
||||
cons(x, xs) {
|
||||
let rest: list[T] = append[T](*xs, m);
|
||||
ret cons[T](x, @rest);
|
||||
let rest = append(*xs, m);
|
||||
ret cons(x, @rest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
// fill-column: 78;
|
||||
|
|
|
@ -53,10 +53,9 @@ fn mk_hashmap[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
|
|||
* will fail.
|
||||
*/
|
||||
|
||||
fn insert_common[@K,
|
||||
@V](hasher: &hashfn[K], eqer: &eqfn[K],
|
||||
bkts: &[mutable bucket[K, V]], nbkts: uint,
|
||||
key: &K, val: &V) -> bool {
|
||||
fn insert_common[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K],
|
||||
bkts: &[mutable bucket[K, V]], nbkts: uint,
|
||||
key: &K, val: &V) -> bool {
|
||||
let i: uint = 0u;
|
||||
let h: uint = hasher(key);
|
||||
while i < nbkts {
|
||||
|
@ -67,21 +66,19 @@ fn mk_hashmap[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
|
|||
|
||||
let k_ = k;
|
||||
if eqer(key, k_) {
|
||||
bkts.(j) = some[K, V](k_, val);
|
||||
bkts.(j) = some(k_, val);
|
||||
ret false;
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
_ { bkts.(j) = some[K, V](key, val); ret true; }
|
||||
_ { bkts.(j) = some(key, val); ret true; }
|
||||
}
|
||||
}
|
||||
fail; // full table
|
||||
|
||||
}
|
||||
fn find_common[@K,
|
||||
@V](hasher: &hashfn[K], eqer: &eqfn[K],
|
||||
bkts: &[mutable bucket[K, V]], nbkts: uint, key: &K)
|
||||
-> option::t[V] {
|
||||
fn find_common[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K],
|
||||
bkts: &[mutable bucket[K, V]], nbkts: uint,
|
||||
key: &K) -> option::t[V] {
|
||||
let i: uint = 0u;
|
||||
let h: uint = hasher(key);
|
||||
while i < nbkts {
|
||||
|
@ -89,71 +86,68 @@ fn mk_hashmap[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
|
|||
alt bkts.(j) {
|
||||
some(k, v) {
|
||||
// Copy to please alias analysis.
|
||||
|
||||
let k_ = k;
|
||||
let v_ = v;
|
||||
if eqer(key, k_) { ret option::some[V](v_); }
|
||||
if eqer(key, k_) { ret option::some(v_); }
|
||||
}
|
||||
nil. { ret option::none[V]; }
|
||||
deleted[K, V]. { }
|
||||
nil. { ret option::none; }
|
||||
deleted. { }
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
ret option::none[V];
|
||||
ret option::none;
|
||||
}
|
||||
fn rehash[@K,
|
||||
@V](hasher: &hashfn[K], eqer: &eqfn[K],
|
||||
oldbkts: &[mutable bucket[K, V]], noldbkts: uint,
|
||||
newbkts: &[mutable bucket[K, V]], nnewbkts: uint) {
|
||||
fn rehash[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K],
|
||||
oldbkts: &[mutable bucket[K, V]], noldbkts: uint,
|
||||
newbkts: &[mutable bucket[K, V]], nnewbkts: uint) {
|
||||
for b: bucket[K, V] in oldbkts {
|
||||
alt b {
|
||||
some(k_, v_) {
|
||||
let k = k_;
|
||||
let v = v_;
|
||||
insert_common[K, V](hasher, eqer, newbkts, nnewbkts, k, v);
|
||||
insert_common(hasher, eqer, newbkts, nnewbkts, k, v);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
}
|
||||
obj hashmap[@K,
|
||||
@V](hasher: hashfn[K],
|
||||
eqer: eqfn[K],
|
||||
mutable bkts: [mutable bucket[K, V]],
|
||||
mutable nbkts: uint,
|
||||
mutable nelts: uint,
|
||||
lf: util::rational) {
|
||||
obj hashmap[@K, @V](hasher: hashfn[K],
|
||||
eqer: eqfn[K],
|
||||
mutable bkts: [mutable bucket[K, V]],
|
||||
mutable nbkts: uint,
|
||||
mutable nelts: uint,
|
||||
lf: util::rational) {
|
||||
fn size() -> uint { ret nelts; }
|
||||
fn insert(key: &K, val: &V) -> bool {
|
||||
let load: util::rational =
|
||||
{num: nelts + 1u as int, den: nbkts as int};
|
||||
if !util::rational_leq(load, lf) {
|
||||
let nnewbkts: uint = uint::next_power_of_two(nbkts + 1u);
|
||||
let newbkts = make_buckets[K, V](nnewbkts);
|
||||
rehash[K, V](hasher, eqer, bkts, nbkts, newbkts, nnewbkts);
|
||||
let newbkts = make_buckets(nnewbkts);
|
||||
rehash(hasher, eqer, bkts, nbkts, newbkts, nnewbkts);
|
||||
bkts = newbkts;
|
||||
nbkts = nnewbkts;
|
||||
}
|
||||
if insert_common[K, V](hasher, eqer, bkts, nbkts, key, val) {
|
||||
if insert_common(hasher, eqer, bkts, nbkts, key, val) {
|
||||
nelts += 1u;
|
||||
ret true;
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
fn contains_key(key: &K) -> bool {
|
||||
ret alt find_common[K, V](hasher, eqer, bkts, nbkts, key) {
|
||||
ret alt find_common(hasher, eqer, bkts, nbkts, key) {
|
||||
option::some(_) { true }
|
||||
_ { false }
|
||||
};
|
||||
}
|
||||
fn get(key: &K) -> V {
|
||||
ret alt find_common[K, V](hasher, eqer, bkts, nbkts, key) {
|
||||
ret alt find_common(hasher, eqer, bkts, nbkts, key) {
|
||||
option::some(val) { val }
|
||||
_ { fail }
|
||||
};
|
||||
}
|
||||
fn find(key: &K) -> option::t[V] {
|
||||
be find_common[K, V](hasher, eqer, bkts, nbkts, key);
|
||||
be find_common(hasher, eqer, bkts, nbkts, key);
|
||||
}
|
||||
fn remove(key: &K) -> option::t[V] {
|
||||
let i: uint = 0u;
|
||||
|
@ -165,21 +159,21 @@ fn mk_hashmap[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
|
|||
let k_ = k;
|
||||
let vo = option::some(v);
|
||||
if eqer(key, k_) {
|
||||
bkts.(j) = deleted[K, V];
|
||||
bkts.(j) = deleted;
|
||||
nelts -= 1u;
|
||||
ret vo;
|
||||
}
|
||||
}
|
||||
deleted. { }
|
||||
nil. { ret option::none[V]; }
|
||||
nil. { ret option::none; }
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
ret option::none[V];
|
||||
ret option::none;
|
||||
}
|
||||
fn rehash() {
|
||||
let newbkts = make_buckets[K, V](nbkts);
|
||||
rehash[K, V](hasher, eqer, bkts, nbkts, newbkts, nbkts);
|
||||
let newbkts = make_buckets(nbkts);
|
||||
rehash(hasher, eqer, bkts, nbkts, newbkts, nbkts);
|
||||
bkts = newbkts;
|
||||
}
|
||||
iter items() -> @{key: K, val: V} {
|
||||
|
@ -193,8 +187,8 @@ fn mk_hashmap[@K, @V](hasher: &hashfn[K], eqer: &eqfn[K]) -> hashmap[K, V] {
|
|||
}
|
||||
}
|
||||
}
|
||||
let bkts = make_buckets[K, V](initial_capacity);
|
||||
ret hashmap[K, V](hasher, eqer, bkts, initial_capacity, 0u, load_factor);
|
||||
let bkts = make_buckets(initial_capacity);
|
||||
ret hashmap(hasher, eqer, bkts, initial_capacity, 0u, load_factor);
|
||||
}
|
||||
|
||||
// Hash map constructors for basic types
|
||||
|
@ -206,13 +200,13 @@ fn new_str_hash[@V]() -> hashmap[str, V] {
|
|||
fn new_int_hash[@V]() -> hashmap[int, V] {
|
||||
fn hash_int(x: &int) -> uint { ret x as uint; }
|
||||
fn eq_int(a: &int, b: &int) -> bool { ret a == b; }
|
||||
ret mk_hashmap[int, V](hash_int, eq_int);
|
||||
ret mk_hashmap(hash_int, eq_int);
|
||||
}
|
||||
|
||||
fn new_uint_hash[@V]() -> hashmap[uint, V] {
|
||||
fn hash_uint(x: &uint) -> uint { ret x; }
|
||||
fn eq_uint(a: &uint, b: &uint) -> bool { ret a == b; }
|
||||
ret mk_hashmap[uint, V](hash_uint, eq_uint);
|
||||
ret mk_hashmap(hash_uint, eq_uint);
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -1,37 +1,39 @@
|
|||
|
||||
|
||||
|
||||
// lib/option::rs
|
||||
|
||||
tag t[@T] { none; some(T); }
|
||||
|
||||
type operator[@T, @U] = fn(&T) -> U ;
|
||||
|
||||
fn get[@T](opt: &t[T]) -> T { ret alt opt { some(x) { x } none. { fail } }; }
|
||||
fn get[@T](opt: &t[T]) -> T {
|
||||
alt opt {
|
||||
some(x) { x }
|
||||
none. { fail "option none" }
|
||||
}
|
||||
}
|
||||
|
||||
fn map[@T, @U](f: &operator[T, U], opt: &t[T]) -> t[U] {
|
||||
ret alt opt { some(x) { some[U](f(x)) } none. { none[U] } };
|
||||
alt opt { some(x) { some(f(x)) } none. { none } }
|
||||
}
|
||||
|
||||
fn is_none[@T](opt: &t[T]) -> bool {
|
||||
ret alt opt { none. { true } some(_) { false } };
|
||||
alt opt { none. { true } some(_) { false } }
|
||||
}
|
||||
|
||||
fn is_some[@T](opt: &t[T]) -> bool { ret !is_none(opt); }
|
||||
fn is_some[@T](opt: &t[T]) -> bool { !is_none(opt) }
|
||||
|
||||
fn from_maybe[@T](def: &T, opt: &t[T]) -> T {
|
||||
let f = bind util::id[T](_);
|
||||
ret maybe[T, T](def, f, opt);
|
||||
alt opt { some(x) { x } none. { def } }
|
||||
}
|
||||
|
||||
fn maybe[@T, @U](def: &U, f: fn(&T) -> U , opt: &t[T]) -> U {
|
||||
ret alt opt { none. { def } some(t) { f(t) } };
|
||||
alt opt { none. { def } some(t) { f(t) } }
|
||||
}
|
||||
|
||||
|
||||
// Can be defined in terms of the above when/if we have const bind.
|
||||
fn may[@T](f: fn(&T) , opt: &t[T]) {
|
||||
alt opt { none. {/* nothing */ } some(t) { f(t); } }
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
// fill-column: 78;
|
||||
|
|
|
@ -17,9 +17,8 @@ fn make_socket(ctx: ctx, p: port[aio::socket_event]) -> client {
|
|||
aio::connected(client) {
|
||||
ret { ctx: ctx, client: client, evt: p };
|
||||
}
|
||||
_ { fail "Could not connect to client"; }
|
||||
}
|
||||
log_err ("Could not connect to client");
|
||||
fail;
|
||||
}
|
||||
|
||||
fn connect_to(ctx: ctx, ip: str, portnum: int) -> client {
|
||||
|
|
Loading…
Reference in a new issue