Remove modes from map API and replace with regions.

API is (for now) mostly by value, there are options to use it by
reference if you like.  Hash and equality functions must be pure
and by reference (forward looking to the day when something
like send_map becomes the standard map).
This commit is contained in:
Niko Matsakis 2012-08-02 15:42:56 -07:00
parent 476ce459bd
commit 97452c0ca1
62 changed files with 578 additions and 473 deletions

View File

@ -734,7 +734,7 @@ An example of imports:
~~~~
import foo = core::info;
import core::float::sin;
import core::str::{slice, hash};
import core::str::{slice, to_upper};
import core::option::some;
fn main() {
@ -745,8 +745,8 @@ fn main() {
log(info, some(1.0));
// Equivalent to 'log(core::info,
// core::str::hash(core::str::slice(~"foo", 0u, 1u)));'
log(info, hash(slice(~"foo", 0u, 1u)));
// core::str::to_upper(core::str::slice(~"foo", 0u, 1u)));'
log(info, to_upper(slice(~"foo", 0u, 1u)));
}
~~~~

View File

@ -1472,7 +1472,7 @@ fn print_pkg(s: source, p: package) {
fn print_source(s: source) {
info(s.name + ~" (" + s.url + ~")");
let pks = sort::merge_sort(|a, b| a < b, copy s.packages);
let pks = sort::merge_sort(sys::shape_lt, copy s.packages);
let l = vec::len(pks);
print(io::with_str_writer(|writer| {

View File

@ -8,3 +8,14 @@ trait eq {
pure fn eq(&&other: self) -> bool;
}
pure fn lt<T: ord>(v1: &T, v2: &T) -> bool {
v1.lt(*v2)
}
pure fn le<T: ord eq>(v1: &T, v2: &T) -> bool {
v1.lt(*v2) || v1.eq(*v2)
}
pure fn eq<T: eq>(v1: &T, v2: &T) -> bool {
v1.eq(*v2)
}

View File

@ -96,13 +96,13 @@ mod ct {
while i < lim {
let size = str::utf8_char_width(s[i]);
let curr = str::slice(s, i, i+size);
if str::eq(curr, ~"%") {
if curr == ~"%" {
i += 1u;
if i >= lim {
error(~"unterminated conversion at end of string");
}
let curr2 = str::slice(s, i, i+1u);
if str::eq(curr2, ~"%") {
if curr2 == ~"%" {
buf += curr2;
i += 1u;
} else {
@ -232,27 +232,27 @@ mod ct {
// FIXME (#2249): Do we really want two signed types here?
// How important is it to be printf compatible?
let t =
if str::eq(tstr, ~"b") {
if tstr == ~"b" {
ty_bool
} else if str::eq(tstr, ~"s") {
} else if tstr == ~"s" {
ty_str
} else if str::eq(tstr, ~"c") {
} else if tstr == ~"c" {
ty_char
} else if str::eq(tstr, ~"d") || str::eq(tstr, ~"i") {
} else if tstr == ~"d" || tstr == ~"i" {
ty_int(signed)
} else if str::eq(tstr, ~"u") {
} else if tstr == ~"u" {
ty_int(unsigned)
} else if str::eq(tstr, ~"x") {
} else if tstr == ~"x" {
ty_hex(case_lower)
} else if str::eq(tstr, ~"X") {
} else if tstr == ~"X" {
ty_hex(case_upper)
} else if str::eq(tstr, ~"t") {
} else if tstr == ~"t" {
ty_bits
} else if str::eq(tstr, ~"o") {
} else if tstr == ~"o" {
ty_octal
} else if str::eq(tstr, ~"f") {
} else if tstr == ~"f" {
ty_float
} else if str::eq(tstr, ~"?") {
} else if tstr == ~"?" {
ty_poly
} else { error(~"unknown type in conversion: " + tstr) };
return {ty: t, next: i + 1u};

View File

@ -19,18 +19,18 @@ const max_value: T = min_value - 1 as T;
pure fn min(&&x: T, &&y: T) -> T { if x < y { x } else { y } }
pure fn max(&&x: T, &&y: T) -> T { if x > y { x } else { y } }
pure fn add(&&x: T, &&y: T) -> T { x + y }
pure fn sub(&&x: T, &&y: T) -> T { x - y }
pure fn mul(&&x: T, &&y: T) -> T { x * y }
pure fn div(&&x: T, &&y: T) -> T { x / y }
pure fn rem(&&x: T, &&y: T) -> T { x % y }
pure fn add(x: &T, y: &T) -> T { *x + *y }
pure fn sub(x: &T, y: &T) -> T { *x - *y }
pure fn mul(x: &T, y: &T) -> T { *x * *y }
pure fn div(x: &T, y: &T) -> T { *x / *y }
pure fn rem(x: &T, y: &T) -> T { *x % *y }
pure fn lt(&&x: T, &&y: T) -> bool { x < y }
pure fn le(&&x: T, &&y: T) -> bool { x <= y }
pure fn eq(&&x: T, &&y: T) -> bool { x == y }
pure fn ne(&&x: T, &&y: T) -> bool { x != y }
pure fn ge(&&x: T, &&y: T) -> bool { x >= y }
pure fn gt(&&x: T, &&y: T) -> bool { x > y }
pure fn lt(x: &T, y: &T) -> bool { *x < *y }
pure fn le(x: &T, y: &T) -> bool { *x <= *y }
pure fn eq(x: &T, y: &T) -> bool { *x == *y }
pure fn ne(x: &T, y: &T) -> bool { *x != *y }
pure fn ge(x: &T, y: &T) -> bool { *x >= *y }
pure fn gt(x: &T, y: &T) -> bool { *x > *y }
pure fn is_positive(x: T) -> bool { x > 0 as T }
pure fn is_negative(x: T) -> bool { x < 0 as T }
@ -221,12 +221,11 @@ fn test_parse_buf() {
#[test]
fn test_to_str() {
import str::eq;
assert (eq(to_str(0 as T, 10u), ~"0"));
assert (eq(to_str(1 as T, 10u), ~"1"));
assert (eq(to_str(-1 as T, 10u), ~"-1"));
assert (eq(to_str(127 as T, 16u), ~"7f"));
assert (eq(to_str(100 as T, 10u), ~"100"));
assert (to_str(0 as T, 10u) == ~"0");
assert (to_str(1 as T, 10u) == ~"1");
assert (to_str(-1 as T, 10u) == ~"-1");
assert (to_str(127 as T, 16u) == ~"7f");
assert (to_str(100 as T, 10u) == ~"100");
}
#[test]

View File

@ -7,7 +7,7 @@ const bits: T = 32 as T;
const bits: T = 64 as T;
/// Produce a uint suitable for use in a hash table
pure fn hash(&&x: int) -> uint { return x as uint; }
pure fn hash(x: &int) -> uint { *x as uint }
/// Returns `base` raised to the power of `exponent`
fn pow(base: int, exponent: uint) -> int {

View File

@ -811,7 +811,7 @@ mod tests {
let inp: io::reader = result::get(io::file_reader(tmpfile));
let frood2: ~str = inp.read_c_str();
log(debug, frood2);
assert (str::eq(frood, frood2));
assert frood == frood2;
}
#[test]

View File

@ -579,7 +579,7 @@ fn list_dir(p: path) -> ~[~str] {
}
do rustrt::rust_list_files(star(p)).filter |filename| {
!str::eq(filename, ~".") && !str::eq(filename, ~"..")
filename != ~"." && filename != ~".."
}
}

View File

@ -637,8 +637,8 @@ pure fn replace(s: &str, from: &str, to: &str) -> ~str {
Section: Comparing strings
*/
/// Bytewise string equality
pure fn eq(&&a: ~str, &&b: ~str) -> bool {
/// Bytewise slice equality
pure fn eq_slice(a: &str, b: &str) -> bool {
// FIXME (#2627): This should just be "a == b" but that calls into the
// shape code.
let a_len = a.len();
@ -655,12 +655,17 @@ pure fn eq(&&a: ~str, &&b: ~str) -> bool {
return true;
}
/// Bytewise string equality
pure fn eq(a: &~str, b: &~str) -> bool {
eq_slice(*a, *b)
}
/// Bytewise less than or equal
pure fn le(&&a: ~str, &&b: ~str) -> bool { a <= b }
pure fn le(a: &~str, b: &~str) -> bool { *a <= *b }
/// String hash function
pure fn hash(&&s: ~str) -> uint {
let x = do as_bytes(s) |bytes| {
pure fn hash(s: &~str) -> uint {
let x = do as_bytes(*s) |bytes| {
hash::hash_bytes(bytes)
};
return x as uint;
@ -2070,17 +2075,17 @@ mod tests {
#[test]
fn test_eq() {
assert (eq(~"", ~""));
assert (eq(~"foo", ~"foo"));
assert (!eq(~"foo", ~"bar"));
assert (eq(&~"", &~""));
assert (eq(&~"foo", &~"foo"));
assert (!eq(&~"foo", &~"bar"));
}
#[test]
fn test_le() {
assert (le(~"", ~""));
assert (le(~"", ~"foo"));
assert (le(~"foo", ~"foo"));
assert (!eq(~"foo", ~"bar"));
assert (le(&~"", &~""));
assert (le(&~"", &~"foo"));
assert (le(&~"foo", &~"foo"));
assert (!eq(&~"foo", &~"bar"));
}
#[test]
@ -2220,7 +2225,7 @@ mod tests {
fn test_split_str() {
fn t(s: ~str, sep: &a/str, i: int, k: ~str) {
let v = split_str(s, sep);
assert eq(v[i], k);
assert v[i] == k;
}
t(~"--1233345--", ~"12345", 0, ~"--1233345--");
@ -2348,7 +2353,7 @@ mod tests {
#[test]
fn test_substr() {
fn t(a: ~str, b: ~str, start: int) {
assert (eq(substr(a, start as uint, len(b)), b));
assert substr(a, start as uint, len(b)) == b;
}
t(~"hello", ~"llo", 2);
t(~"hello", ~"el", 1);
@ -2357,7 +2362,7 @@ mod tests {
#[test]
fn test_concat() {
fn t(v: ~[~str], s: ~str) { assert (eq(concat(v), s)); }
fn t(v: ~[~str], s: ~str) { assert concat(v) == s; }
t(~[~"you", ~"know", ~"I'm", ~"no", ~"good"], ~"youknowI'mnogood");
let v: ~[~str] = ~[];
t(v, ~"");
@ -2367,7 +2372,7 @@ mod tests {
#[test]
fn test_connect() {
fn t(v: ~[~str], sep: ~str, s: ~str) {
assert (eq(connect(v, sep), s));
assert connect(v, sep) == s;
}
t(~[~"you", ~"know", ~"I'm", ~"no", ~"good"],
~" ", ~"you know I'm no good");
@ -2385,7 +2390,7 @@ mod tests {
let input = ~"abcDEF" + unicode + ~"xyz:.;";
let expected = ~"ABCDEF" + unicode + ~"XYZ:.;";
let actual = to_upper(input);
assert (eq(expected, actual));
assert expected == actual;
}
#[test]
@ -2398,9 +2403,9 @@ mod tests {
#[test]
fn test_unsafe_slice() {
unsafe {
assert (eq(~"ab", unsafe::slice_bytes(~"abc", 0u, 2u)));
assert (eq(~"bc", unsafe::slice_bytes(~"abc", 1u, 3u)));
assert (eq(~"", unsafe::slice_bytes(~"abc", 1u, 1u)));
assert ~"ab" == unsafe::slice_bytes(~"abc", 0u, 2u);
assert ~"bc" == unsafe::slice_bytes(~"abc", 1u, 3u);
assert ~"" == unsafe::slice_bytes(~"abc", 1u, 1u);
fn a_million_letter_a() -> ~str {
let mut i = 0;
let mut rs = ~"";
@ -2413,9 +2418,8 @@ mod tests {
while i < 100000 { push_str(rs, ~"aaaaa"); i += 1; }
return rs;
}
assert eq(half_a_million_letter_a(),
unsafe::slice_bytes(a_million_letter_a(),
0u, 500000u));
assert half_a_million_letter_a() ==
unsafe::slice_bytes(a_million_letter_a(), 0u, 500000u);
}
}
@ -2501,10 +2505,10 @@ mod tests {
#[test]
fn test_slice() {
assert (eq(~"ab", slice(~"abc", 0u, 2u)));
assert (eq(~"bc", slice(~"abc", 1u, 3u)));
assert (eq(~"", slice(~"abc", 1u, 1u)));
assert (eq(~"\u65e5", slice(~"\u65e5\u672c", 0u, 3u)));
assert ~"ab" == slice(~"abc", 0u, 2u);
assert ~"bc" == slice(~"abc", 1u, 3u);
assert ~"" == slice(~"abc", 1u, 1u);
assert ~"\u65e5" == slice(~"\u65e5\u672c", 0u, 3u);
let data = ~"ประเทศไทย中华";
assert ~"" == slice(data, 0u, 3u);
@ -2524,8 +2528,8 @@ mod tests {
while i < 100000 { push_str(rs, ~"华华华华华"); i += 1; }
return rs;
}
assert eq(half_a_million_letter_X(),
slice(a_million_letter_X(), 0u, 3u * 500000u));
assert half_a_million_letter_X() ==
slice(a_million_letter_X(), 0u, 3u * 500000u);
}
#[test]
@ -2709,7 +2713,7 @@ mod tests {
let s = ~"hello";
let sb = as_buf(s, |b, _l| b);
let s_cstr = unsafe::from_buf(sb);
assert (eq(s_cstr, s));
assert s_cstr == s;
}
}

View File

@ -8,6 +8,7 @@ export pref_align_of;
export refcount;
export log_str;
export lock_and_signal, condition, methods;
export shape_eq, shape_lt, shape_le;
import task::atomically;
@ -39,6 +40,20 @@ extern mod rusti {
fn min_align_of<T>() -> uint;
}
/// Compares contents of two pointers using the default method.
/// Equivalent to `*x1 == *x2`. Useful for hashtables.
pure fn shape_eq<T>(x1: &T, x2: &T) -> bool {
*x1 == *x2
}
pure fn shape_lt<T>(x1: &T, x2: &T) -> bool {
*x1 < *x2
}
pure fn shape_le<T>(x1: &T, x2: &T) -> bool {
*x1 < *x2
}
/**
* Returns a pointer to a type descriptor.
*

View File

@ -19,18 +19,18 @@ const max_value: T = 0 as T - 1 as T;
pure fn min(&&x: T, &&y: T) -> T { if x < y { x } else { y } }
pure fn max(&&x: T, &&y: T) -> T { if x > y { x } else { y } }
pure fn add(&&x: T, &&y: T) -> T { x + y }
pure fn sub(&&x: T, &&y: T) -> T { x - y }
pure fn mul(&&x: T, &&y: T) -> T { x * y }
pure fn div(&&x: T, &&y: T) -> T { x / y }
pure fn rem(&&x: T, &&y: T) -> T { x % y }
pure fn add(x: &T, y: &T) -> T { *x + *y }
pure fn sub(x: &T, y: &T) -> T { *x - *y }
pure fn mul(x: &T, y: &T) -> T { *x * *y }
pure fn div(x: &T, y: &T) -> T { *x / *y }
pure fn rem(x: &T, y: &T) -> T { *x % *y }
pure fn lt(&&x: T, &&y: T) -> bool { x < y }
pure fn le(&&x: T, &&y: T) -> bool { x <= y }
pure fn eq(&&x: T, &&y: T) -> bool { x == y }
pure fn ne(&&x: T, &&y: T) -> bool { x != y }
pure fn ge(&&x: T, &&y: T) -> bool { x >= y }
pure fn gt(&&x: T, &&y: T) -> bool { x > y }
pure fn lt(x: &T, y: &T) -> bool { *x < *y }
pure fn le(x: &T, y: &T) -> bool { *x <= *y }
pure fn eq(x: &T, y: &T) -> bool { *x == *y }
pure fn ne(x: &T, y: &T) -> bool { *x != *y }
pure fn ge(x: &T, y: &T) -> bool { *x >= *y }
pure fn gt(x: &T, y: &T) -> bool { *x > *y }
pure fn is_positive(x: T) -> bool { x > 0 as T }
pure fn is_negative(x: T) -> bool { x < 0 as T }

View File

@ -13,9 +13,9 @@ type T = uint;
* The smallest integer `q` such that `x/y <= q`.
*/
pure fn div_ceil(x: uint, y: uint) -> uint {
let div = div(x, y);
if x % y == 0u { return div;}
else { return div + 1u; }
let div = x / y;
if x % y == 0u { div }
else { div + 1u }
}
/**
@ -31,9 +31,9 @@ pure fn div_ceil(x: uint, y: uint) -> uint {
* The integer `q` closest to `x/y`.
*/
pure fn div_round(x: uint, y: uint) -> uint {
let div = div(x, y);
if x % y * 2u < y { return div;}
else { return div + 1u; }
let div = x / y;
if x % y * 2u < y { div }
else { div + 1u }
}
/**
@ -54,7 +54,7 @@ pure fn div_round(x: uint, y: uint) -> uint {
pure fn div_floor(x: uint, y: uint) -> uint { return x / y; }
/// Produce a uint suitable for use in a hash table
pure fn hash(&&x: uint) -> uint { return x; }
pure fn hash(x: &uint) -> uint { *x }
/**
* Iterate over the range [`lo`..`hi`), or stop when requested

View File

@ -1654,13 +1654,13 @@ mod u8 {
export memcpy, memmove;
/// Bytewise string comparison
pure fn cmp(&&a: ~[u8], &&b: ~[u8]) -> int {
let a_len = len(a);
let b_len = len(b);
pure fn cmp(a: &~[u8], b: &~[u8]) -> int {
let a_len = len(*a);
let b_len = len(*b);
let n = uint::min(a_len, b_len) as libc::size_t;
let r = unsafe {
libc::memcmp(unsafe::to_ptr(a) as *libc::c_void,
unsafe::to_ptr(b) as *libc::c_void, n) as int
libc::memcmp(unsafe::to_ptr(*a) as *libc::c_void,
unsafe::to_ptr(*b) as *libc::c_void, n) as int
};
if r != 0 { r } else {
@ -1675,26 +1675,26 @@ mod u8 {
}
/// Bytewise less than or equal
pure fn lt(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) < 0 }
pure fn lt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) < 0 }
/// Bytewise less than or equal
pure fn le(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) <= 0 }
pure fn le(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) <= 0 }
/// Bytewise equality
pure fn eq(&&a: ~[u8], &&b: ~[u8]) -> bool { unsafe { cmp(a, b) == 0 } }
pure fn eq(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) == 0 }
/// Bytewise inequality
pure fn ne(&&a: ~[u8], &&b: ~[u8]) -> bool { unsafe { cmp(a, b) != 0 } }
pure fn ne(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) != 0 }
/// Bytewise greater than or equal
pure fn ge(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) >= 0 }
pure fn ge(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) >= 0 }
/// Bytewise greater than
pure fn gt(&&a: ~[u8], &&b: ~[u8]) -> bool { cmp(a, b) > 0 }
pure fn gt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) > 0 }
/// Byte-vec hash function
fn hash(&&s: ~[u8]) -> uint {
hash::hash_bytes(s) as uint
fn hash(s: &~[u8]) -> uint {
hash::hash_bytes(*s) as uint
}
/**

View File

@ -391,8 +391,7 @@ class bitv {
* Each uint in the resulting vector has either value 0u or 1u.
*/
fn to_vec() -> ~[uint] {
let sub = |x| self.init_to_vec(x);
return vec::from_fn::<uint>(self.nbits, sub);
vec::from_fn(self.nbits, |x| self.init_to_vec(x))
}
/**

View File

@ -201,7 +201,7 @@ fn getopts(args: ~[~str], opts: ~[opt]) -> result unsafe {
let curlen = str::len(cur);
if !is_arg(cur) {
vec::push(free, cur);
} else if str::eq(cur, ~"--") {
} else if cur == ~"--" {
let mut j = i + 1u;
while j < l { vec::push(free, args[j]); j += 1u; }
break;

View File

@ -588,18 +588,24 @@ impl of to_json for @~str {
fn to_json() -> json { string(self) }
}
impl <A: to_json copy, B: to_json copy> of to_json for (A, B) {
impl <A: to_json, B: to_json> of to_json for (A, B) {
fn to_json() -> json {
let (a, b) = self;
list(@~[a.to_json(), b.to_json()])
alt self {
(a, b) => {
list(@~[a.to_json(), b.to_json()])
}
}
}
}
impl <A: to_json copy, B: to_json copy, C: to_json copy>
impl <A: to_json, B: to_json, C: to_json>
of to_json for (A, B, C) {
fn to_json() -> json {
let (a, b, c) = self;
list(@~[a.to_json(), b.to_json(), c.to_json()])
alt self {
(a, b, c) => {
list(@~[a.to_json(), b.to_json(), c.to_json()])
}
}
}
}

View File

@ -1,5 +1,7 @@
//! A map type
#[warn(deprecated_mode)];
import chained::hashmap;
import io::writer_util;
import to_str::to_str;
@ -15,16 +17,16 @@ export vec_from_set;
*
* The hash should concentrate entropy in the lower bits.
*/
type hashfn<K> = fn@(K) -> uint;
type hashfn<K> = fn~(key: &K) -> uint;
type eqfn<K> = fn@(K, K) -> bool;
type eqfn<K> = fn~(key1: &K, key2: &K) -> bool;
/// A convenience type to treat a hashmap as a set
type set<K> = hashmap<K, ()>;
type hashmap<K, V> = chained::t<K, V>;
trait map<K, V: copy> {
trait map<K: copy, V: copy> {
/// Return the number of elements in the map
fn size() -> uint;
@ -39,40 +41,50 @@ trait map<K, V: copy> {
fn insert(+K, +V) -> bool;
/// Returns true if the map contains a value for the specified key
fn contains_key(K) -> bool;
fn contains_key(+key: K) -> bool;
/// Returns true if the map contains a value for the specified
/// key, taking the key by reference.
fn contains_key_ref(key: &K) -> bool;
/**
* Get the value for the specified key. Fails if the key does not exist in
* the map.
*/
fn get(K) -> V;
/// Like get, but as an operator.
fn [](K) -> V;
fn get(+key: K) -> V;
/**
* Get the value for the specified key. If the key does not exist in
* the map then returns none.
*/
fn find(K) -> option<V>;
fn find(+key: K) -> option<V>;
/**
* Remove and return a value from the map. If the key does not exist
* in the map then returns none.
*/
fn remove(K) -> option<V>;
fn remove(+key: K) -> option<V>;
/// Clear the map, removing all key/value pairs.
fn clear();
/// Iterate over all the key/value pairs in the map
fn each(fn(K, V) -> bool);
/// Iterate over all the key/value pairs in the map by value
fn each(fn(+key: K, +value: V) -> bool);
/// Iterate over all the keys in the map
fn each_key(fn(K) -> bool);
/// Iterate over all the keys in the map by value
fn each_key(fn(+key: K) -> bool);
/// Iterate over all the values in the map
fn each_value(fn(V) -> bool);
/// Iterate over all the values in the map by value
fn each_value(fn(+value: V) -> bool);
/// Iterate over all the key/value pairs in the map by reference
fn each_ref(fn(key: &K, value: &V) -> bool);
/// Iterate over all the keys in the map by reference
fn each_key_ref(fn(key: &K) -> bool);
/// Iterate over all the values in the map by reference
fn each_value_ref(fn(value: &V) -> bool);
}
mod util {
@ -93,53 +105,43 @@ mod chained {
const initial_capacity: uint = 32u; // 2^5
type entry<K, V> = {
hash: uint,
key: K,
mut value: V,
mut next: chain<K, V>
};
enum chain<K, V> {
present(@entry<K, V>),
absent
struct entry<K, V> {
hash: uint;
key: K;
value: V;
mut next: option<@entry<K, V>>;
}
struct hashmap_<K, V> {
mut count: uint;
mut chains: ~[mut option<@entry<K,V>>];
hasher: hashfn<K>;
eqer: eqfn<K>;
}
type hashmap__<K, V> = {
mut count: uint,
mut chains: ~[mut chain<K,V>],
hasher: hashfn<K>,
eqer: eqfn<K>
};
type t<K, V> = @hashmap_<K, V>;
enum hashmap_<K, V> {
hashmap_(@hashmap__<K, V>)
}
type t<K, V> = hashmap_<K, V>;
enum search_result<K, V> {
not_found,
found_first(uint, @entry<K,V>),
found_after(@entry<K,V>, @entry<K,V>)
}
impl private_methods<K, V: copy> for hashmap_<K, V> {
fn search_rem(k: K, h: uint, idx: uint,
impl private_methods<K, V: copy> for t<K, V> {
fn search_rem(k: &K, h: uint, idx: uint,
e_root: @entry<K,V>) -> search_result<K,V> {
let mut e0 = e_root;
let mut comp = 1u; // for logging
loop {
alt copy e0.next {
absent {
none {
debug!{"search_tbl: absent, comp %u, hash %u, idx %u",
comp, h, idx};
return not_found;
}
present(e1) {
some(e1) {
comp += 1u;
if e1.hash == h && self.eqer(e1.key, k) {
if e1.hash == h && self.eqer(&e1.key, k) {
debug!{"search_tbl: present, comp %u, \
hash %u, idx %u",
comp, h, idx};
@ -152,16 +154,16 @@ mod chained {
};
}
fn search_tbl(k: K, h: uint) -> search_result<K,V> {
fn search_tbl(k: &K, h: uint) -> search_result<K,V> {
let idx = h % vec::len(self.chains);
alt copy self.chains[idx] {
absent {
debug!{"search_tbl: absent, comp %u, hash %u, idx %u",
none {
debug!{"search_tbl: none, comp %u, hash %u, idx %u",
0u, h, idx};
return not_found;
}
present(e) {
if e.hash == h && self.eqer(e.key, k) {
some(e) {
if e.hash == h && self.eqer(&e.key, k) {
debug!{"search_tbl: present, comp %u, hash %u, idx %u",
1u, h, idx};
return found_first(idx, e);
@ -173,25 +175,27 @@ mod chained {
}
fn rehash() {
let n_old_chains = vec::len(self.chains);
let n_old_chains = self.chains.len();
let n_new_chains: uint = uint::next_power_of_two(n_old_chains+1u);
let new_chains = chains(n_new_chains);
for self.each_entry |entry| {
let idx = entry.hash % n_new_chains;
entry.next = new_chains[idx];
new_chains[idx] = present(entry);
new_chains[idx] = some(entry);
}
self.chains = new_chains;
}
fn each_entry(blk: fn(@entry<K,V>) -> bool) {
let mut i = 0u, n = vec::len(self.chains);
// n.b. we can't use vec::iter() here because self.chains
// is stored in a mutable location.
let mut i = 0u, n = self.chains.len();
while i < n {
let mut chain = self.chains[i];
loop {
chain = alt chain {
absent { break; }
present(entry) {
none { break; }
some(entry) {
let next = entry.next;
if !blk(entry) { return; }
next
@ -203,10 +207,14 @@ mod chained {
}
}
impl hashmap<K, V: copy> of map<K, V> for t<K, V> {
impl hashmap<K: copy, V: copy> of map<K, V> for t<K, V> {
fn size() -> uint { self.count }
fn contains_key(k: K) -> bool {
fn contains_key(+k: K) -> bool {
self.contains_key_ref(&k)
}
fn contains_key_ref(k: &K) -> bool {
let hash = self.hasher(k);
alt self.search_tbl(k, hash) {
not_found {false}
@ -215,17 +223,17 @@ mod chained {
}
fn insert(+k: K, +v: V) -> bool {
let hash = self.hasher(k);
alt self.search_tbl(k, hash) {
let hash = self.hasher(&k);
alt self.search_tbl(&k, hash) {
not_found {
self.count += 1u;
let idx = hash % vec::len(self.chains);
let old_chain = self.chains[idx];
self.chains[idx] = present(@{
self.chains[idx] = some(@entry {
hash: hash,
key: k,
mut value: v,
mut next: old_chain});
value: v,
next: old_chain});
// consider rehashing if more 3/4 full
let nchains = vec::len(self.chains);
@ -237,38 +245,43 @@ mod chained {
return true;
}
found_first(_, entry) {
entry.value = v;
found_first(idx, entry) {
self.chains[idx] = some(@entry {
hash: hash,
key: k,
value: v,
next: entry.next});
return false;
}
found_after(_, entry) {
entry.value = v;
return false
found_after(prev, entry) {
prev.next = some(@entry {
hash: hash,
key: k,
value: v,
next: entry.next});
return false;
}
}
}
fn find(k: K) -> option<V> {
alt self.search_tbl(k, self.hasher(k)) {
fn find(+k: K) -> option<V> {
alt self.search_tbl(&k, self.hasher(&k)) {
not_found {none}
found_first(_, entry) {some(entry.value)}
found_after(_, entry) {some(entry.value)}
}
}
fn get(k: K) -> V {
alt self.find(k) {
some(v) => {v}
none => {fail fmt!{"Key not found in table: %?", k}}
fn get(+k: K) -> V {
let opt_v = self.find(k);
if opt_v.is_none() {
fail fmt!{"Key not found in table: %?", k};
}
option::unwrap(opt_v)
}
fn [](k: K) -> V {
self.get(k)
}
fn remove(k: K) -> option<V> {
alt self.search_tbl(k, self.hasher(k)) {
fn remove(+k: K) -> option<V> {
alt self.search_tbl(&k, self.hasher(&k)) {
not_found {none}
found_first(idx, entry) {
self.count -= 1u;
@ -288,18 +301,34 @@ mod chained {
self.chains = chains(initial_capacity);
}
fn each(blk: fn(K,V) -> bool) {
fn each(blk: fn(+key: K, +value: V) -> bool) {
self.each_ref(|k, v| blk(*k, *v))
}
fn each_key(blk: fn(+key: K) -> bool) {
self.each_key_ref(|p| blk(*p))
}
fn each_value(blk: fn(+value: V) -> bool) {
self.each_value_ref(|p| blk(*p))
}
fn each_ref(blk: fn(key: &K, value: &V) -> bool) {
for self.each_entry |entry| {
if !blk(entry.key, copy entry.value) { break; }
if !blk(&entry.key, &entry.value) { break; }
}
}
fn each_key(blk: fn(K) -> bool) { self.each(|k, _v| blk(k)) }
fn each_key_ref(blk: fn(key: &K) -> bool) {
self.each_ref(|k, _v| blk(k))
}
fn each_value(blk: fn(V) -> bool) { self.each(|_k, v| blk(v)) }
fn each_value_ref(blk: fn(value: &V) -> bool) {
self.each_ref(|_k, v| blk(v))
}
}
impl hashmap<K: to_str, V: to_str copy> of to_str for hashmap_<K, V> {
impl hashmap<K: copy to_str, V: to_str copy> of to_str for t<K, V> {
fn to_writer(wr: io::writer) {
if self.count == 0u {
wr.write_str("{}");
@ -325,24 +354,23 @@ mod chained {
}
}
impl hashmap<K, V: copy> of ops::index<K, V> for t<K, V> {
pure fn index(k: K) -> V {
impl hashmap<K: copy, V: copy> of ops::index<K, V> for t<K, V> {
pure fn index(&&k: K) -> V {
unchecked {
self.get(k)
}
}
}
fn chains<K,V>(nchains: uint) -> ~[mut chain<K,V>] {
return vec::to_mut(vec::from_elem(nchains, absent));
fn chains<K,V>(nchains: uint) -> ~[mut option<@entry<K,V>>] {
vec::to_mut(vec::from_elem(nchains, none))
}
fn mk<K, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>) -> t<K,V> {
let slf: t<K, V> = hashmap_(@{mut count: 0u,
mut chains: chains(initial_capacity),
fn mk<K, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>) -> t<K,V> {
let slf: t<K, V> = @hashmap_ {count: 0u,
chains: chains(initial_capacity),
hasher: hasher,
eqer: eqer});
eqer: eqer};
slf
}
}
@ -357,7 +385,7 @@ Parameters:
hasher - The hash function for key type K
eqer - The equality function for key type K
*/
fn hashmap<K: const, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>)
fn hashmap<K: const, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>)
-> hashmap<K, V> {
chained::mk(hasher, eqer)
}
@ -369,7 +397,8 @@ fn str_hash<V: copy>() -> hashmap<~str, V> {
/// Construct a hashmap for boxed string keys
fn box_str_hash<V: copy>() -> hashmap<@~str, V> {
return hashmap(|x: @~str| str::hash(*x), |x,y| str::eq(*x,*y));
hashmap(|x: &@~str| str::hash(&**x),
|x: &@~str, y: &@~str| str::eq(&**x, &**y))
}
/// Construct a hashmap for byte string keys
@ -388,13 +417,14 @@ fn uint_hash<V: copy>() -> hashmap<uint, V> {
}
/// Convenience function for adding keys to a hashmap with nil type keys
fn set_add<K: const copy>(set: set<K>, key: K) -> bool {
return set.insert(key, ());
fn set_add<K: const copy>(set: set<K>, +key: K) -> bool {
set.insert(key, ())
}
/// Convert a set into a vector.
fn vec_from_set<T: copy>(s: set<T>) -> ~[T] {
let mut v = ~[];
vec::reserve(v, s.size());
do s.each_key() |k| {
vec::push(v, k);
true
@ -403,8 +433,8 @@ fn vec_from_set<T: copy>(s: set<T>) -> ~[T] {
}
/// Construct a hashmap from a vector
fn hash_from_vec<K: const copy, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>,
items: ~[(K, V)]) -> hashmap<K, V> {
fn hash_from_vec<K: const copy, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>,
items: &[(K, V)]) -> hashmap<K, V> {
let map = hashmap(hasher, eqer);
do vec::iter(items) |item| {
let (key, value) = item;
@ -414,22 +444,22 @@ fn hash_from_vec<K: const copy, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>,
}
/// Construct a hashmap from a vector with string keys
fn hash_from_strs<V: copy>(items: ~[(~str, V)]) -> hashmap<~str, V> {
fn hash_from_strs<V: copy>(items: &[(~str, V)]) -> hashmap<~str, V> {
hash_from_vec(str::hash, str::eq, items)
}
/// Construct a hashmap from a vector with byte keys
fn hash_from_bytes<V: copy>(items: ~[(~[u8], V)]) -> hashmap<~[u8], V> {
fn hash_from_bytes<V: copy>(items: &[(~[u8], V)]) -> hashmap<~[u8], V> {
hash_from_vec(vec::u8::hash, vec::u8::eq, items)
}
/// Construct a hashmap from a vector with int keys
fn hash_from_ints<V: copy>(items: ~[(int, V)]) -> hashmap<int, V> {
fn hash_from_ints<V: copy>(items: &[(int, V)]) -> hashmap<int, V> {
hash_from_vec(int::hash, int::eq, items)
}
/// Construct a hashmap from a vector with uint keys
fn hash_from_uints<V: copy>(items: ~[(uint, V)]) -> hashmap<uint, V> {
fn hash_from_uints<V: copy>(items: &[(uint, V)]) -> hashmap<uint, V> {
hash_from_vec(uint::hash, uint::eq, items)
}
@ -439,15 +469,15 @@ mod tests {
#[test]
fn test_simple() {
debug!{"*** starting test_simple"};
fn eq_uint(&&x: uint, &&y: uint) -> bool { return x == y; }
fn uint_id(&&x: uint) -> uint { x }
pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y }
pure fn uint_id(x: &uint) -> uint { *x }
let hasher_uint: map::hashfn<uint> = uint_id;
let eqer_uint: map::eqfn<uint> = eq_uint;
let hasher_str: map::hashfn<~str> = str::hash;
let eqer_str: map::eqfn<~str> = str::eq;
debug!{"uint -> uint"};
let hm_uu: map::hashmap<uint, uint> =
map::hashmap::<uint, uint>(hasher_uint, eqer_uint);
map::hashmap::<uint, uint>(copy hasher_uint, copy eqer_uint);
assert (hm_uu.insert(10u, 12u));
assert (hm_uu.insert(11u, 13u));
assert (hm_uu.insert(12u, 14u));
@ -463,7 +493,7 @@ mod tests {
let twelve: ~str = ~"twelve";
debug!{"str -> uint"};
let hm_su: map::hashmap<~str, uint> =
map::hashmap::<~str, uint>(hasher_str, eqer_str);
map::hashmap::<~str, uint>(copy hasher_str, copy eqer_str);
assert (hm_su.insert(~"ten", 12u));
assert (hm_su.insert(eleven, 13u));
assert (hm_su.insert(~"twelve", 14u));
@ -477,30 +507,30 @@ mod tests {
assert (hm_su.get(~"twelve") == 12u);
debug!{"uint -> str"};
let hm_us: map::hashmap<uint, ~str> =
map::hashmap::<uint, ~str>(hasher_uint, eqer_uint);
map::hashmap::<uint, ~str>(copy hasher_uint, copy eqer_uint);
assert (hm_us.insert(10u, ~"twelve"));
assert (hm_us.insert(11u, ~"thirteen"));
assert (hm_us.insert(12u, ~"fourteen"));
assert (str::eq(hm_us.get(11u), ~"thirteen"));
assert (str::eq(hm_us.get(12u), ~"fourteen"));
assert (str::eq(hm_us.get(10u), ~"twelve"));
assert hm_us.get(11u) == ~"thirteen";
assert hm_us.get(12u) == ~"fourteen";
assert hm_us.get(10u) == ~"twelve";
assert (!hm_us.insert(12u, ~"fourteen"));
assert (str::eq(hm_us.get(12u), ~"fourteen"));
assert hm_us.get(12u) == ~"fourteen";
assert (!hm_us.insert(12u, ~"twelve"));
assert (str::eq(hm_us.get(12u), ~"twelve"));
assert hm_us.get(12u) == ~"twelve";
debug!{"str -> str"};
let hm_ss: map::hashmap<~str, ~str> =
map::hashmap::<~str, ~str>(hasher_str, eqer_str);
map::hashmap::<~str, ~str>(copy hasher_str, copy eqer_str);
assert (hm_ss.insert(ten, ~"twelve"));
assert (hm_ss.insert(eleven, ~"thirteen"));
assert (hm_ss.insert(twelve, ~"fourteen"));
assert (str::eq(hm_ss.get(~"eleven"), ~"thirteen"));
assert (str::eq(hm_ss.get(~"twelve"), ~"fourteen"));
assert (str::eq(hm_ss.get(~"ten"), ~"twelve"));
assert hm_ss.get(~"eleven") == ~"thirteen";
assert hm_ss.get(~"twelve") == ~"fourteen";
assert hm_ss.get(~"ten") == ~"twelve";
assert (!hm_ss.insert(~"twelve", ~"fourteen"));
assert (str::eq(hm_ss.get(~"twelve"), ~"fourteen"));
assert hm_ss.get(~"twelve") == ~"fourteen";
assert (!hm_ss.insert(~"twelve", ~"twelve"));
assert (str::eq(hm_ss.get(~"twelve"), ~"twelve"));
assert hm_ss.get(~"twelve") == ~"twelve";
debug!{"*** finished test_simple"};
}
@ -512,8 +542,8 @@ mod tests {
fn test_growth() {
debug!{"*** starting test_growth"};
let num_to_insert: uint = 64u;
fn eq_uint(&&x: uint, &&y: uint) -> bool { return x == y; }
fn uint_id(&&x: uint) -> uint { x }
pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y }
pure fn uint_id(x: &uint) -> uint { *x }
debug!{"uint -> uint"};
let hasher_uint: map::hashfn<uint> = uint_id;
let eqer_uint: map::eqfn<uint> = eq_uint;
@ -560,22 +590,20 @@ mod tests {
debug!{"get(\"%s\") = \"%s\"",
uint::to_str(i, 2u),
hm_ss.get(uint::to_str(i, 2u))};
assert (str::eq(hm_ss.get(uint::to_str(i, 2u)),
uint::to_str(i * i, 2u)));
assert hm_ss.get(uint::to_str(i, 2u)) == uint::to_str(i * i, 2u);
i += 1u;
}
assert (hm_ss.insert(uint::to_str(num_to_insert, 2u),
uint::to_str(17u, 2u)));
assert (str::eq(hm_ss.get(uint::to_str(num_to_insert, 2u)),
uint::to_str(17u, 2u)));
assert hm_ss.get(uint::to_str(num_to_insert, 2u)) ==
uint::to_str(17u, 2u);
debug!{"-----"};
i = 0u;
while i < num_to_insert {
debug!{"get(\"%s\") = \"%s\"",
uint::to_str(i, 2u),
hm_ss.get(uint::to_str(i, 2u))};
assert (str::eq(hm_ss.get(uint::to_str(i, 2u)),
uint::to_str(i * i, 2u)));
assert hm_ss.get(uint::to_str(i, 2u)) == uint::to_str(i * i, 2u);
i += 1u;
}
debug!{"*** finished test_growth"};
@ -585,16 +613,15 @@ mod tests {
fn test_removal() {
debug!{"*** starting test_removal"};
let num_to_insert: uint = 64u;
fn eq(&&x: uint, &&y: uint) -> bool { return x == y; }
fn hash(&&u: uint) -> uint {
fn eq(x: &uint, y: &uint) -> bool { *x == *y }
fn hash(u: &uint) -> uint {
// This hash function intentionally causes collisions between
// consecutive integer pairs.
return u / 2u * 2u;
*u / 2u * 2u
}
assert (hash(0u) == hash(1u));
assert (hash(2u) == hash(3u));
assert (hash(0u) != hash(2u));
assert (hash(&0u) == hash(&1u));
assert (hash(&2u) == hash(&3u));
assert (hash(&0u) != hash(&2u));
let hasher: map::hashfn<uint> = hash;
let eqer: map::eqfn<uint> = eq;
let hm: map::hashmap<uint, uint> =

View File

@ -74,8 +74,10 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> {
insert(self, key, value);
return !exists;
}
fn remove(&&key: uint) -> option<V> {
if key >= self.v.len() { return none; }
fn remove(+key: uint) -> option<V> {
if key >= self.v.len() {
return none;
}
let old = self.v.get_elt(key);
self.v.set_elt(key, none);
old
@ -83,14 +85,16 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> {
fn clear() {
self.v.set(~[mut]);
}
fn contains_key(&&key: uint) -> bool {
fn contains_key(+key: uint) -> bool {
contains_key(self, key)
}
fn get(&&key: uint) -> V { get(self, key) }
fn [](&&key: uint) -> V { get(self, key) }
fn find(&&key: uint) -> option<V> { find(self, key) }
fn contains_key_ref(key: &uint) -> bool {
contains_key(self, *key)
}
fn get(+key: uint) -> V { get(self, key) }
fn find(+key: uint) -> option<V> { find(self, key) }
fn rehash() { fail }
fn each(it: fn(&&uint, V) -> bool) {
fn each(it: fn(+key: uint, +value: V) -> bool) {
let mut idx = 0u, l = self.v.len();
while idx < l {
alt self.v.get_elt(idx) {
@ -102,15 +106,29 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> {
idx += 1u;
}
}
fn each_key(it: fn(&&uint) -> bool) {
fn each_key(it: fn(+key: uint) -> bool) {
self.each(|k, _v| it(k))
}
fn each_value(it: fn(+value: V) -> bool) {
self.each(|_k, v| it(v))
}
fn each_ref(it: fn(key: &uint, value: &V) -> bool) {
let mut idx = 0u, l = self.v.len();
while idx < l {
if self.v.get_elt(idx) != none && !it(idx) { return; }
alt self.v.get_elt(idx) {
some(elt) {
if !it(&idx, &elt) { break; }
}
none { }
}
idx += 1u;
}
}
fn each_value(it: fn(V) -> bool) {
self.each(|_i, v| it(v));
fn each_key_ref(blk: fn(key: &uint) -> bool) {
self.each_ref(|k, _v| blk(k))
}
fn each_value_ref(blk: fn(value: &V) -> bool) {
self.each_ref(|_k, v| blk(v))
}
}

View File

@ -1,13 +1,13 @@
//! Sorting methods
import vec::{len, push};
import int::{eq, ord};
import core::cmp::{eq, ord};
export le;
export merge_sort;
export quick_sort;
export quick_sort3;
type le<T> = fn(T, T) -> bool;
type le<T> = pure fn(v1: &T, v2: &T) -> bool;
/**
* Merge sort. Returns a new vector containing the sorted list.
@ -43,7 +43,7 @@ fn merge_sort<T: copy>(le: le<T>, v: ~[const T]) -> ~[T] {
let b_len = len(b);
let mut b_ix = 0u;
while a_ix < a_len && b_ix < b_len {
if le(a[a_ix], b[b_ix]) {
if le(&a[a_ix], &b[b_ix]) {
vec::push(rs, a[a_ix]);
a_ix += 1u;
} else { vec::push(rs, b[b_ix]); b_ix += 1u; }
@ -61,7 +61,7 @@ fn part<T: copy>(compare_func: le<T>, arr: ~[mut T], left: uint,
let mut storage_index: uint = left;
let mut i: uint = left;
while i < right {
if compare_func(copy arr[i], pivot_value) {
if compare_func(&arr[i], &pivot_value) {
arr[i] <-> arr[storage_index];
storage_index += 1u;
}
@ -105,19 +105,19 @@ fn qsort3<T: copy>(compare_func_lt: le<T>, compare_func_eq: le<T>,
let mut q: int = j;
loop {
i += 1;
while compare_func_lt(copy arr[i], v) { i += 1; }
while compare_func_lt(&arr[i], &v) { i += 1; }
j -= 1;
while compare_func_lt(v, copy arr[j]) {
while compare_func_lt(&v, &arr[j]) {
if j == left { break; }
j -= 1;
}
if i >= j { break; }
arr[i] <-> arr[j];
if compare_func_eq(copy arr[i], v) {
if compare_func_eq(&arr[i], &v) {
p += 1;
arr[p] <-> arr[i];
}
if compare_func_eq(v, copy arr[j]) {
if compare_func_eq(&v, &arr[j]) {
q -= 1;
arr[j] <-> arr[q];
}
@ -154,9 +154,8 @@ fn qsort3<T: copy>(compare_func_lt: le<T>, compare_func_eq: le<T>,
* This is an unstable sort.
*/
fn quick_sort3<T: copy ord eq>(arr: ~[mut T]) {
if len::<T>(arr) == 0u { return; }
qsort3::<T>(|x, y| x.lt(y), |x, y| x.eq(y), arr, 0,
(len::<T>(arr) as int) - 1);
if arr.len() <= 1 { return; }
qsort3(core::cmp::lt, core::cmp::eq, arr, 0, (arr.len() - 1) as int);
}
#[cfg(test)]
@ -202,9 +201,8 @@ mod test_qsort3 {
mod test_qsort {
fn check_sort(v1: ~[mut int], v2: ~[mut int]) {
let len = vec::len::<int>(v1);
fn leual(&&a: int, &&b: int) -> bool { return a <= b; }
let f = leual;
quick_sort::<int>(f, v1);
pure fn leual(a: &int, b: &int) -> bool { *a <= *b }
quick_sort::<int>(leual, v1);
let mut i = 0u;
while i < len {
log(debug, v2[i]);
@ -245,8 +243,7 @@ mod test_qsort {
let expected = ~[1, 2, 3];
fn le(&&a: int, &&b: int) -> bool { int::le(a, b) }
sort::quick_sort(le, names);
sort::quick_sort(int::le, names);
let immut_names = vec::from_mut(names);
@ -264,7 +261,7 @@ mod tests {
fn check_sort(v1: ~[int], v2: ~[int]) {
let len = vec::len::<int>(v1);
fn le(&&a: int, &&b: int) -> bool { return a <= b; }
pure fn le(a: &int, b: &int) -> bool { *a <= *b }
let f = le;
let v3 = merge_sort::<int>(f, v1);
let mut i = 0u;
@ -294,7 +291,7 @@ mod tests {
#[test]
fn test_merge_sort_mutable() {
fn le(&&a: int, &&b: int) -> bool { return a <= b; }
pure fn le(a: &int, b: &int) -> bool { *a <= *b }
let v1 = ~[mut 3, 2, 1];
let v2 = merge_sort(le, v1);
assert v2 == ~[1, 2, 3];

View File

@ -38,7 +38,7 @@ fn color_supported() -> bool {
return alt os::getenv(~"TERM") {
option::some(env) {
for vec::each(supported_terms) |term| {
if str::eq(term, env) { return true; }
if term == env { return true; }
}
false
}

View File

@ -372,13 +372,12 @@ fn filter_tests(opts: test_opts,
};
// Sort the tests alphabetically
filtered =
{
fn lteq(t1: test_desc, t2: test_desc) -> bool {
str::le(t1.name, t2.name)
}
sort::merge_sort(|x,y| lteq(x, y), filtered)
};
filtered = {
pure fn lteq(t1: &test_desc, t2: &test_desc) -> bool {
str::le(&t1.name, &t2.name)
}
sort::merge_sort(lteq, filtered)
};
return filtered;
}
@ -486,7 +485,7 @@ mod tests {
let args = ~[~"progname", ~"filter"];
let opts = alt parse_opts(args) { either::left(o) { o }
_ { fail ~"Malformed arg in first_free_arg_should_be_a_filter"; } };
assert (str::eq(~"filter", option::get(opts.filter)));
assert ~"filter" == option::get(opts.filter);
}
#[test]

View File

@ -230,18 +230,18 @@ pure fn is_call_expr(e: @expr) -> bool {
alt e.node { expr_call(_, _, _) { true } _ { false } }
}
fn eq_ty(&&a: @ty, &&b: @ty) -> bool { return box::ptr_eq(a, b); }
pure fn eq_ty(a: &@ty, b: &@ty) -> bool { box::ptr_eq(*a, *b) }
fn hash_ty(&&t: @ty) -> uint {
pure fn hash_ty(t: &@ty) -> uint {
let res = (t.span.lo << 16u) + t.span.hi;
return res;
}
fn def_eq(a: ast::def_id, b: ast::def_id) -> bool {
return a.crate == b.crate && a.node == b.node;
pure fn def_eq(a: &ast::def_id, b: &ast::def_id) -> bool {
a.crate == b.crate && a.node == b.node
}
fn hash_def(d: ast::def_id) -> uint {
pure fn hash_def(d: &ast::def_id) -> uint {
let mut h = 5381u;
h = (h << 5u) + h ^ (d.crate as uint);
h = (h << 5u) + h ^ (d.node as uint);

View File

@ -289,15 +289,15 @@ fn last_meta_item_list_by_name(
// FIXME (#607): This needs to sort by meta_item variant in addition to
// the item name (See [Fixme-sorting])
fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] {
fn lteq(&&ma: @ast::meta_item, &&mb: @ast::meta_item) -> bool {
fn key(m: @ast::meta_item) -> ast::ident {
pure fn lteq(ma: &@ast::meta_item, mb: &@ast::meta_item) -> bool {
pure fn key(m: &ast::meta_item) -> ast::ident {
alt m.node {
ast::meta_word(name) { /* FIXME (#2543) */ copy name }
ast::meta_name_value(name, _) { /* FIXME (#2543) */ copy name }
ast::meta_list(name, _) { /* FIXME (#2543) */ copy name }
}
}
return key(ma) <= key(mb);
key(*ma) <= key(*mb)
}
// This is sort of stupid here, converting to a vec of mutables and back

View File

@ -13,10 +13,14 @@ import io::*;
import codemap::span;
type aq_ctxt = @{lo: uint,
gather: dvec<{lo: uint, hi: uint,
e: @ast::expr,
constr: ~str}>};
struct gather_item {
lo: uint;
hi: uint;
e: @ast::expr;
constr: ~str;
}
type aq_ctxt = @{lo: uint, gather: dvec<gather_item>};
enum fragment {
from_expr(@ast::expr),
from_ty(@ast::ty)
@ -110,7 +114,10 @@ fn gather_anti_quotes<N: qq_helper>(lo: uint, node: N) -> aq_ctxt
// FIXME (#2250): Maybe this is an overkill (merge_sort), it might
// be better to just keep the gather array in sorted order.
do cx.gather.swap |v| {
vec::to_mut(std::sort::merge_sort(|a,b| a.lo < b.lo, v))
pure fn by_lo(a: &gather_item, b: &gather_item) -> bool {
a.lo < b.lo
}
vec::to_mut(std::sort::merge_sort(by_lo, v))
};
return cx;
}
@ -119,8 +126,11 @@ fn visit_aq<T:qq_helper>(node: T, constr: ~str, &&cx: aq_ctxt, v: vt<aq_ctxt>)
{
alt (node.extract_mac()) {
some(mac_aq(sp, e)) {
cx.gather.push({lo: sp.lo - cx.lo, hi: sp.hi - cx.lo,
e: e, constr: constr});
cx.gather.push(gather_item {
lo: sp.lo - cx.lo,
hi: sp.hi - cx.lo,
e: e,
constr: constr});
}
_ {node.visit(cx, v);}
}

View File

@ -112,14 +112,14 @@ impl parser_common of parser_common for parser {
// A sanity check that the word we are asking for is a known keyword
fn require_keyword(word: ~str) {
if !self.keywords.contains_key(word) {
if !self.keywords.contains_key_ref(&word) {
self.bug(fmt!{"unknown keyword: %s", word});
}
}
fn token_is_word(word: ~str, ++tok: token::token) -> bool {
alt tok {
token::IDENT(sid, false) => { str::eq(word, *self.get_str(sid)) }
token::IDENT(sid, false) => { word == *self.get_str(sid) }
_ => { false }
}
}
@ -136,7 +136,7 @@ impl parser_common of parser_common for parser {
fn is_any_keyword(tok: token::token) -> bool {
alt tok {
token::IDENT(sid, false) {
self.keywords.contains_key(*self.get_str(sid))
self.keywords.contains_key_ref(self.get_str(sid))
}
_ { false }
}
@ -148,7 +148,7 @@ impl parser_common of parser_common for parser {
let mut bump = false;
let val = alt self.token {
token::IDENT(sid, false) {
if str::eq(word, *self.get_str(sid)) {
if word == *self.get_str(sid) {
bump = true;
true
} else { false }
@ -169,7 +169,7 @@ impl parser_common of parser_common for parser {
}
fn is_restricted_keyword(word: ~str) -> bool {
self.restricted_keywords.contains_key(word)
self.restricted_keywords.contains_key_ref(&word)
}
fn check_restricted_keywords() {

View File

@ -456,7 +456,7 @@ fn next_token_inner(rdr: string_reader) -> token::token {
bump(rdr);
c = rdr.curr;
}
if str::eq(accum_str, ~"_") { return token::UNDERSCORE; }
if accum_str == ~"_" { return token::UNDERSCORE; }
let is_mod_name = c == ':' && nextch(rdr) == ':';
// FIXME: perform NFKC normalization here. (Issue #2253)

View File

@ -2066,7 +2066,7 @@ class parser {
fn is_self_ident() -> bool {
alt self.token {
token::IDENT(sid, false) if str::eq(~"self", *self.get_str(sid)) {
token::IDENT(sid, false) if ~"self" == *self.get_str(sid) {
true
}
_ => {

View File

@ -467,12 +467,13 @@ fn print_item(s: ps, &&item: @ast::item) {
ast::item_enum(variants, params) {
let newtype =
vec::len(variants) == 1u &&
str::eq(*item.ident, *variants[0].node.name) &&
str::eq(item.ident, variants[0].node.name) &&
vec::len(variants[0].node.args) == 1u;
if newtype {
ibox(s, indent_unit);
word_space(s, ~"enum");
} else { head(s, ~"enum"); }
word(s.s, *item.ident);
print_type_params(s, params);
space(s.s);
@ -1789,12 +1790,12 @@ fn opt_proto_to_str(opt_p: option<ast::proto>) -> ~str {
}
}
fn purity_to_str(p: ast::purity) -> ~str {
pure fn purity_to_str(p: ast::purity) -> ~str {
alt p {
ast::impure_fn {~"impure"}
ast::unsafe_fn {~"unsafe"}
ast::pure_fn {~"pure"}
ast::extern_fn {~"extern"}
ast::impure_fn => ~"impure",
ast::unsafe_fn => ~"unsafe",
ast::pure_fn => ~"pure",
ast::extern_fn => ~"extern"
}
}

View File

@ -11,8 +11,8 @@ type hash_interner<T: const> =
hasher: hashfn<T>,
eqer: eqfn<T>};
fn mk<T: const copy>(hasher: hashfn<T>, eqer: eqfn<T>) -> interner<T> {
let m = map::hashmap::<T, uint>(hasher, eqer);
fn mk<T: const copy>(+hasher: hashfn<T>, +eqer: eqfn<T>) -> interner<T> {
let m = map::hashmap::<T, uint>(copy hasher, copy eqer);
let hi: hash_interner<T> =
{map: m, vect: dvec(), hasher: hasher, eqer: eqer};
return hi as interner::<T>;

View File

@ -573,19 +573,17 @@ fn build_session_(sopts: @session::options,
}
fn parse_pretty(sess: session, &&name: ~str) -> pp_mode {
if str::eq(name, ~"normal") {
return ppm_normal;
} else if str::eq(name, ~"expanded") {
return ppm_expanded;
} else if str::eq(name, ~"typed") {
return ppm_typed;
} else if str::eq(name, ~"expanded,identified") {
return ppm_expanded_identified;
} else if str::eq(name, ~"identified") {
return ppm_identified;
alt name {
~"normal" => ppm_normal,
~"expanded" => ppm_expanded,
~"typed" => ppm_typed,
~"expanded,identified" => ppm_expanded_identified,
~"identified" => ppm_identified,
_ => {
sess.fatal(~"argument to `pretty` must be one of `normal`, `typed`, \
or `identified`");
}
}
sess.fatal(~"argument to `pretty` must be one of `normal`, `typed`, or " +
~"`identified`");
}
fn opts() -> ~[getopts::opt] {

View File

@ -1003,8 +1003,8 @@ fn name_has_type(tn: type_names, s: ~str) -> option<TypeRef> {
}
fn mk_type_names() -> type_names {
fn hash(&&t: TypeRef) -> uint { return t as uint; }
fn eq(&&a: TypeRef, &&b: TypeRef) -> bool { a as uint == b as uint }
pure fn hash(t: &TypeRef) -> uint { *t as uint }
pure fn eq(a: &TypeRef, b: &TypeRef) -> bool { *a == *b }
@{type_names: std::map::hashmap(hash, eq),
named_types: std::map::str_hash()}
}

View File

@ -163,8 +163,8 @@ fn get_dep_hashes(cstore: cstore) -> ~[@~str] {
debug!{"Add hash[%s]: %s", cdata.name, *hash};
vec::push(result, {name: @cdata.name, hash: hash});
};
fn lteq(a: crate_hash, b: crate_hash) -> bool {
return *a.name <= *b.name;
pure fn lteq(a: &crate_hash, b: &crate_hash) -> bool {
*a.name <= *b.name
}
let sorted = std::sort::merge_sort(lteq, result);
debug!{"sorted:"};

View File

@ -603,7 +603,7 @@ fn get_self_ty(item: ebml::doc) -> ast::self_ty_ {
ebml::get_doc(self_type_doc,
tag_item_trait_method_self_ty_region);
let region_string = str::from_bytes(ebml::doc_data(region_doc));
if str::eq(region_string, ~"") {
if region_string == ~"" {
region = ast::re_anon;
} else {
region = ast::re_named(@region_string);

View File

@ -1089,7 +1089,9 @@ fn encode_crate_deps(ebml_w: ebml::writer, cstore: cstore::cstore) {
};
// Sort by cnum
fn lteq(kv1: numdep, kv2: numdep) -> bool { kv1.cnum <= kv2.cnum }
pure fn lteq(kv1: &numdep, kv2: &numdep) -> bool {
kv1.cnum <= kv2.cnum
}
std::sort::quick_sort(lteq, deps);
// Sanity-check the crate numbers

View File

@ -183,7 +183,7 @@ fn get_metadata_section(os: os,
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
let name_buf = llvm::LLVMGetSectionName(si.llsi);
let name = unsafe { str::unsafe::from_c_str(name_buf) };
if str::eq(name, meta_section_name(os)) {
if name == meta_section_name(os) {
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
unsafe {

View File

@ -417,11 +417,11 @@ fn save_and_restore<T:copy,U>(&save_and_restore_t: T, f: fn() -> U) -> U {
fn root_map() -> root_map {
return hashmap(root_map_key_hash, root_map_key_eq);
fn root_map_key_eq(k1: root_map_key, k2: root_map_key) -> bool {
pure fn root_map_key_eq(k1: &root_map_key, k2: &root_map_key) -> bool {
k1.id == k2.id && k1.derefs == k2.derefs
}
fn root_map_key_hash(k: root_map_key) -> uint {
pure fn root_map_key_hash(k: &root_map_key) -> uint {
(k.id << 4) as uint | k.derefs
}
}

View File

@ -118,7 +118,7 @@ class LanguageItemCollector {
}
fn match_and_collect_item(item_def_id: def_id, key: ~str, value: ~str) {
if !str_eq(key, ~"lang") {
if key != ~"lang" {
return; // Didn't match.
}

View File

@ -293,7 +293,7 @@ class AtomTable {
/// Creates a hash table of atoms.
fn atom_hashmap<V:copy>() -> hashmap<Atom,V> {
return hashmap::<Atom,V>(|a| a, |a, b| a == b);
hashmap::<Atom,V>(uint::hash, uint::eq)
}
/**
@ -3168,7 +3168,7 @@ class Resolver {
if !self.session.building_library &&
is_none(self.session.main_fn) &&
str::eq(*item.ident, ~"main") {
*item.ident == ~"main" {
self.session.main_fn = some((item.id, item.span));
}

View File

@ -94,7 +94,7 @@ type bind_map = ~[{
fn assoc(key: ast::ident, list: bind_map) -> option<binding> {
for vec::each(list) |elt| {
if str::eq(*elt.ident, *key) {
if str::eq(elt.ident, key) {
return some(elt.binding);
}
}
@ -231,7 +231,7 @@ fn enter_rec(bcx: block, dm: DefMap, m: match_, col: uint,
for vec::each(fields) |fname| {
let mut pat = dummy;
for vec::each(fpats) |fpat| {
if str::eq(*fpat.ident, *fname) { pat = fpat.pat; break; }
if str::eq(fpat.ident, fname) { pat = fpat.pat; break; }
}
vec::push(pats, pat);
}
@ -331,7 +331,7 @@ fn collect_record_fields(m: match_, col: uint) -> ~[ast::ident] {
alt br.pats[col].node {
ast::pat_rec(fs, _) {
for vec::each(fs) |f| {
if !vec::any(fields, |x| str::eq(*f.ident, *x)) {
if !vec::any(fields, |x| str::eq(f.ident, x)) {
vec::push(fields, f.ident);
}
}

View File

@ -3352,7 +3352,7 @@ fn trans_rec(bcx: block, fields: ~[ast::field],
let mut temp_cleanups = ~[];
for fields.each |fld| {
let ix = option::get(vec::position(ty_fields, |ft| {
str::eq(*fld.node.ident, *ft.ident)
str::eq(fld.node.ident, ft.ident)
}));
let dst = GEPi(bcx, addr, ~[0u, ix]);
bcx = trans_expr_save_in(bcx, fld.node.expr, dst);
@ -3365,7 +3365,7 @@ fn trans_rec(bcx: block, fields: ~[ast::field],
bcx = cx;
// Copy over inherited fields
for ty_fields.eachi |i, tf| {
if !vec::any(fields, |f| str::eq(*f.node.ident, *tf.ident)) {
if !vec::any(fields, |f| str::eq(f.node.ident, tf.ident)) {
let dst = GEPi(bcx, addr, ~[0u, i]);
let base = GEPi(bcx, base_val, ~[0u, i]);
let val = load_if_immediate(bcx, base, tf.mt.ty);
@ -3429,7 +3429,7 @@ fn trans_struct(block_context: block, span: span, fields: ~[ast::field],
for fields.each |field| {
let mut found = none;
for class_fields.eachi |i, class_field| {
if str::eq(*class_field.ident, *field.node.ident) {
if str::eq(class_field.ident, field.node.ident) {
found = some((i, class_field.id));
break;
}
@ -5554,10 +5554,10 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
discrim_symbols: int_hash::<~str>(),
tydescs: ty::new_ty_hash(),
external: ast_util::new_def_hash(),
monomorphized: map::hashmap(hash_mono_id, |a, b| a == b),
monomorphized: map::hashmap(hash_mono_id, sys::shape_eq),
monomorphizing: ast_util::new_def_hash(),
type_use_cache: ast_util::new_def_hash(),
vtables: map::hashmap(hash_mono_id, |a, b| a == b),
vtables: map::hashmap(hash_mono_id, sys::shape_eq),
const_cstr_cache: map::str_hash(),
module_data: str_hash::<ValueRef>(),
lltypes: ty::new_ty_hash(),

View File

@ -927,14 +927,16 @@ enum mono_param_id {
mono_repr(uint /* size */, uint /* align */),
}
type mono_id = @{def: ast::def_id, params: ~[mono_param_id]};
fn hash_mono_id(&&mi: mono_id) -> uint {
let mut h = syntax::ast_util::hash_def(mi.def);
pure fn hash_mono_id(mi: &mono_id) -> uint {
let mut h = syntax::ast_util::hash_def(&mi.def);
for vec::each(mi.params) |param| {
h = h * alt param {
mono_precise(ty, vts) {
let mut h = ty::type_id(ty);
do option::iter(vts) |vts| {
for vec::each(vts) |vt| { h += hash_mono_id(vt); }
for vec::each(vts) |vt| {
h += hash_mono_id(&vt);
}
}
h
}

View File

@ -33,7 +33,7 @@ fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id,
@{did: did, parent_id: parent_id, tps: tps_norm}
}
fn hash_nominal_id(&&ri: nominal_id) -> uint {
pure fn hash_nominal_id(ri: &nominal_id) -> uint {
let mut h = 5381u;
h *= 33u;
h += ri.did.crate as uint;
@ -46,7 +46,7 @@ fn hash_nominal_id(&&ri: nominal_id) -> uint {
return h;
}
fn eq_nominal_id(&&mi: nominal_id, &&ni: nominal_id) -> bool {
pure fn eq_nominal_id(mi: &nominal_id, ni: &nominal_id) -> bool {
if mi.did != ni.did {
false
} else {

View File

@ -295,16 +295,18 @@ pure fn get(t: t) -> t_box unsafe {
t3
}
fn tbox_has_flag(tb: t_box, flag: tbox_flag) -> bool {
pure fn tbox_has_flag(tb: t_box, flag: tbox_flag) -> bool {
(tb.flags & (flag as uint)) != 0u
}
fn type_has_params(t: t) -> bool { tbox_has_flag(get(t), has_params) }
fn type_has_self(t: t) -> bool { tbox_has_flag(get(t), has_self) }
fn type_needs_infer(t: t) -> bool { tbox_has_flag(get(t), needs_infer) }
fn type_has_regions(t: t) -> bool { tbox_has_flag(get(t), has_regions) }
fn type_has_resources(t: t) -> bool { tbox_has_flag(get(t), has_resources) }
fn type_def_id(t: t) -> option<ast::def_id> { get(t).o_def_id }
fn type_id(t: t) -> uint { get(t).id }
pure fn type_has_params(t: t) -> bool { tbox_has_flag(get(t), has_params) }
pure fn type_has_self(t: t) -> bool { tbox_has_flag(get(t), has_self) }
pure fn type_needs_infer(t: t) -> bool { tbox_has_flag(get(t), needs_infer) }
pure fn type_has_regions(t: t) -> bool { tbox_has_flag(get(t), has_regions) }
pure fn type_has_resources(t: t) -> bool {
tbox_has_flag(get(t), has_resources)
}
pure fn type_def_id(t: t) -> option<ast::def_id> { get(t).o_def_id }
pure fn type_id(t: t) -> uint { get(t).id }
enum closure_kind {
ck_block,
@ -478,31 +480,31 @@ enum tvi_vid = uint;
enum region_vid = uint;
trait vid {
fn to_uint() -> uint;
fn to_str() -> ~str;
pure fn to_uint() -> uint;
pure fn to_str() -> ~str;
}
impl of vid for tv_vid {
fn to_uint() -> uint { *self }
fn to_str() -> ~str { fmt!{"<V%u>", self.to_uint()} }
pure fn to_uint() -> uint { *self }
pure fn to_str() -> ~str { fmt!{"<V%u>", self.to_uint()} }
}
impl of vid for tvi_vid {
fn to_uint() -> uint { *self }
fn to_str() -> ~str { fmt!{"<VI%u>", self.to_uint()} }
pure fn to_uint() -> uint { *self }
pure fn to_str() -> ~str { fmt!{"<VI%u>", self.to_uint()} }
}
impl of vid for region_vid {
fn to_uint() -> uint { *self }
fn to_str() -> ~str { fmt!{"<R%u>", self.to_uint()} }
pure fn to_uint() -> uint { *self }
pure fn to_str() -> ~str { fmt!{"<R%u>", self.to_uint()} }
}
trait purity_to_str {
fn to_str() -> ~str;
pure fn to_str() -> ~str;
}
impl of purity_to_str for purity {
fn to_str() -> ~str {
pure fn to_str() -> ~str {
purity_to_str(self)
}
}
@ -541,18 +543,18 @@ type node_type_table = @smallintmap::smallintmap<t>;
fn mk_rcache() -> creader_cache {
type val = {cnum: int, pos: uint, len: uint};
fn hash_cache_entry(k: val) -> uint {
return (k.cnum as uint) + k.pos + k.len;
pure fn hash_cache_entry(k: &val) -> uint {
(k.cnum as uint) + k.pos + k.len
}
fn eq_cache_entries(a: val, b: val) -> bool {
return a.cnum == b.cnum && a.pos == b.pos && a.len == b.len;
pure fn eq_cache_entries(a: &val, b: &val) -> bool {
a.cnum == b.cnum && a.pos == b.pos && a.len == b.len
}
return map::hashmap(hash_cache_entry, eq_cache_entries);
}
fn new_ty_hash<V: copy>() -> map::hashmap<t, V> {
map::hashmap(|&&t: t| type_id(t),
|&&a: t, &&b: t| type_id(a) == type_id(b))
map::hashmap(|t: &t| type_id(*t),
|a: &t, b: &t| type_id(*a) == type_id(*b))
}
fn mk_ctxt(s: session::session,
@ -561,10 +563,11 @@ fn mk_ctxt(s: session::session,
freevars: freevars::freevar_map,
region_map: middle::region::region_map,
region_paramd_items: middle::region::region_paramd_items) -> ctxt {
let interner = map::hashmap(|&&k: intern_key| {
pure fn hash_intern_key(k: &intern_key) -> uint {
hash_type_structure(k.struct) +
option::map_default(k.o_def_id, 0u, ast_util::hash_def)
}, |&&a, &&b| a == b);
option::map_default(k.o_def_id, 0u, |d| ast_util::hash_def(&d))
}
let interner = map::hashmap(hash_intern_key, sys::shape_eq);
let vecs_implicitly_copyable =
get_lint_level(s.lint_settings.default_settings,
lint::vecs_implicitly_copyable) == allow;
@ -2131,46 +2134,47 @@ fn index_sty(cx: ctxt, sty: sty) -> option<mt> {
}
}
fn hash_bound_region(br: bound_region) -> uint {
alt br { // no idea if this is any good
pure fn hash_bound_region(br: &bound_region) -> uint {
alt *br { // no idea if this is any good
ty::br_self { 0u }
ty::br_anon { 1u }
ty::br_named(str) { str::hash(*str) }
ty::br_cap_avoid(id, br) { id as uint | hash_bound_region(*br) }
ty::br_named(str) { str::hash(str) }
ty::br_cap_avoid(id, br) { id as uint | hash_bound_region(br) }
}
}
fn br_hashmap<V:copy>() -> hashmap<bound_region, V> {
map::hashmap(hash_bound_region,
|&&a: bound_region, &&b: bound_region| a == b)
map::hashmap(hash_bound_region, sys::shape_eq)
}
// Type hashing.
fn hash_type_structure(st: sty) -> uint {
fn hash_uint(id: uint, n: uint) -> uint { (id << 2u) + n }
fn hash_def(id: uint, did: ast::def_id) -> uint {
pure fn hash_type_structure(st: sty) -> uint {
pure fn hash_uint(id: uint, n: uint) -> uint { (id << 2u) + n }
pure fn hash_def(id: uint, did: ast::def_id) -> uint {
let h = (id << 2u) + (did.crate as uint);
(h << 2u) + (did.node as uint)
}
fn hash_subty(id: uint, subty: t) -> uint { (id << 2u) + type_id(subty) }
fn hash_subtys(id: uint, subtys: ~[t]) -> uint {
pure fn hash_subty(id: uint, subty: t) -> uint {
(id << 2u) + type_id(subty)
}
pure fn hash_subtys(id: uint, subtys: ~[t]) -> uint {
let mut h = id;
for subtys.each |s| { h = (h << 2u) + type_id(s) }
for vec::each(subtys) |s| { h = (h << 2u) + type_id(s) }
h
}
fn hash_region(r: region) -> uint {
alt r { // no idea if this is any good
re_bound(br) { (hash_bound_region(br)) << 2u | 0u }
pure fn hash_region(r: &region) -> uint {
alt *r { // no idea if this is any good
re_bound(br) { (hash_bound_region(&br)) << 2u | 0u }
re_free(id, br) { ((id as uint) << 4u) |
(hash_bound_region(br)) << 2u | 1u }
(hash_bound_region(&br)) << 2u | 1u }
re_scope(id) { ((id as uint) << 2u) | 2u }
re_var(id) { (id.to_uint() << 2u) | 3u }
re_bot { 4u }
}
}
fn hash_substs(h: uint, substs: substs) -> uint {
pure fn hash_substs(h: uint, substs: substs) -> uint {
let h = hash_subtys(h, substs.tps);
h + substs.self_r.map_default(0u, hash_region)
h + substs.self_r.map_default(0u, |r| hash_region(&r))
}
alt st {
ty_nil { 0u } ty_bool { 1u }
@ -2200,12 +2204,12 @@ fn hash_type_structure(st: sty) -> uint {
ty_tup(ts) { hash_subtys(25u, ts) }
ty_rec(fields) {
let mut h = 26u;
for fields.each |f| { h = hash_subty(h, f.mt.ty); }
for vec::each(fields) |f| { h = hash_subty(h, f.mt.ty); }
h
}
ty_fn(f) {
let mut h = 27u;
for f.inputs.each |a| { h = hash_subty(h, a.ty); }
for vec::each(f.inputs) |a| { h = hash_subty(h, a.ty); }
hash_subty(h, f.output)
}
ty_self { 28u }
@ -2229,7 +2233,7 @@ fn hash_type_structure(st: sty) -> uint {
hash_substs(h, substs)
}
ty_rptr(region, mt) {
let mut h = (46u << 2u) + hash_region(region);
let mut h = (46u << 2u) + hash_region(&region);
hash_subty(h, mt.ty)
}
}
@ -2375,7 +2379,7 @@ fn field_idx(id: ast::ident, fields: ~[field]) -> option<uint> {
}
fn get_field(rec_ty: t, id: ast::ident) -> field {
alt check vec::find(get_fields(rec_ty), |f| str::eq(*f.ident, *id)) {
alt check vec::find(get_fields(rec_ty), |f| str::eq(f.ident, id)) {
some(f) { f }
}
}
@ -2848,7 +2852,7 @@ fn enum_variant_with_id(cx: ctxt, enum_id: ast::def_id,
let mut i = 0u;
while i < vec::len::<variant_info>(*variants) {
let variant = variants[i];
if ast_util::def_eq(variant.id, variant_id) { return variant; }
if ast_util::def_eq(&variant.id, &variant_id) { return variant; }
i += 1u;
}
cx.sess.bug(~"enum_variant_with_id(): no variant exists with that ID");

View File

@ -1670,7 +1670,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
for fields_t.each |f| {
let mut found = false;
for base_fields.each |bf| {
if str::eq(*f.node.ident, *bf.ident) {
if str::eq(f.node.ident, bf.ident) {
demand::suptype(fcx, f.span, bf.mt.ty, f.node.mt.ty);
found = true;
}

View File

@ -197,7 +197,7 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
ex_f_count, f_count});
}
fn matches(name: ast::ident, f: ty::field) -> bool {
return str::eq(*name, *f.ident);
str::eq(name, f.ident)
}
for fields.each |f| {
alt vec::find(ex_fields, |a| matches(f.ident, a)) {

View File

@ -316,11 +316,11 @@ impl util of page_utils for ~[page] {
}
trait item {
fn item() -> itemdoc;
pure fn item() -> itemdoc;
}
impl of item for itemtag {
fn item() -> itemdoc {
pure fn item() -> itemdoc {
alt self {
doc::modtag(doc) { doc.item }
doc::nmodtag(doc) { doc.item }
@ -335,60 +335,60 @@ impl of item for itemtag {
}
impl of item for simpleitemdoc {
fn item() -> itemdoc { self.item }
pure fn item() -> itemdoc { self.item }
}
impl of item for moddoc {
fn item() -> itemdoc { self.item }
pure fn item() -> itemdoc { self.item }
}
impl of item for nmoddoc {
fn item() -> itemdoc { self.item }
pure fn item() -> itemdoc { self.item }
}
impl of item for enumdoc {
fn item() -> itemdoc { self.item }
pure fn item() -> itemdoc { self.item }
}
impl of item for traitdoc {
fn item() -> itemdoc { self.item }
pure fn item() -> itemdoc { self.item }
}
impl of item for impldoc {
fn item() -> itemdoc { self.item }
pure fn item() -> itemdoc { self.item }
}
trait item_utils {
fn id() -> ast_id;
fn name() -> ~str;
fn path() -> ~[~str];
fn brief() -> option<~str>;
fn desc() -> option<~str>;
fn sections() -> ~[section];
pure fn id() -> ast_id;
pure fn name() -> ~str;
pure fn path() -> ~[~str];
pure fn brief() -> option<~str>;
pure fn desc() -> option<~str>;
pure fn sections() -> ~[section];
}
impl util<A:item> of item_utils for A {
fn id() -> ast_id {
pure fn id() -> ast_id {
self.item().id
}
fn name() -> ~str {
pure fn name() -> ~str {
self.item().name
}
fn path() -> ~[~str] {
pure fn path() -> ~[~str] {
self.item().path
}
fn brief() -> option<~str> {
pure fn brief() -> option<~str> {
self.item().brief
}
fn desc() -> option<~str> {
pure fn desc() -> option<~str> {
self.item().desc
}
fn sections() -> ~[section] {
pure fn sections() -> ~[section] {
self.item().sections
}
}

View File

@ -26,9 +26,9 @@ fn run(
+writer_factory: writer_factory
) -> doc::doc {
fn mods_last(item1: doc::itemtag, item2: doc::itemtag) -> bool {
fn is_mod(item: doc::itemtag) -> bool {
alt item {
pure fn mods_last(item1: &doc::itemtag, item2: &doc::itemtag) -> bool {
pure fn is_mod(item: &doc::itemtag) -> bool {
alt *item {
doc::modtag(_) { true }
_ { false }
}

View File

@ -4,9 +4,10 @@ import doc::item_utils;
export mk_pass;
fn mk_pass() -> pass {
sort_pass::mk_pass(~"sort_item_name", |item1, item2| {
str::le(item1.name(), item2.name())
})
pure fn by_item_name(item1: &doc::itemtag, item2: &doc::itemtag) -> bool {
(*item1).name() <= (*item2).name()
}
sort_pass::mk_pass(~"sort_item_name", by_item_name)
}
#[test]

View File

@ -5,9 +5,9 @@ import doc::item_utils;
export mk_pass;
fn mk_pass() -> pass {
do sort_pass::mk_pass(~"sort_item_type") |item1, item2| {
fn score(item: doc::itemtag) -> int {
alt item {
pure fn by_score(item1: &doc::itemtag, item2: &doc::itemtag) -> bool {
pure fn score(item: &doc::itemtag) -> int {
alt *item {
doc::consttag(_) { 0 }
doc::tytag(_) { 1 }
doc::enumtag(_) { 2 }
@ -21,6 +21,8 @@ fn mk_pass() -> pass {
score(item1) <= score(item2)
}
sort_pass::mk_pass(~"sort_item_type", by_score)
}
#[test]

View File

@ -5,7 +5,7 @@ import std::sort;
export item_lteq, mk_pass;
type item_lteq = fn~(doc::itemtag, doc::itemtag) -> bool;
type item_lteq = pure fn~(v1: &doc::itemtag, v2: &doc::itemtag) -> bool;
fn mk_pass(name: ~str, +lteq: item_lteq) -> pass {
{
@ -43,8 +43,8 @@ fn fold_mod(
#[test]
fn test() {
fn name_lteq(item1: doc::itemtag, item2: doc::itemtag) -> bool {
str::le(item1.name(), item2.name())
pure fn name_lteq(item1: &doc::itemtag, item2: &doc::itemtag) -> bool {
(*item1).name() <= (*item2).name()
}
let source = ~"mod z { mod y { } fn x() { } } mod w { }";
@ -60,7 +60,7 @@ fn test() {
#[test]
fn should_be_stable() {
fn always_eq(_item1: doc::itemtag, _item2: doc::itemtag) -> bool {
pure fn always_eq(_item1: &doc::itemtag, _item2: &doc::itemtag) -> bool {
true
}

View File

@ -66,9 +66,11 @@ fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
}
}
pure fn node_hash(n: &node_id) -> uint { *n as uint }
fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph {
let graph = do vec::from_fn(N) |_i| {
map::hashmap::<node_id, ()>(|x| x as uint , |x, y| x == y )
map::hashmap::<node_id, ()>(node_hash, sys::shape_eq)
};
do vec::each(edges) |e| {
@ -84,7 +86,7 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph {
}
fn gen_search_keys(graph: graph, n: uint) -> ~[node_id] {
let keys = map::hashmap::<node_id, ()>(|x| x as uint , |x, y| x == y );
let keys = map::hashmap::<node_id, ()>(node_hash, sys::shape_eq);
let r = rand::rng();
while keys.size() < n {

View File

@ -17,15 +17,17 @@ fn sort_and_fmt(mm: hashmap<~[u8], uint>, total: uint) -> ~str {
return (xx as float) * 100f / (yy as float);
}
fn le_by_val<TT: copy, UU: copy>(kv0: (TT,UU), kv1: (TT,UU)) -> bool {
let (_, v0) = kv0;
let (_, v1) = kv1;
pure fn le_by_val<TT: copy, UU: copy>(kv0: &(TT,UU),
kv1: &(TT,UU)) -> bool {
let (_, v0) = *kv0;
let (_, v1) = *kv1;
return v0 >= v1;
}
fn le_by_key<TT: copy, UU: copy>(kv0: (TT,UU), kv1: (TT,UU)) -> bool {
let (k0, _) = kv0;
let (k1, _) = kv1;
pure fn le_by_key<TT: copy, UU: copy>(kv0: &(TT,UU),
kv1: &(TT,UU)) -> bool {
let (k0, _) = *kv0;
let (k1, _) = *kv1;
return k0 <= k1;
}

View File

@ -15,15 +15,17 @@ fn sort_and_fmt(mm: hashmap<~[u8], uint>, total: uint) -> ~str {
return (xx as float) * 100f / (yy as float);
}
fn le_by_val<TT: copy, UU: copy>(kv0: (TT,UU), kv1: (TT,UU)) -> bool {
let (_, v0) = kv0;
let (_, v1) = kv1;
pure fn le_by_val<TT: copy, UU: copy>(kv0: &(TT,UU),
kv1: &(TT,UU)) -> bool {
let (_, v0) = *kv0;
let (_, v1) = *kv1;
return v0 >= v1;
}
fn le_by_key<TT: copy, UU: copy>(kv0: (TT,UU), kv1: (TT,UU)) -> bool {
let (k0, _) = kv0;
let (k1, _) = kv1;
pure fn le_by_key<TT: copy, UU: copy>(kv0: &(TT,UU),
kv1: &(TT,UU)) -> bool {
let (k0, _) = *kv0;
let (k1, _) = *kv1;
return k0 <= k1;
}

View File

@ -42,19 +42,20 @@ trait word_reader {
}
trait hash_key {
fn hash() -> uint;
fn eq(self) -> bool;
pure fn hash() -> uint;
pure fn eq(&&k: self) -> bool;
}
fn mk_hash<K: const hash_key, V: copy>() -> map::hashmap<K, V> {
fn hashfn<K: const hash_key>(k: K) -> uint { k.hash() }
pure fn hashfn<K: const hash_key>(k: &K) -> uint { k.hash() }
pure fn hasheq<K: const hash_key>(k1: &K, k2: &K) -> bool { k1.eq(*k2) }
map::hashmap(hashfn::<K>, |x, y| x.eq(y))
map::hashmap(hashfn, hasheq)
}
impl of hash_key for ~str {
fn hash() -> uint { str::hash(self) }
fn eq(&&x: ~str) -> bool { str::eq(self, x) }
pure fn hash() -> uint { str::hash(&self) }
pure fn eq(&&x: ~str) -> bool { self == x }
}
// These used to be in task, but they disappeard.

View File

@ -7,12 +7,12 @@ import uint;
fn main() {
let count = @mut 0u;
fn hash(&&s: ~[@~str]) -> uint {
if (vec::len(s) > 0u && str::eq(*s[0], ~"boom")) { fail; }
pure fn hash(s: &~[@~str]) -> uint {
if vec::len(*s) > 0u && *s[0] == ~"boom" { fail; }
return 10u;
}
fn eq(&&s: ~[@~str], &&t: ~[@~str]) -> bool {
return s == t;
pure fn eq(s: &~[@~str], t: &~[@~str]) -> bool {
return *s == *t;
}
let map = map::hashmap(hash, eq);

View File

@ -24,9 +24,6 @@ fn enum_uints(start: uint, end: uint) -> ~[uint] {
fn main() {
let a = 'a' as u8, j = 'j' as u8, k = 1u, l = 9u;
// Silly, but necessary
assert (u8::le(a, j));
assert (uint::le(k, l));
let chars = enum_chars(a, j);
let ints = enum_uints(k, l);

View File

@ -45,21 +45,22 @@ class cat<T: copy> : map<int, T> {
self.meows += k;
true
}
fn contains_key(&&k: int) -> bool { k <= self.meows }
fn get(&&k:int) -> T { alt self.find(k) {
fn contains_key(+k: int) -> bool { k <= self.meows }
fn contains_key_ref(k: &int) -> bool { self.contains_key(*k) }
fn get(+k:int) -> T { alt self.find(k) {
some(v) { v }
none { fail ~"epic fail"; }
}
}
fn [](&&k:int) -> T { self.get(k) }
fn find(&&k:int) -> option<T> { if k <= self.meows {
fn find(+k:int) -> option<T> { if k <= self.meows {
some(self.name)
}
else { none }
}
fn remove(&&k:int) -> option<T> {
fn remove(+k:int) -> option<T> {
alt self.find(k) {
some(x) {
self.meows -= k; some(x)
@ -68,7 +69,7 @@ class cat<T: copy> : map<int, T> {
}
}
fn each(f: fn(&&int, &&T) -> bool) {
fn each(f: fn(+int, +T) -> bool) {
let mut n = int::abs(self.meows);
while n > 0 {
if !f(n, self.name) { break; }
@ -76,12 +77,17 @@ class cat<T: copy> : map<int, T> {
}
}
fn each_key(&&f: fn(&&int) -> bool) {
fn each_key(&&f: fn(+int) -> bool) {
for self.each |k, _v| { if !f(k) { break; } again;};
}
fn each_value(&&f: fn(&&T) -> bool) {
fn each_value(&&f: fn(+T) -> bool) {
for self.each |_k, v| { if !f(v) { break; } again;};
}
fn each_ref(f: fn(k: &int, v: &T) -> bool) {}
fn each_key_ref(f: fn(k: &int) -> bool) {}
fn each_value_ref(f: fn(k: &T) -> bool) {}
fn clear() { }
}

View File

@ -13,7 +13,7 @@ import task;
type ctx = comm::chan<int>;
fn iotask(cx: ctx, ip: ~str) {
assert (str::eq(ip, ~"localhost"));
assert (ip == ~"localhost");
}
fn main() {

View File

@ -19,8 +19,8 @@ fn test2() {
let b: ~str = ~"ABC" + ff + ~"ABC";
log(debug, a);
log(debug, b);
assert (str::eq(a, ~"abcABCabc"));
assert (str::eq(b, ~"ABCabcABC"));
assert (a == ~"abcABCabc");
assert (b == ~"ABCabcABC");
}
fn main() { test1(); test2(); }

View File

@ -12,6 +12,6 @@ is a test";
is \
another \
test";
assert (str::eq(a, ~"this is a test"));
assert (str::eq(b, ~"this is another test"));
assert (a == ~"this is a test");
assert (b == ~"this is another test");
}

View File

@ -4,7 +4,7 @@ import str;
fn test(actual: ~str, expected: ~str) {
log(debug, actual);
log(debug, expected);
assert (str::eq(actual, expected));
assert (actual == expected);
}
fn main() {

View File

@ -10,7 +10,7 @@ fn main() {
assert (str::len(s) == 10u);
assert (str::char_len(s) == 4u);
assert (vec::len(str::chars(s)) == 4u);
assert (str::eq(str::from_chars(str::chars(s)), s));
assert (str::from_chars(str::chars(s)) == s);
assert (str::char_at(s, 0u) == 'e');
assert (str::char_at(s, 1u) == 'é');
@ -23,9 +23,9 @@ fn main() {
assert (str::pop_char(stack) == '€');
assert (str::pop_char(stack) == 'c');
str::push_char(stack, 'u');
assert (str::eq(stack, ~"a×u"));
assert (stack == ~"a×u");
assert (str::shift_char(stack) == 'a');
assert (str::shift_char(stack) == '×');
str::unshift_char(stack, 'ß');
assert (str::eq(stack, ~"ßu"));
assert (stack == ~"ßu");
}