parent
58c82a8da2
commit
cfdf193c46
94 changed files with 289 additions and 288 deletions
|
@ -88,7 +88,7 @@ fn parse_input_src(sess: session::session, cfg: ast::crate_cfg, infile: str)
|
|||
ret {crate: crate, src: src};
|
||||
}
|
||||
|
||||
fn time<@T>(do_it: bool, what: str, thunk: fn@() -> T) -> T {
|
||||
fn time<T>(do_it: bool, what: str, thunk: fn@() -> T) -> T {
|
||||
if !do_it { ret thunk(); }
|
||||
let start = std::time::precise_time_s();
|
||||
let rv = thunk();
|
||||
|
|
|
@ -182,7 +182,7 @@ fn require_unique_names(sess: session::session, metas: [@ast::meta_item]) {
|
|||
}
|
||||
}
|
||||
|
||||
fn span<@T>(item: T) -> ast::spanned<T> {
|
||||
fn span<T>(item: T) -> ast::spanned<T> {
|
||||
ret {node: item, span: ast_util::dummy_sp()};
|
||||
}
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ fn mk_test_module(cx: test_ctxt) -> @ast::item {
|
|||
ret @item;
|
||||
}
|
||||
|
||||
fn nospan<@T>(t: T) -> ast::spanned<T> { ret {node: t, span: dummy_sp()}; }
|
||||
fn nospan<T>(t: T) -> ast::spanned<T> { ret {node: t, span: dummy_sp()}; }
|
||||
|
||||
fn mk_tests(cx: test_ctxt) -> @ast::item {
|
||||
let ret_ty = mk_test_desc_vec_ty(cx);
|
||||
|
|
|
@ -391,7 +391,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer) ->
|
|||
|
||||
// Path and definition ID indexing
|
||||
|
||||
fn create_index<@T>(index: [entry<T>], hash_fn: fn(T) -> uint) ->
|
||||
fn create_index<T>(index: [entry<T>], hash_fn: fn(T) -> uint) ->
|
||||
[@[entry<T>]] {
|
||||
let buckets: [@mutable [entry<T>]] = [];
|
||||
uint::range(0u, 256u) {|_i| buckets += [@mutable []]; };
|
||||
|
|
|
@ -150,7 +150,7 @@ fn parse_ty_constr_arg(st: @pstate, sd: str_def) ->
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_constr<@T>(st: @pstate, sd: str_def, pser: arg_parser<T>) ->
|
||||
fn parse_constr<T>(st: @pstate, sd: str_def, pser: arg_parser<T>) ->
|
||||
@ty::constr_general<T> {
|
||||
let sp = ast_util::dummy_sp(); // FIXME: use a real span
|
||||
let args: [@sp_constr_arg<T>] = [];
|
||||
|
|
|
@ -75,7 +75,7 @@ fn map_expr(cx: ctx, ex: @expr) {
|
|||
cx.map.insert(ex.id, node_expr(ex));
|
||||
}
|
||||
|
||||
fn new_smallintmap_int_adapter<@V>() -> std::map::hashmap<int, V> {
|
||||
fn new_smallintmap_int_adapter<V>() -> std::map::hashmap<int, V> {
|
||||
let key_idx = fn (&&key: int) -> uint { key as uint };
|
||||
let idx_key = fn (idx: uint) -> int { idx as int };
|
||||
ret new_smallintmap_adapter(key_idx, idx_key);
|
||||
|
@ -86,13 +86,13 @@ fn new_smallintmap_int_adapter<@V>() -> std::map::hashmap<int, V> {
|
|||
// the entire codebase adapting all the callsites to the different
|
||||
// interface.
|
||||
// FIXME: hashmap and smallintmap should support the same interface.
|
||||
fn new_smallintmap_adapter<@K, @V>(key_idx: fn(K) -> uint,
|
||||
fn new_smallintmap_adapter<K, V>(key_idx: fn(K) -> uint,
|
||||
idx_key: fn(uint) -> K)
|
||||
-> std::map::hashmap<K, V> {
|
||||
|
||||
obj adapter<@K, @V>(map: smallintmap::smallintmap<V>,
|
||||
key_idx: fn(K) -> uint,
|
||||
idx_key: fn(uint) -> K) {
|
||||
obj adapter<K, V>(map: smallintmap::smallintmap<V>,
|
||||
key_idx: fn(K) -> uint,
|
||||
idx_key: fn(uint) -> K) {
|
||||
|
||||
fn size() -> uint { fail }
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
*
|
||||
*
|
||||
* Since this forms a lattice, we denote the capabilites in terms of a
|
||||
* worst-case requirement. That is, if your function needs to move-and-send
|
||||
* (or copy) your T, you write fn<~T>(...). If you need to move but not send,
|
||||
* you write fn<@T>(...). And if you need neither -- can work with any sort of
|
||||
* pinned data at all -- then you write fn<T>(...).
|
||||
* worst-case requirement. That is, if your function needs to move-and-send (or
|
||||
* copy) your T, you write fn<unique T>(...). If you need to move but not send,
|
||||
* you write fn<T>(...). And if you need neither -- can work with any sort of
|
||||
* pinned data at all -- then you write fn<pinned T>(...).
|
||||
*
|
||||
* Most types are unique or shared. Other possible name combinations for these
|
||||
* two: (tree, graph; pruned, pooled; message, local; owned, common) are
|
||||
|
|
|
@ -2,7 +2,7 @@ import std::{str, option};
|
|||
import codemap::span;
|
||||
import ast::*;
|
||||
|
||||
fn respan<@T>(sp: span, t: T) -> spanned<T> { ret {node: t, span: sp}; }
|
||||
fn respan<T>(sp: span, t: T) -> spanned<T> { ret {node: t, span: sp}; }
|
||||
|
||||
/* assuming that we're not in macro expansion */
|
||||
fn mk_sp(lo: uint, hi: uint) -> span {
|
||||
|
@ -186,7 +186,7 @@ fn eq_def_id(&&a: def_id, &&b: def_id) -> bool {
|
|||
a == b
|
||||
}
|
||||
|
||||
fn new_def_id_hash<@T>() -> std::map::hashmap<def_id, T> {
|
||||
fn new_def_id_hash<T>() -> std::map::hashmap<def_id, T> {
|
||||
std::map::mk_hashmap(hash_def_id, eq_def_id)
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ fn elts_to_ell(cx: ext_ctxt, elts: [@expr]) ->
|
|||
}
|
||||
}
|
||||
|
||||
fn option_flatten_map<T, @U>(f: fn@(T) -> option::t<U>, v: [T]) ->
|
||||
fn option_flatten_map<T, U>(f: fn@(T) -> option::t<U>, v: [T]) ->
|
||||
option::t<[U]> {
|
||||
let res = [];
|
||||
for elem: T in v {
|
||||
|
|
|
@ -210,7 +210,7 @@ fn expect_gt(p: parser) {
|
|||
}
|
||||
}
|
||||
|
||||
fn spanned<@T>(lo: uint, hi: uint, node: T) -> spanned<T> {
|
||||
fn spanned<T>(lo: uint, hi: uint, node: T) -> spanned<T> {
|
||||
ret {node: node, span: ast_util::mk_sp(lo, hi)};
|
||||
}
|
||||
|
||||
|
@ -595,7 +595,7 @@ fn parse_fn_block_arg(p: parser) -> ast::arg {
|
|||
ret {mode: m, ty: t, ident: i, id: p.get_id()};
|
||||
}
|
||||
|
||||
fn parse_seq_to_before_gt<@T>(sep: option::t<token::token>,
|
||||
fn parse_seq_to_before_gt<T>(sep: option::t<token::token>,
|
||||
f: fn@(parser) -> T,
|
||||
p: parser) -> [T] {
|
||||
let first = true;
|
||||
|
@ -612,7 +612,7 @@ fn parse_seq_to_before_gt<@T>(sep: option::t<token::token>,
|
|||
ret v;
|
||||
}
|
||||
|
||||
fn parse_seq_to_gt<@T>(sep: option::t<token::token>, f: fn@(parser) -> T,
|
||||
fn parse_seq_to_gt<T>(sep: option::t<token::token>, f: fn@(parser) -> T,
|
||||
p: parser) -> [T] {
|
||||
let v = parse_seq_to_before_gt(sep, f, p);
|
||||
expect_gt(p);
|
||||
|
@ -620,7 +620,7 @@ fn parse_seq_to_gt<@T>(sep: option::t<token::token>, f: fn@(parser) -> T,
|
|||
ret v;
|
||||
}
|
||||
|
||||
fn parse_seq_lt_gt<@T>(sep: option::t<token::token>, f: fn@(parser) -> T,
|
||||
fn parse_seq_lt_gt<T>(sep: option::t<token::token>, f: fn@(parser) -> T,
|
||||
p: parser) -> spanned<[T]> {
|
||||
let lo = p.get_lo_pos();
|
||||
expect(p, token::LT);
|
||||
|
@ -630,14 +630,14 @@ fn parse_seq_lt_gt<@T>(sep: option::t<token::token>, f: fn@(parser) -> T,
|
|||
ret spanned(lo, hi, result);
|
||||
}
|
||||
|
||||
fn parse_seq_to_end<@T>(ket: token::token, sep: option::t<token::token>,
|
||||
fn parse_seq_to_end<T>(ket: token::token, sep: option::t<token::token>,
|
||||
f: fn(parser) -> T, p: parser) -> [T] {
|
||||
let val = parse_seq_to_before_end(ket, sep, f, p);
|
||||
p.bump();
|
||||
ret val;
|
||||
}
|
||||
|
||||
fn parse_seq_to_before_end<@T>(ket: token::token,
|
||||
fn parse_seq_to_before_end<T>(ket: token::token,
|
||||
sep: option::t<token::token>,
|
||||
f: fn@(parser) -> T, p: parser) -> [T] {
|
||||
let first: bool = true;
|
||||
|
@ -653,7 +653,7 @@ fn parse_seq_to_before_end<@T>(ket: token::token,
|
|||
}
|
||||
|
||||
|
||||
fn parse_seq<@T>(bra: token::token, ket: token::token,
|
||||
fn parse_seq<T>(bra: token::token, ket: token::token,
|
||||
sep: option::t<token::token>, f: fn@(parser) -> T, p: parser)
|
||||
-> spanned<[T]> {
|
||||
let lo = p.get_lo_pos();
|
||||
|
|
|
@ -11,12 +11,12 @@ type interner<T> =
|
|||
hasher: hashfn<T>,
|
||||
eqer: eqfn<T>};
|
||||
|
||||
fn mk<@T>(hasher: hashfn<T>, eqer: eqfn<T>) -> interner<T> {
|
||||
fn mk<T>(hasher: hashfn<T>, eqer: eqfn<T>) -> interner<T> {
|
||||
let m = map::mk_hashmap::<T, uint>(hasher, eqer);
|
||||
ret {map: m, mutable vect: [], hasher: hasher, eqer: eqer};
|
||||
}
|
||||
|
||||
fn intern<@T>(itr: interner<T>, val: T) -> uint {
|
||||
fn intern<T>(itr: interner<T>, val: T) -> uint {
|
||||
alt itr.map.find(val) {
|
||||
some(idx) { ret idx; }
|
||||
none. {
|
||||
|
@ -31,7 +31,7 @@ fn intern<@T>(itr: interner<T>, val: T) -> uint {
|
|||
// |get| isn't "pure" in the traditional sense, because it can go from
|
||||
// failing to returning a value as items are interned. But for typestate,
|
||||
// where we first check a pred and then rely on it, ceasing to fail is ok.
|
||||
pure fn get<@T>(itr: interner<T>, idx: uint) -> T {
|
||||
pure fn get<T>(itr: interner<T>, idx: uint) -> T {
|
||||
unchecked {
|
||||
itr.vect[idx]
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ fn hash_def(d: ast::def_id) -> uint {
|
|||
ret h;
|
||||
}
|
||||
|
||||
fn new_def_hash<@V>() -> std::map::hashmap<ast::def_id, V> {
|
||||
fn new_def_hash<V>() -> std::map::hashmap<ast::def_id, V> {
|
||||
let hasher: std::map::hashfn<ast::def_id> = hash_def;
|
||||
let eqer: std::map::eqfn<ast::def_id> = def_eq;
|
||||
ret std::map::mk_hashmap::<ast::def_id, V>(hasher, eqer);
|
||||
|
@ -166,7 +166,7 @@ fn lit_in_range(l: @ast::lit, m1: @ast::lit, m2: @ast::lit) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn ranges_overlap<@T>(a1: T, a2: T, b1: T, b2: T) -> bool {
|
||||
fn ranges_overlap<T>(a1: T, a2: T, b1: T, b2: T) -> bool {
|
||||
let min1 = min(a1, a2);
|
||||
let max1 = max(a1, a2);
|
||||
let min2 = min(b1, b2);
|
||||
|
|
|
@ -16,7 +16,7 @@ export pick_file;
|
|||
export search;
|
||||
export relative_target_lib_path;
|
||||
|
||||
type pick<@T> = block(path: fs::path) -> option::t<T>;
|
||||
type pick<T> = block(path: fs::path) -> option::t<T>;
|
||||
|
||||
fn pick_file(file: fs::path, path: fs::path) -> option::t<fs::path> {
|
||||
if fs::basename(path) == file { option::some(path) }
|
||||
|
@ -57,7 +57,7 @@ fn mk_filesearch(maybe_sysroot: option::t<fs::path>,
|
|||
}
|
||||
|
||||
// FIXME #1001: This can't be an obj method
|
||||
fn search<@T>(filesearch: filesearch, pick: pick<T>) -> option::t<T> {
|
||||
fn search<T>(filesearch: filesearch, pick: pick<T>) -> option::t<T> {
|
||||
for lib_search_path in filesearch.lib_search_paths() {
|
||||
log #fmt["searching %s", lib_search_path];
|
||||
for path in fs::list_dir(lib_search_path) {
|
||||
|
|
|
@ -154,17 +154,17 @@ fn worker(p: port<request>) {
|
|||
|
||||
// Only windows needs to set the library path
|
||||
#[cfg(target_os = "win32")]
|
||||
fn maybe_with_lib_path<@T>(path: str, f: fn@() -> T) -> T {
|
||||
fn maybe_with_lib_path<T>(path: str, f: fn@() -> T) -> T {
|
||||
with_lib_path(path, f)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "macos")]
|
||||
fn maybe_with_lib_path<@T>(_path: str, f: fn@() -> T) -> T {
|
||||
fn maybe_with_lib_path<T>(_path: str, f: fn@() -> T) -> T {
|
||||
f()
|
||||
}
|
||||
|
||||
fn with_lib_path<@T>(path: str, f: fn@() -> T) -> T {
|
||||
fn with_lib_path<T>(path: str, f: fn@() -> T) -> T {
|
||||
let maybe_oldpath = getenv(util::lib_path_env_var());
|
||||
append_lib_path(path);
|
||||
let res = f();
|
||||
|
|
|
@ -227,7 +227,7 @@ fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap,
|
|||
check_variants_T(crate, codemap, filename, "ty", stolen.tys, pprust::ty_to_str, replace_ty_in_crate, cx);
|
||||
}
|
||||
|
||||
fn check_variants_T<@T>(
|
||||
fn check_variants_T<T>(
|
||||
crate: ast::crate,
|
||||
codemap: codemap::codemap,
|
||||
filename: str,
|
||||
|
|
|
@ -22,22 +22,22 @@ import std::vec::slice;
|
|||
import std::vec::len;
|
||||
import std::int;
|
||||
|
||||
fn vec_omit<@T>(v: [T], i: uint) -> [T] {
|
||||
fn vec_omit<T>(v: [T], i: uint) -> [T] {
|
||||
slice(v, 0u, i) + slice(v, i + 1u, len(v))
|
||||
}
|
||||
fn vec_dup<@T>(v: [T], i: uint) -> [T] {
|
||||
fn vec_dup<T>(v: [T], i: uint) -> [T] {
|
||||
slice(v, 0u, i) + [v[i]] + slice(v, i, len(v))
|
||||
}
|
||||
fn vec_swadj<@T>(v: [T], i: uint) -> [T] {
|
||||
fn vec_swadj<T>(v: [T], i: uint) -> [T] {
|
||||
slice(v, 0u, i) + [v[i + 1u], v[i]] + slice(v, i + 2u, len(v))
|
||||
}
|
||||
fn vec_prefix<@T>(v: [T], i: uint) -> [T] { slice(v, 0u, i) }
|
||||
fn vec_suffix<@T>(v: [T], i: uint) -> [T] { slice(v, i, len(v)) }
|
||||
fn vec_prefix<T>(v: [T], i: uint) -> [T] { slice(v, 0u, i) }
|
||||
fn vec_suffix<T>(v: [T], i: uint) -> [T] { slice(v, i, len(v)) }
|
||||
|
||||
fn vec_poke<@T>(v: [T], i: uint, x: T) -> [T] {
|
||||
fn vec_poke<T>(v: [T], i: uint, x: T) -> [T] {
|
||||
slice(v, 0u, i) + [x] + slice(v, i + 1u, len(v))
|
||||
}
|
||||
fn vec_insert<@T>(v: [T], i: uint, x: T) -> [T] {
|
||||
fn vec_insert<T>(v: [T], i: uint, x: T) -> [T] {
|
||||
slice(v, 0u, i) + [x] + slice(v, i, len(v))
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ fn ix(skip_low: uint, skip_high: uint, length: uint, it: block(uint)) {
|
|||
}
|
||||
|
||||
// Returns a bunch of modified versions of v, some of which introduce new elements (borrowed from xs).
|
||||
fn vec_edits<@T>(v: [T], xs: [T]) -> [[T]] {
|
||||
fn vec_edits<T>(v: [T], xs: [T]) -> [[T]] {
|
||||
let edits: [[T]] = [];
|
||||
let Lv: uint = len(v);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ fn choice<T>(r : rand::rng, v : [T]) -> T { assert vec::len(v) != 0u; v[under(r,
|
|||
fn unlikely(r : rand::rng, n : uint) -> bool { under(r, n) == 0u }
|
||||
|
||||
// shuffle a vec in place
|
||||
fn shuffle<@T>(r : rand::rng, &v : [mutable T]) {
|
||||
fn shuffle<T>(r : rand::rng, &v : [mutable T]) {
|
||||
let i = vec::len(v);
|
||||
while i >= 2u {
|
||||
// Loop invariant: elements with index >= i have been locked in place.
|
||||
|
@ -22,7 +22,7 @@ fn shuffle<@T>(r : rand::rng, &v : [mutable T]) {
|
|||
}
|
||||
|
||||
// create a shuffled copy of a vec
|
||||
fn shuffled<@T>(r : rand::rng, v : [T]) -> [T] {
|
||||
fn shuffled<T>(r : rand::rng, v : [T]) -> [T] {
|
||||
let w = vec::to_mut(v);
|
||||
shuffle(r, w);
|
||||
vec::from_mut(w) // Shouldn't this happen automatically?
|
||||
|
@ -35,7 +35,7 @@ fn shuffled<@T>(r : rand::rng, v : [T]) -> [T] {
|
|||
// * weighted_choice is O(number of choices) time
|
||||
// * weighted_vec is O(total weight) space
|
||||
type weighted<T> = { weight: uint, item: T };
|
||||
fn weighted_choice<@T>(r : rand::rng, v : [weighted<T>]) -> T {
|
||||
fn weighted_choice<T>(r : rand::rng, v : [weighted<T>]) -> T {
|
||||
assert vec::len(v) != 0u;
|
||||
let total = 0u;
|
||||
for {weight: weight, item: _} in v {
|
||||
|
|
|
@ -12,9 +12,9 @@ native "c-stack-cdecl" mod rustrt {
|
|||
type void;
|
||||
type rust_port;
|
||||
|
||||
fn chan_id_send<~T>(t: *sys::type_desc,
|
||||
target_task: task::task, target_port: port_id,
|
||||
-data: T);
|
||||
fn chan_id_send<unique T>(t: *sys::type_desc,
|
||||
target_task: task::task, target_port: port_id,
|
||||
-data: T);
|
||||
|
||||
fn new_port(unit_sz: uint) -> *rust_port;
|
||||
fn del_port(po: *rust_port);
|
||||
|
@ -23,38 +23,38 @@ native "c-stack-cdecl" mod rustrt {
|
|||
}
|
||||
|
||||
native "rust-intrinsic" mod rusti {
|
||||
fn recv<~T>(port: *rustrt::rust_port) -> T;
|
||||
fn recv<unique T>(port: *rustrt::rust_port) -> T;
|
||||
}
|
||||
|
||||
type port_id = int;
|
||||
|
||||
// It's critical that this only have one variant, so it has a record
|
||||
// layout, and will work in the rust_task structure in task.rs.
|
||||
tag chan<~T> { chan_t(task::task, port_id); }
|
||||
tag chan<unique T> { chan_t(task::task, port_id); }
|
||||
|
||||
resource port_ptr(po: *rustrt::rust_port) {
|
||||
rustrt::drop_port(po);
|
||||
rustrt::del_port(po);
|
||||
}
|
||||
|
||||
tag port<~T> { port_t(@port_ptr); }
|
||||
tag port<unique T> { port_t(@port_ptr); }
|
||||
|
||||
fn send<~T>(ch: chan<T>, -data: T) {
|
||||
fn send<unique T>(ch: chan<T>, -data: T) {
|
||||
let chan_t(t, p) = ch;
|
||||
rustrt::chan_id_send(sys::get_type_desc::<T>(), t, p, data);
|
||||
task::yield();
|
||||
}
|
||||
|
||||
fn port<~T>() -> port<T> {
|
||||
fn port<unique T>() -> port<T> {
|
||||
let p = rustrt::new_port(sys::size_of::<T>());
|
||||
ret port_t(@port_ptr(p));
|
||||
}
|
||||
|
||||
fn recv<~T>(p: port<T>) -> T {
|
||||
fn recv<unique T>(p: port<T>) -> T {
|
||||
ret rusti::recv(***p);
|
||||
}
|
||||
|
||||
fn chan<~T>(p: port<T>) -> chan<T> {
|
||||
fn chan<unique T>(p: port<T>) -> chan<T> {
|
||||
let id = rustrt::get_port_id(***p);
|
||||
ret chan_t(task::get_task_id(), id);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ type t<T> =
|
|||
fn get(int) -> T;
|
||||
};
|
||||
|
||||
fn create<@T>() -> t<T> {
|
||||
fn create<T>() -> t<T> {
|
||||
type cell<T> = option::t<T>;
|
||||
|
||||
let initial_capacity: uint = 32u; // 2^5
|
||||
|
@ -30,7 +30,7 @@ fn create<@T>() -> t<T> {
|
|||
|
||||
|
||||
|
||||
fn grow<@T>(nelts: uint, lo: uint, elts: [mutable cell<T>]) ->
|
||||
fn grow<T>(nelts: uint, lo: uint, elts: [mutable cell<T>]) ->
|
||||
[mutable cell<T>] {
|
||||
assert (nelts == vec::len(elts));
|
||||
let rv = [mutable];
|
||||
|
@ -46,10 +46,10 @@ fn create<@T>() -> t<T> {
|
|||
|
||||
ret rv;
|
||||
}
|
||||
fn get<@T>(elts: [mutable cell<T>], i: uint) -> T {
|
||||
fn get<T>(elts: [mutable cell<T>], i: uint) -> T {
|
||||
ret alt elts[i] { option::some(t) { t } _ { fail } };
|
||||
}
|
||||
obj deque<@T>(mutable nelts: uint,
|
||||
obj deque<T>(mutable nelts: uint,
|
||||
mutable lo: uint,
|
||||
mutable hi: uint,
|
||||
mutable elts: [mutable cell<T>]) {
|
||||
|
|
|
@ -10,7 +10,7 @@ fn either<T, U,
|
|||
alt value { left(l) { f_left(l) } right(r) { f_right(r) } }
|
||||
}
|
||||
|
||||
fn lefts<@T, U>(eithers: [t<T, U>]) -> [T] {
|
||||
fn lefts<T, U>(eithers: [t<T, U>]) -> [T] {
|
||||
let result: [T] = [];
|
||||
for elt: t<T, U> in eithers {
|
||||
alt elt { left(l) { result += [l]; } _ {/* fallthrough */ } }
|
||||
|
@ -18,7 +18,7 @@ fn lefts<@T, U>(eithers: [t<T, U>]) -> [T] {
|
|||
ret result;
|
||||
}
|
||||
|
||||
fn rights<T, @U>(eithers: [t<T, U>]) -> [U] {
|
||||
fn rights<T, U>(eithers: [t<T, U>]) -> [U] {
|
||||
let result: [U] = [];
|
||||
for elt: t<T, U> in eithers {
|
||||
alt elt { right(r) { result += [r]; } _ {/* fallthrough */ } }
|
||||
|
@ -26,7 +26,7 @@ fn rights<T, @U>(eithers: [t<T, U>]) -> [U] {
|
|||
ret result;
|
||||
}
|
||||
|
||||
fn partition<@T, @U>(eithers: [t<T, U>]) -> {lefts: [T], rights: [U]} {
|
||||
fn partition<T, U>(eithers: [t<T, U>]) -> {lefts: [T], rights: [U]} {
|
||||
let lefts: [T] = [];
|
||||
let rights: [U] = [];
|
||||
for elt: t<T, U> in eithers {
|
||||
|
|
|
@ -19,16 +19,16 @@ export insert;
|
|||
export find;
|
||||
export traverse;
|
||||
|
||||
tag tree_node<@K, @V> {
|
||||
tag tree_node<K, V> {
|
||||
empty;
|
||||
node(@K, @V, @tree_node<K, V>, @tree_node<K, V>);
|
||||
}
|
||||
|
||||
type treemap<@K, @V> = @tree_node<K, V>;
|
||||
type treemap<K, V> = @tree_node<K, V>;
|
||||
|
||||
fn init<@K, @V>() -> treemap<K, V> { @empty }
|
||||
fn init<K, V>() -> treemap<K, V> { @empty }
|
||||
|
||||
fn insert<@K, @V>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
|
||||
fn insert<K, V>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
|
||||
@alt m {
|
||||
@empty. { node(@k, @v, @empty, @empty) }
|
||||
@node(@kk, vv, left, right) {
|
||||
|
@ -41,7 +41,7 @@ fn insert<@K, @V>(m: treemap<K, V>, k: K, v: V) -> treemap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
fn find<@K, @V>(m: treemap<K, V>, k: K) -> option<V> {
|
||||
fn find<K, V>(m: treemap<K, V>, k: K) -> option<V> {
|
||||
alt *m {
|
||||
empty. { none }
|
||||
node(@kk, @v, left, right) {
|
||||
|
@ -54,7 +54,7 @@ fn find<@K, @V>(m: treemap<K, V>, k: K) -> option<V> {
|
|||
|
||||
|
||||
// Performs an in-order traversal
|
||||
fn traverse<@K, @V>(m: treemap<K, V>, f: fn(K, V)) {
|
||||
fn traverse<K, V>(m: treemap<K, V>, f: fn(K, V)) {
|
||||
alt *m {
|
||||
empty. { }
|
||||
node(@k, @v, _, _) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import option::{some, none};
|
|||
|
||||
tag list<T> { cons(T, @list<T>); nil; }
|
||||
|
||||
fn from_vec<@T>(v: [T]) -> list<T> {
|
||||
fn from_vec<T>(v: [T]) -> list<T> {
|
||||
let l = nil::<T>;
|
||||
// FIXME: This would be faster and more space efficient if it looped over
|
||||
// a reverse vector iterator. Unfortunately generic iterators seem not to
|
||||
|
@ -12,7 +12,7 @@ fn from_vec<@T>(v: [T]) -> list<T> {
|
|||
ret l;
|
||||
}
|
||||
|
||||
fn foldl<@T, @U>(ls_: list<T>, u: U, f: block(T, U) -> U) -> U {
|
||||
fn foldl<T, U>(ls_: list<T>, u: U, f: block(T, U) -> U) -> U {
|
||||
let accum: U = u;
|
||||
let ls = ls_;
|
||||
while true {
|
||||
|
@ -24,7 +24,7 @@ fn foldl<@T, @U>(ls_: list<T>, u: U, f: block(T, U) -> U) -> U {
|
|||
ret accum;
|
||||
}
|
||||
|
||||
fn find<@T, @U>(ls_: list<T>, f: block(T) -> option::t<U>) -> option::t<U> {
|
||||
fn find<T, U>(ls_: list<T>, f: block(T) -> option::t<U>) -> option::t<U> {
|
||||
let ls = ls_;
|
||||
while true {
|
||||
alt ls {
|
||||
|
@ -37,7 +37,7 @@ fn find<@T, @U>(ls_: list<T>, f: block(T) -> option::t<U>) -> option::t<U> {
|
|||
ret none;
|
||||
}
|
||||
|
||||
fn has<@T>(ls_: list<T>, elt: T) -> bool {
|
||||
fn has<T>(ls_: list<T>, elt: T) -> bool {
|
||||
let ls = ls_;
|
||||
while true {
|
||||
alt ls {
|
||||
|
@ -48,20 +48,20 @@ fn has<@T>(ls_: list<T>, elt: T) -> bool {
|
|||
ret false;
|
||||
}
|
||||
|
||||
fn length<@T>(ls: list<T>) -> uint {
|
||||
fn length<T>(ls: list<T>) -> uint {
|
||||
fn count<T>(_t: T, &&u: uint) -> uint { ret u + 1u; }
|
||||
ret foldl(ls, 0u, bind count(_, _));
|
||||
}
|
||||
|
||||
fn cdr<@T>(ls: list<T>) -> list<T> {
|
||||
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 {
|
||||
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> {
|
||||
fn append<T>(l: list<T>, m: list<T>) -> list<T> {
|
||||
alt l {
|
||||
nil. { ret m; }
|
||||
cons(x, xs) { let rest = append(*xs, m); ret cons(x, @rest); }
|
||||
|
|
|
@ -20,14 +20,14 @@ type hashmap<K, V> =
|
|||
};
|
||||
type hashset<K> = hashmap<K, ()>;
|
||||
|
||||
fn set_add<@K>(set: hashset<K>, key: K) -> bool { ret set.insert(key, ()); }
|
||||
fn set_add<K>(set: hashset<K>, key: K) -> bool { ret set.insert(key, ()); }
|
||||
|
||||
fn mk_hashmap<@K, @V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, V> {
|
||||
fn mk_hashmap<K, V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, V> {
|
||||
let initial_capacity: uint = 32u; // 2^5
|
||||
|
||||
let load_factor: util::rational = {num: 3, den: 4};
|
||||
tag bucket<@K, @V> { nil; deleted; some(K, V); }
|
||||
fn make_buckets<@K, @V>(nbkts: uint) -> [mutable bucket<K, V>] {
|
||||
tag bucket<K, V> { nil; deleted; some(K, V); }
|
||||
fn make_buckets<K, V>(nbkts: uint) -> [mutable bucket<K, V>] {
|
||||
ret vec::init_elt_mut::<bucket<K, V>>(nil::<K, V>, nbkts);
|
||||
}
|
||||
// Derive two hash functions from the one given by taking the upper
|
||||
|
@ -54,10 +54,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 {
|
||||
|
@ -75,9 +74,8 @@ fn mk_hashmap<@K, @V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, V> {
|
|||
}
|
||||
fail; // full table
|
||||
}
|
||||
fn find_common<@K,
|
||||
@V>(hasher: hashfn<K>, eqer: eqfn<K>,
|
||||
bkts: [mutable bucket<K, V>], nbkts: uint, key: K) ->
|
||||
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);
|
||||
|
@ -97,10 +95,9 @@ fn mk_hashmap<@K, @V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, 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_) {
|
||||
|
@ -112,7 +109,7 @@ fn mk_hashmap<@K, @V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, V> {
|
|||
}
|
||||
}
|
||||
}
|
||||
obj hashmap<@K, @V>(hasher: hashfn<K>,
|
||||
obj hashmap<K, V>(hasher: hashfn<K>,
|
||||
eqer: eqfn<K>,
|
||||
mutable bkts: [mutable bucket<K, V>],
|
||||
mutable nbkts: uint,
|
||||
|
@ -199,17 +196,17 @@ fn mk_hashmap<@K, @V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, V> {
|
|||
|
||||
// Hash map constructors for basic types
|
||||
|
||||
fn new_str_hash<@V>() -> hashmap<str, V> {
|
||||
fn new_str_hash<V>() -> hashmap<str, V> {
|
||||
ret mk_hashmap(str::hash, str::eq);
|
||||
}
|
||||
|
||||
fn new_int_hash<@V>() -> hashmap<int, 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(hash_int, eq_int);
|
||||
}
|
||||
|
||||
fn new_uint_hash<@V>() -> hashmap<uint, V> {
|
||||
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(hash_uint, eq_uint);
|
||||
|
|
|
@ -18,5 +18,5 @@ fn atan(x: float) -> float { llvm::atan(x) }
|
|||
|
||||
const pi: float = 3.141592653589793;
|
||||
|
||||
fn min<@T>(x: T, y: T) -> T { x < y ? x : y }
|
||||
fn max<@T>(x: T, y: T) -> T { x < y ? y : x }
|
||||
fn min<T>(x: T, y: T) -> T { x < y ? x : y }
|
||||
fn max<T>(x: T, y: T) -> T { x < y ? y : x }
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
// lib/option::rs
|
||||
|
||||
tag t<@T> { none; some(T); }
|
||||
tag t<T> { none; some(T); }
|
||||
|
||||
fn get<@T>(opt: t<T>) -> &T {
|
||||
fn get<T>(opt: t<T>) -> &T {
|
||||
alt opt { some(x) { ret x; } none. { fail "option none"; } }
|
||||
}
|
||||
|
||||
fn map<@T, @U>(f: block(T) -> U, opt: t<T>) -> t<U> {
|
||||
fn map<T, U>(f: block(T) -> U, opt: t<T>) -> t<U> {
|
||||
alt opt { some(x) { some(f(x)) } none. { none } }
|
||||
}
|
||||
|
||||
fn is_none<@T>(opt: t<T>) -> bool {
|
||||
fn is_none<T>(opt: t<T>) -> bool {
|
||||
alt opt { none. { true } some(_) { false } }
|
||||
}
|
||||
|
||||
fn is_some<@T>(opt: t<T>) -> bool { !is_none(opt) }
|
||||
fn is_some<T>(opt: t<T>) -> bool { !is_none(opt) }
|
||||
|
||||
fn from_maybe<@T>(def: T, opt: t<T>) -> T {
|
||||
fn from_maybe<T>(def: T, opt: t<T>) -> T {
|
||||
alt opt { some(x) { x } none. { def } }
|
||||
}
|
||||
|
||||
fn maybe<@T, @U>(def: U, f: block(T) -> U, opt: t<T>) -> U {
|
||||
fn maybe<T, U>(def: U, f: block(T) -> U, opt: t<T>) -> U {
|
||||
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: block(T), opt: t<T>) {
|
||||
fn may<T>(f: block(T), opt: t<T>) {
|
||||
alt opt { none. {/* nothing */ } some(t) { f(t); } }
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ native "rust-intrinsic" mod rusti {
|
|||
fn ptr_offset<T>(ptr: *T, count: uint) -> *T;
|
||||
}
|
||||
|
||||
fn addr_of<@T>(val: T) -> *mutable T { ret rusti::addr_of(val); }
|
||||
fn offset<@T>(ptr: *T, count: uint) -> *T {
|
||||
fn addr_of<T>(val: T) -> *mutable T { ret rusti::addr_of(val); }
|
||||
fn offset<T>(ptr: *T, count: uint) -> *T {
|
||||
ret rusti::ptr_offset(ptr, count);
|
||||
}
|
||||
|
||||
fn null<@T>() -> *T { ret unsafe::reinterpret_cast(0u); }
|
||||
fn null<T>() -> *T { ret unsafe::reinterpret_cast(0u); }
|
||||
|
|
|
@ -8,32 +8,32 @@ import option::{some, none};
|
|||
// to be.
|
||||
type smallintmap<T> = @{mutable v: [mutable option::t<T>]};
|
||||
|
||||
fn mk<@T>() -> smallintmap<T> {
|
||||
fn mk<T>() -> smallintmap<T> {
|
||||
let v: [mutable option::t<T>] = [mutable];
|
||||
ret @{mutable v: v};
|
||||
}
|
||||
|
||||
fn insert<@T>(m: smallintmap<T>, key: uint, val: T) {
|
||||
fn insert<T>(m: smallintmap<T>, key: uint, val: T) {
|
||||
vec::grow_set::<option::t<T>>(m.v, key, none::<T>, some::<T>(val));
|
||||
}
|
||||
|
||||
fn find<@T>(m: smallintmap<T>, key: uint) -> option::t<T> {
|
||||
fn find<T>(m: smallintmap<T>, key: uint) -> option::t<T> {
|
||||
if key < vec::len::<option::t<T>>(m.v) { ret m.v[key]; }
|
||||
ret none::<T>;
|
||||
}
|
||||
|
||||
fn get<@T>(m: smallintmap<T>, key: uint) -> T {
|
||||
fn get<T>(m: smallintmap<T>, key: uint) -> T {
|
||||
alt find::<T>(m, key) {
|
||||
none::<T>. { log_err "smallintmap::get(): key not present"; fail; }
|
||||
some::<T>(v) { ret v; }
|
||||
}
|
||||
}
|
||||
|
||||
fn contains_key<@T>(m: smallintmap<T>, key: uint) -> bool {
|
||||
fn contains_key<T>(m: smallintmap<T>, key: uint) -> bool {
|
||||
ret !option::is_none(find::<T>(m, key));
|
||||
}
|
||||
|
||||
fn truncate<@T>(m: smallintmap<T>, len: uint) {
|
||||
fn truncate<T>(m: smallintmap<T>, len: uint) {
|
||||
m.v = vec::slice_mut::<option::t<T>>(m.v, 0u, len);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ export quick_sort3;
|
|||
|
||||
type lteq<T> = block(T, T) -> bool;
|
||||
|
||||
fn merge_sort<@T>(le: lteq<T>, v: [T]) -> [T] {
|
||||
fn merge<@T>(le: lteq<T>, a: [T], b: [T]) -> [T] {
|
||||
fn merge_sort<T>(le: lteq<T>, v: [T]) -> [T] {
|
||||
fn merge<T>(le: lteq<T>, a: [T], b: [T]) -> [T] {
|
||||
let rs: [T] = [];
|
||||
let a_len: uint = len::<T>(a);
|
||||
let a_ix: uint = 0u;
|
||||
|
@ -32,13 +32,13 @@ fn merge_sort<@T>(le: lteq<T>, v: [T]) -> [T] {
|
|||
ret merge::<T>(le, merge_sort::<T>(le, a), merge_sort::<T>(le, b));
|
||||
}
|
||||
|
||||
fn swap<@T>(arr: [mutable T], x: uint, y: uint) {
|
||||
fn swap<T>(arr: [mutable T], x: uint, y: uint) {
|
||||
let a = arr[x];
|
||||
arr[x] = arr[y];
|
||||
arr[y] = a;
|
||||
}
|
||||
|
||||
fn part<@T>(compare_func: lteq<T>, arr: [mutable T], left: uint, right: uint,
|
||||
fn part<T>(compare_func: lteq<T>, arr: [mutable T], left: uint, right: uint,
|
||||
pivot: uint) -> uint {
|
||||
let pivot_value = arr[pivot];
|
||||
swap::<T>(arr, pivot, right);
|
||||
|
@ -55,7 +55,7 @@ fn part<@T>(compare_func: lteq<T>, arr: [mutable T], left: uint, right: uint,
|
|||
ret storage_index;
|
||||
}
|
||||
|
||||
fn qsort<@T>(compare_func: lteq<T>, arr: [mutable T], left: uint,
|
||||
fn qsort<T>(compare_func: lteq<T>, arr: [mutable T], left: uint,
|
||||
right: uint) {
|
||||
if right > left {
|
||||
let pivot = (left + right) / 2u;
|
||||
|
@ -68,7 +68,7 @@ fn qsort<@T>(compare_func: lteq<T>, arr: [mutable T], left: uint,
|
|||
}
|
||||
}
|
||||
|
||||
fn quick_sort<@T>(compare_func: lteq<T>, arr: [mutable T]) {
|
||||
fn quick_sort<T>(compare_func: lteq<T>, arr: [mutable T]) {
|
||||
if len::<T>(arr) == 0u { ret; }
|
||||
qsort::<T>(compare_func, arr, 0u, len::<T>(arr) - 1u);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ fn quick_sort<@T>(compare_func: lteq<T>, arr: [mutable T]) {
|
|||
// http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf
|
||||
// According to these slides this is the algorithm of choice for
|
||||
// 'randomly ordered keys, abstract compare' & 'small number of key values'
|
||||
fn qsort3<@T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
|
||||
fn qsort3<T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
|
||||
arr: [mutable T], left: int, right: int) {
|
||||
if right <= left { ret; }
|
||||
let v: T = arr[right];
|
||||
|
@ -126,8 +126,8 @@ fn qsort3<@T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
|
|||
qsort3::<T>(compare_func_lt, compare_func_eq, arr, i, right);
|
||||
}
|
||||
|
||||
fn quick_sort3<@T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
|
||||
arr: [mutable T]) {
|
||||
fn quick_sort3<T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
|
||||
arr: [mutable T]) {
|
||||
if len::<T>(arr) == 0u { ret; }
|
||||
qsort3::<T>(compare_func_lt, compare_func_eq, arr, 0,
|
||||
(len::<T>(arr) as int) - 1);
|
||||
|
|
|
@ -95,16 +95,16 @@ fn unpin() { rustrt2::unpin_task(); }
|
|||
|
||||
fn set_min_stack(stack_size: uint) { rustrt2::set_min_stack(stack_size); }
|
||||
|
||||
fn spawn<~T>(-data: T, f: fn(T)) -> task {
|
||||
fn spawn<unique T>(-data: T, f: fn(T)) -> task {
|
||||
spawn_inner2(data, f, none)
|
||||
}
|
||||
|
||||
fn spawn_notify<~T>(-data: T, f: fn(T),
|
||||
fn spawn_notify<unique T>(-data: T, f: fn(T),
|
||||
notify: comm::chan<task_notification>) -> task {
|
||||
spawn_inner2(data, f, some(notify))
|
||||
}
|
||||
|
||||
fn spawn_joinable<~T>(-data: T, f: fn(T)) -> joinable_task {
|
||||
fn spawn_joinable<unique T>(-data: T, f: fn(T)) -> joinable_task {
|
||||
let p = comm::port::<task_notification>();
|
||||
let id = spawn_notify(data, f, comm::chan::<task_notification>(p));
|
||||
ret (id, p);
|
||||
|
@ -120,11 +120,11 @@ fn spawn_joinable<~T>(-data: T, f: fn(T)) -> joinable_task {
|
|||
//
|
||||
// After the transition this should all be rewritten.
|
||||
|
||||
fn spawn_inner2<~T>(-data: T, f: fn(T),
|
||||
notify: option<comm::chan<task_notification>>)
|
||||
fn spawn_inner2<unique T>(-data: T, f: fn(T),
|
||||
notify: option<comm::chan<task_notification>>)
|
||||
-> task_id {
|
||||
|
||||
fn wrapper<~T>(-data: *u8, f: fn(T)) {
|
||||
fn wrapper<unique T>(-data: *u8, f: fn(T)) {
|
||||
let data: ~T = unsafe::reinterpret_cast(data);
|
||||
f(*data);
|
||||
}
|
||||
|
|
|
@ -41,13 +41,13 @@ type test_name = str;
|
|||
// the test succeeds; if the function fails then the test fails. We
|
||||
// may need to come up with a more clever definition of test in order
|
||||
// to support isolation of tests into tasks.
|
||||
type test_fn<@T> = T;
|
||||
type test_fn<T> = T;
|
||||
|
||||
type default_test_fn = test_fn<fn()>;
|
||||
|
||||
// The definition of a single test. A test runner will run a list of
|
||||
// these.
|
||||
type test_desc<@T> = {
|
||||
type test_desc<T> = {
|
||||
name: test_name,
|
||||
fn: test_fn<T>,
|
||||
ignore: bool
|
||||
|
@ -100,7 +100,7 @@ type joinable = (task, comm::port<task::task_notification>);
|
|||
// In cases where test functions are closures it is not ok to just dump them
|
||||
// into a task and run them, so this transformation gives the caller a chance
|
||||
// to create the test task.
|
||||
type test_to_task<@T> = fn@(test_fn<T>) -> joinable;
|
||||
type test_to_task<T> = fn@(test_fn<T>) -> joinable;
|
||||
|
||||
// A simple console test runner
|
||||
fn run_tests_console(opts: test_opts,
|
||||
|
@ -108,7 +108,7 @@ fn run_tests_console(opts: test_opts,
|
|||
run_tests_console_(opts, tests, default_test_to_task)
|
||||
}
|
||||
|
||||
fn run_tests_console_<@T>(opts: test_opts, tests: [test_desc<T>],
|
||||
fn run_tests_console_<T>(opts: test_opts, tests: [test_desc<T>],
|
||||
to_task: test_to_task<T>) -> bool {
|
||||
|
||||
type test_state =
|
||||
|
@ -120,7 +120,7 @@ fn run_tests_console_<@T>(opts: test_opts, tests: [test_desc<T>],
|
|||
mutable ignored: uint,
|
||||
mutable failures: [test_desc<T>]};
|
||||
|
||||
fn callback<@T>(event: testevent<T>, st: test_state) {
|
||||
fn callback<T>(event: testevent<T>, st: test_state) {
|
||||
alt event {
|
||||
te_filtered(filtered_tests) {
|
||||
st.total = vec::len(filtered_tests);
|
||||
|
@ -207,13 +207,13 @@ fn run_tests_console_<@T>(opts: test_opts, tests: [test_desc<T>],
|
|||
|
||||
fn use_color() -> bool { ret get_concurrency() == 1u; }
|
||||
|
||||
tag testevent<@T> {
|
||||
tag testevent<T> {
|
||||
te_filtered([test_desc<T>]);
|
||||
te_wait(test_desc<T>);
|
||||
te_result(test_desc<T>, test_result);
|
||||
}
|
||||
|
||||
fn run_tests<@T>(opts: test_opts, tests: [test_desc<T>],
|
||||
fn run_tests<T>(opts: test_opts, tests: [test_desc<T>],
|
||||
to_task: test_to_task<T>,
|
||||
callback: fn@(testevent<T>)) {
|
||||
|
||||
|
@ -248,7 +248,7 @@ fn run_tests<@T>(opts: test_opts, tests: [test_desc<T>],
|
|||
|
||||
fn get_concurrency() -> uint { rustrt::sched_threads() }
|
||||
|
||||
fn filter_tests<@T>(opts: test_opts,
|
||||
fn filter_tests<T>(opts: test_opts,
|
||||
tests: [test_desc<T>]) -> [test_desc<T>] {
|
||||
let filtered = tests;
|
||||
|
||||
|
@ -262,7 +262,7 @@ fn filter_tests<@T>(opts: test_opts,
|
|||
option::none. { "" }
|
||||
};
|
||||
|
||||
fn filter_fn<@T>(test: test_desc<T>, filter_str: str) ->
|
||||
fn filter_fn<T>(test: test_desc<T>, filter_str: str) ->
|
||||
option::t<test_desc<T>> {
|
||||
if str::find(test.name, filter_str) >= 0 {
|
||||
ret option::some(test);
|
||||
|
@ -278,7 +278,7 @@ fn filter_tests<@T>(opts: test_opts,
|
|||
filtered = if !opts.run_ignored {
|
||||
filtered
|
||||
} else {
|
||||
fn filter<@T>(test: test_desc<T>) -> option::t<test_desc<T>> {
|
||||
fn filter<T>(test: test_desc<T>) -> option::t<test_desc<T>> {
|
||||
if test.ignore {
|
||||
ret option::some({name: test.name,
|
||||
fn: test.fn,
|
||||
|
@ -292,7 +292,7 @@ fn filter_tests<@T>(opts: test_opts,
|
|||
// Sort the tests alphabetically
|
||||
filtered =
|
||||
{
|
||||
fn lteq<@T>(t1: test_desc<T>, t2: test_desc<T>) -> bool {
|
||||
fn lteq<T>(t1: test_desc<T>, t2: test_desc<T>) -> bool {
|
||||
str::lteq(t1.name, t2.name)
|
||||
}
|
||||
sort::merge_sort(bind lteq(_, _), filtered)
|
||||
|
@ -301,9 +301,9 @@ fn filter_tests<@T>(opts: test_opts,
|
|||
ret filtered;
|
||||
}
|
||||
|
||||
type test_future<@T> = {test: test_desc<T>, wait: fn@() -> test_result};
|
||||
type test_future<T> = {test: test_desc<T>, wait: fn@() -> test_result};
|
||||
|
||||
fn run_test<@T>(test: test_desc<T>,
|
||||
fn run_test<T>(test: test_desc<T>,
|
||||
to_task: test_to_task<T>) -> test_future<T> {
|
||||
if !test.ignore {
|
||||
let test_task = to_task(test.fn);
|
||||
|
|
|
@ -16,13 +16,13 @@ export insert;
|
|||
export find;
|
||||
export traverse;
|
||||
|
||||
tag tree_node<@K, @V> { empty; node(@K, @V, treemap<K, V>, treemap<K, V>); }
|
||||
tag tree_node<K, V> { empty; node(@K, @V, treemap<K, V>, treemap<K, V>); }
|
||||
|
||||
type treemap<@K, @V> = @mutable tree_node<K, V>;
|
||||
type treemap<K, V> = @mutable tree_node<K, V>;
|
||||
|
||||
fn init<@K, @V>() -> treemap<K, V> { @mutable empty }
|
||||
fn init<K, V>() -> treemap<K, V> { @mutable empty }
|
||||
|
||||
fn insert<@K, @V>(m: treemap<K, V>, k: K, v: V) {
|
||||
fn insert<K, V>(m: treemap<K, V>, k: K, v: V) {
|
||||
alt m {
|
||||
@empty. { *m = node(@k, @v, @mutable empty, @mutable empty); }
|
||||
@node(@kk, _, _, _) {
|
||||
|
@ -36,7 +36,7 @@ fn insert<@K, @V>(m: treemap<K, V>, k: K, v: V) {
|
|||
}
|
||||
}
|
||||
|
||||
fn find<@K, @V>(m: treemap<K, V>, k: K) -> option<V> {
|
||||
fn find<K, V>(m: treemap<K, V>, k: K) -> option<V> {
|
||||
alt *m {
|
||||
empty. { none }
|
||||
node(@kk, @v, _, _) {
|
||||
|
@ -52,7 +52,7 @@ fn find<@K, @V>(m: treemap<K, V>, k: K) -> option<V> {
|
|||
}
|
||||
|
||||
// Performs an in-order traversal
|
||||
fn traverse<@K, @V>(m: treemap<K, V>, f: fn@(K, V)) {
|
||||
fn traverse<K, V>(m: treemap<K, V>, f: fn@(K, V)) {
|
||||
alt *m {
|
||||
empty. { }
|
||||
node(k, v, _, _) {
|
||||
|
|
|
@ -5,10 +5,10 @@ native "rust-intrinsic" mod rusti {
|
|||
}
|
||||
|
||||
native "c-stack-cdecl" mod rustrt {
|
||||
fn leak<@T>(-thing: T);
|
||||
fn leak<T>(-thing: T);
|
||||
}
|
||||
|
||||
// Casts the value at `src` to U. The two types must have the same length.
|
||||
fn reinterpret_cast<T, @U>(src: T) -> U { ret rusti::cast(src); }
|
||||
fn reinterpret_cast<T, U>(src: T) -> U { ret rusti::cast(src); }
|
||||
|
||||
fn leak<@T>(-thing: T) { rustrt::leak(thing); }
|
||||
fn leak<T>(-thing: T) { rustrt::leak(thing); }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
pure fn id<@T>(x: T) -> T { x }
|
||||
pure fn id<T>(x: T) -> T { x }
|
||||
|
||||
fn unreachable() -> ! {
|
||||
fail "Internal error: entered unreachable code";
|
||||
|
|
|
@ -18,7 +18,7 @@ native "c-stack-cdecl" mod rustrt {
|
|||
}
|
||||
|
||||
/// Reserves space for `n` elements in the given vector.
|
||||
fn reserve<@T>(&v: [mutable? T], n: uint) {
|
||||
fn reserve<T>(&v: [mutable? T], n: uint) {
|
||||
rustrt::vec_reserve_shared(sys::get_type_desc::<T>(), v, n);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ pure fn len<T>(v: [mutable? T]) -> uint { unchecked { rusti::vec_len(v) } }
|
|||
|
||||
type init_op<T> = fn@(uint) -> T;
|
||||
|
||||
fn init_fn<@T>(op: init_op<T>, n_elts: uint) -> [T] {
|
||||
fn init_fn<T>(op: init_op<T>, n_elts: uint) -> [T] {
|
||||
let v = [];
|
||||
reserve(v, n_elts);
|
||||
let i: uint = 0u;
|
||||
|
@ -35,7 +35,7 @@ fn init_fn<@T>(op: init_op<T>, n_elts: uint) -> [T] {
|
|||
}
|
||||
|
||||
// TODO: Remove me once we have slots.
|
||||
fn init_fn_mut<@T>(op: init_op<T>, n_elts: uint) -> [mutable T] {
|
||||
fn init_fn_mut<T>(op: init_op<T>, n_elts: uint) -> [mutable T] {
|
||||
let v = [mutable];
|
||||
reserve(v, n_elts);
|
||||
let i: uint = 0u;
|
||||
|
@ -43,7 +43,7 @@ fn init_fn_mut<@T>(op: init_op<T>, n_elts: uint) -> [mutable T] {
|
|||
ret v;
|
||||
}
|
||||
|
||||
fn init_elt<@T>(t: T, n_elts: uint) -> [T] {
|
||||
fn init_elt<T>(t: T, n_elts: uint) -> [T] {
|
||||
let v = [];
|
||||
reserve(v, n_elts);
|
||||
let i: uint = 0u;
|
||||
|
@ -52,7 +52,7 @@ fn init_elt<@T>(t: T, n_elts: uint) -> [T] {
|
|||
}
|
||||
|
||||
// TODO: Remove me once we have slots.
|
||||
fn init_elt_mut<@T>(t: T, n_elts: uint) -> [mutable T] {
|
||||
fn init_elt_mut<T>(t: T, n_elts: uint) -> [mutable T] {
|
||||
let v = [mutable];
|
||||
reserve(v, n_elts);
|
||||
let i: uint = 0u;
|
||||
|
@ -62,14 +62,14 @@ fn init_elt_mut<@T>(t: T, n_elts: uint) -> [mutable T] {
|
|||
|
||||
// FIXME: Possible typestate postcondition:
|
||||
// len(result) == len(v) (needs issue #586)
|
||||
fn to_mut<@T>(v: [T]) -> [mutable T] {
|
||||
fn to_mut<T>(v: [T]) -> [mutable T] {
|
||||
let vres = [mutable];
|
||||
for t: T in v { vres += [mutable t]; }
|
||||
ret vres;
|
||||
}
|
||||
|
||||
// Same comment as from_mut
|
||||
fn from_mut<@T>(v: [mutable T]) -> [T] {
|
||||
fn from_mut<T>(v: [mutable T]) -> [T] {
|
||||
let vres = [];
|
||||
for t: T in v { vres += [t]; }
|
||||
ret vres;
|
||||
|
@ -87,26 +87,26 @@ pure fn is_not_empty<T>(v: [mutable? T]) -> bool { ret !is_empty(v); }
|
|||
// Accessors
|
||||
|
||||
/// Returns the first element of a vector
|
||||
fn head<@T>(v: [mutable? T]) : is_not_empty(v) -> T { ret v[0]; }
|
||||
fn head<T>(v: [mutable? T]) : is_not_empty(v) -> T { ret v[0]; }
|
||||
|
||||
/// Returns all but the first element of a vector
|
||||
fn tail<@T>(v: [mutable? T]) : is_not_empty(v) -> [T] {
|
||||
fn tail<T>(v: [mutable? T]) : is_not_empty(v) -> [T] {
|
||||
ret slice(v, 1u, len(v));
|
||||
}
|
||||
|
||||
/// Returns the last element of `v`.
|
||||
fn last<@T>(v: [mutable? T]) -> option::t<T> {
|
||||
fn last<T>(v: [mutable? T]) -> option::t<T> {
|
||||
if len(v) == 0u { ret none; }
|
||||
ret some(v[len(v) - 1u]);
|
||||
}
|
||||
|
||||
/// Returns the last element of a non-empty vector `v`.
|
||||
fn last_total<@T>(v: [mutable? T]) : is_not_empty(v) -> T {
|
||||
fn last_total<T>(v: [mutable? T]) : is_not_empty(v) -> T {
|
||||
ret v[len(v) - 1u];
|
||||
}
|
||||
|
||||
/// Returns a copy of the elements from [`start`..`end`) from `v`.
|
||||
fn slice<@T>(v: [mutable? T], start: uint, end: uint) -> [T] {
|
||||
fn slice<T>(v: [mutable? T], start: uint, end: uint) -> [T] {
|
||||
assert (start <= end);
|
||||
assert (end <= len(v));
|
||||
let result = [];
|
||||
|
@ -117,7 +117,7 @@ fn slice<@T>(v: [mutable? T], start: uint, end: uint) -> [T] {
|
|||
}
|
||||
|
||||
// TODO: Remove me once we have slots.
|
||||
fn slice_mut<@T>(v: [mutable? T], start: uint, end: uint) -> [mutable T] {
|
||||
fn slice_mut<T>(v: [mutable? T], start: uint, end: uint) -> [mutable T] {
|
||||
assert (start <= end);
|
||||
assert (end <= len(v));
|
||||
let result = [mutable];
|
||||
|
@ -130,7 +130,7 @@ fn slice_mut<@T>(v: [mutable? T], start: uint, end: uint) -> [mutable T] {
|
|||
|
||||
// Mutators
|
||||
|
||||
fn shift<@T>(&v: [mutable? T]) -> T {
|
||||
fn shift<T>(&v: [mutable? T]) -> T {
|
||||
let ln = len::<T>(v);
|
||||
assert (ln > 0u);
|
||||
let e = v[0];
|
||||
|
@ -139,7 +139,7 @@ fn shift<@T>(&v: [mutable? T]) -> T {
|
|||
}
|
||||
|
||||
// TODO: Write this, unsafely, in a way that's not O(n).
|
||||
fn pop<@T>(&v: [mutable? T]) -> T {
|
||||
fn pop<T>(&v: [mutable? T]) -> T {
|
||||
let ln = len(v);
|
||||
assert (ln > 0u);
|
||||
ln -= 1u;
|
||||
|
@ -154,14 +154,14 @@ fn pop<@T>(&v: [mutable? T]) -> T {
|
|||
// Appending
|
||||
|
||||
/// Expands the given vector in-place by appending `n` copies of `initval`.
|
||||
fn grow<@T>(&v: [T], n: uint, initval: T) {
|
||||
fn grow<T>(&v: [T], n: uint, initval: T) {
|
||||
reserve(v, next_power_of_two(len(v) + n));
|
||||
let i: uint = 0u;
|
||||
while i < n { v += [initval]; i += 1u; }
|
||||
}
|
||||
|
||||
// TODO: Remove me once we have slots.
|
||||
fn grow_mut<@T>(&v: [mutable T], n: uint, initval: T) {
|
||||
fn grow_mut<T>(&v: [mutable T], n: uint, initval: T) {
|
||||
reserve(v, next_power_of_two(len(v) + n));
|
||||
let i: uint = 0u;
|
||||
while i < n { v += [mutable initval]; i += 1u; }
|
||||
|
@ -169,7 +169,7 @@ fn grow_mut<@T>(&v: [mutable T], n: uint, initval: T) {
|
|||
|
||||
/// Calls `f` `n` times and appends the results of these calls to the given
|
||||
/// vector.
|
||||
fn grow_fn<@T>(&v: [T], n: uint, init_fn: fn(uint) -> T) {
|
||||
fn grow_fn<T>(&v: [T], n: uint, init_fn: fn(uint) -> T) {
|
||||
reserve(v, next_power_of_two(len(v) + n));
|
||||
let i: uint = 0u;
|
||||
while i < n { v += [init_fn(i)]; i += 1u; }
|
||||
|
@ -178,7 +178,7 @@ fn grow_fn<@T>(&v: [T], n: uint, init_fn: fn(uint) -> T) {
|
|||
/// 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.
|
||||
fn grow_set<@T>(&v: [mutable T], index: uint, initval: T, val: T) {
|
||||
fn grow_set<T>(&v: [mutable T], index: uint, initval: T, val: T) {
|
||||
if index >= len(v) { grow_mut(v, index - len(v) + 1u, initval); }
|
||||
v[index] = val;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ fn grow_set<@T>(&v: [mutable T], index: uint, initval: T, val: T) {
|
|||
|
||||
// Functional utilities
|
||||
|
||||
fn map<@T, @U>(f: block(T) -> U, v: [mutable? T]) -> [U] {
|
||||
fn map<T, U>(f: block(T) -> U, v: [mutable? T]) -> [U] {
|
||||
let result = [];
|
||||
reserve(result, len(v));
|
||||
for elem: T in v {
|
||||
|
@ -196,7 +196,7 @@ fn map<@T, @U>(f: block(T) -> U, v: [mutable? T]) -> [U] {
|
|||
ret result;
|
||||
}
|
||||
|
||||
fn map2<@T, @U, @V>(f: block(T, U) -> V, v0: [T], v1: [U]) -> [V] {
|
||||
fn map2<T, U, V>(f: block(T, U) -> V, v0: [T], v1: [U]) -> [V] {
|
||||
let v0_len = len::<T>(v0);
|
||||
if v0_len != len::<U>(v1) { fail; }
|
||||
let u: [V] = [];
|
||||
|
@ -205,7 +205,7 @@ fn map2<@T, @U, @V>(f: block(T, U) -> V, v0: [T], v1: [U]) -> [V] {
|
|||
ret u;
|
||||
}
|
||||
|
||||
fn filter_map<@T, @U>(f: block(T) -> option::t<U>, v: [mutable? T]) -> [U] {
|
||||
fn filter_map<T, U>(f: block(T) -> option::t<U>, v: [mutable? T]) -> [U] {
|
||||
let result = [];
|
||||
for elem: T in v {
|
||||
let elem2 = elem; // satisfies alias checker
|
||||
|
@ -217,7 +217,7 @@ fn filter_map<@T, @U>(f: block(T) -> option::t<U>, v: [mutable? T]) -> [U] {
|
|||
ret result;
|
||||
}
|
||||
|
||||
fn filter<@T>(f: block(T) -> bool, v: [mutable? T]) -> [T] {
|
||||
fn filter<T>(f: block(T) -> bool, v: [mutable? T]) -> [T] {
|
||||
let result = [];
|
||||
for elem: T in v {
|
||||
let elem2 = elem; // satisfies alias checker
|
||||
|
@ -228,7 +228,7 @@ fn filter<@T>(f: block(T) -> bool, v: [mutable? T]) -> [T] {
|
|||
ret result;
|
||||
}
|
||||
|
||||
fn foldl<@T, @U>(p: block(U, T) -> U, z: U, v: [mutable? T]) -> U {
|
||||
fn foldl<T, U>(p: block(U, T) -> U, z: U, v: [mutable? T]) -> U {
|
||||
let sz = len(v);
|
||||
if sz == 0u { ret z; }
|
||||
let first = v[0];
|
||||
|
@ -257,12 +257,12 @@ fn count<T>(x: T, v: [mutable? T]) -> uint {
|
|||
ret cnt;
|
||||
}
|
||||
|
||||
fn find<@T>(f: block(T) -> bool, v: [T]) -> option::t<T> {
|
||||
fn find<T>(f: block(T) -> bool, v: [T]) -> option::t<T> {
|
||||
for elt: T in v { if f(elt) { ret some(elt); } }
|
||||
ret none;
|
||||
}
|
||||
|
||||
fn position<@T>(x: T, v: [T]) -> option::t<uint> {
|
||||
fn position<T>(x: T, v: [T]) -> option::t<uint> {
|
||||
let i: uint = 0u;
|
||||
while i < len(v) { if x == v[i] { ret some::<uint>(i); } i += 1u; }
|
||||
ret none;
|
||||
|
@ -282,13 +282,13 @@ pure fn same_length<T, U>(xs: [T], ys: [U]) -> bool {
|
|||
// 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)
|
||||
fn unzip<@T, @U>(v: [(T, U)]) -> ([T], [U]) {
|
||||
fn unzip<T, U>(v: [(T, U)]) -> ([T], [U]) {
|
||||
let as = [], bs = [];
|
||||
for (a, b) in v { as += [a]; bs += [b]; }
|
||||
ret (as, bs);
|
||||
}
|
||||
|
||||
fn zip<@T, @U>(v: [T], u: [U]) : same_length(v, u) -> [(T, U)] {
|
||||
fn zip<T, U>(v: [T], u: [U]) : same_length(v, u) -> [(T, U)] {
|
||||
let zipped = [];
|
||||
let sz = len(v), i = 0u;
|
||||
assert (sz == len(u));
|
||||
|
@ -297,14 +297,14 @@ fn zip<@T, @U>(v: [T], u: [U]) : same_length(v, u) -> [(T, U)] {
|
|||
}
|
||||
|
||||
// Swaps two elements in a vector
|
||||
fn swap<@T>(v: [mutable T], a: uint, b: uint) {
|
||||
fn swap<T>(v: [mutable T], a: uint, b: uint) {
|
||||
let t: T = v[a];
|
||||
v[a] = v[b];
|
||||
v[b] = t;
|
||||
}
|
||||
|
||||
// In place vector reversal
|
||||
fn reverse<@T>(v: [mutable T]) {
|
||||
fn reverse<T>(v: [mutable T]) {
|
||||
let i: uint = 0u;
|
||||
let ln = len::<T>(v);
|
||||
while i < ln / 2u { swap(v, i, ln - i - 1u); i += 1u; }
|
||||
|
@ -312,7 +312,7 @@ fn reverse<@T>(v: [mutable T]) {
|
|||
|
||||
|
||||
// Functional vector reversal. Returns a reversed copy of v.
|
||||
fn reversed<@T>(v: [T]) -> [T] {
|
||||
fn reversed<T>(v: [T]) -> [T] {
|
||||
let rs: [T] = [];
|
||||
let i = len::<T>(v);
|
||||
if i == 0u { ret rs; } else { i -= 1u; }
|
||||
|
@ -336,7 +336,7 @@ fn enum_uints(start: uint, end: uint) : uint::le(start, end) -> [uint] {
|
|||
ret r;
|
||||
}
|
||||
|
||||
fn eachi<@T>(f: block(T, uint) -> (), v: [mutable? T]) {
|
||||
fn eachi<T>(f: block(T, uint) -> (), v: [mutable? T]) {
|
||||
let i = 0u;
|
||||
let l = len(v);
|
||||
while (i < l) {
|
||||
|
@ -347,7 +347,7 @@ fn eachi<@T>(f: block(T, uint) -> (), v: [mutable? T]) {
|
|||
}
|
||||
|
||||
// Iterate over a list with with the indexes
|
||||
fn iter2<@T>(v: [T], it: block(uint, T)) {
|
||||
fn iter2<T>(v: [T], it: block(uint, T)) {
|
||||
let i = 0u;
|
||||
for x in v { it(i, x); i += 1u; }
|
||||
}
|
||||
|
@ -355,23 +355,23 @@ fn iter2<@T>(v: [T], it: block(uint, T)) {
|
|||
mod unsafe {
|
||||
type vec_repr = {mutable fill: uint, mutable alloc: uint, data: u8};
|
||||
|
||||
unsafe fn from_buf<@T>(ptr: *T, elts: uint) -> [T] {
|
||||
unsafe fn from_buf<T>(ptr: *T, elts: uint) -> [T] {
|
||||
ret rustrt::vec_from_buf_shared(sys::get_type_desc::<T>(),
|
||||
ptr, elts);
|
||||
}
|
||||
|
||||
unsafe fn set_len<@T>(&v: [T], new_len: uint) {
|
||||
unsafe fn set_len<T>(&v: [T], new_len: uint) {
|
||||
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
||||
(**repr).fill = new_len * sys::size_of::<T>();
|
||||
}
|
||||
|
||||
unsafe fn to_ptr<@T>(v: [T]) -> *T {
|
||||
unsafe fn to_ptr<T>(v: [T]) -> *T {
|
||||
let repr: **vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
|
||||
ret ::unsafe::reinterpret_cast(addr_of((**repr).data));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn to_ptr<@T>(v: [T]) -> *T { ret unsafe::to_ptr(v); }
|
||||
unsafe fn to_ptr<T>(v: [T]) -> *T { ret unsafe::to_ptr(v); }
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
|
|
|
@ -55,25 +55,25 @@ mod map_reduce {
|
|||
export reducer;
|
||||
export map_reduce;
|
||||
|
||||
type putter<~K, ~V> = fn(K, V);
|
||||
type putter<unique K, unique V> = fn(K, V);
|
||||
|
||||
// FIXME: the first K1 parameter should probably be a -, but that
|
||||
// doesn't parse at the moment.
|
||||
type mapper<~K1, ~K2, ~V> = fn(K1, putter<K2, V>);
|
||||
type mapper<unique K1, unique K2, unique V> = fn(K1, putter<K2, V>);
|
||||
|
||||
type getter<~V> = fn() -> option<V>;
|
||||
type getter<unique V> = fn() -> option<V>;
|
||||
|
||||
type reducer<~K, ~V> = fn(K, getter<V>);
|
||||
type reducer<unique K, unique V> = fn(K, getter<V>);
|
||||
|
||||
tag ctrl_proto<~K, ~V> {
|
||||
tag ctrl_proto<unique K, unique V> {
|
||||
find_reducer(K, chan<chan<reduce_proto<V>>>);
|
||||
mapper_done;
|
||||
}
|
||||
|
||||
tag reduce_proto<~V> { emit_val(V); done; ref; release; }
|
||||
tag reduce_proto<unique V> { emit_val(V); done; ref; release; }
|
||||
|
||||
fn start_mappers<~K1, ~K2,
|
||||
~V>(map: mapper<K1, K2, V>,
|
||||
fn start_mappers<unique K1, unique K2,
|
||||
unique V>(map: mapper<K1, K2, V>,
|
||||
ctrl: chan<ctrl_proto<K2, V>>, inputs: [K1]) ->
|
||||
[joinable_task] {
|
||||
let tasks = [];
|
||||
|
@ -84,14 +84,15 @@ mod map_reduce {
|
|||
ret tasks;
|
||||
}
|
||||
|
||||
fn map_task<~K1, ~K2,
|
||||
~V>(-map: mapper<K1, K2, V>, -ctrl: chan<ctrl_proto<K2, V>>,
|
||||
fn map_task<unique K1, unique K2,
|
||||
unique V>(-map: mapper<K1, K2, V>,
|
||||
-ctrl: chan<ctrl_proto<K2, V>>,
|
||||
-input: K1) {
|
||||
// log_err "map_task " + input;
|
||||
let intermediates = treemap::init();
|
||||
|
||||
fn emit<~K2,
|
||||
~V>(im: treemap::treemap<K2, chan<reduce_proto<V>>>,
|
||||
fn emit<unique K2,
|
||||
unique V>(im: treemap::treemap<K2, chan<reduce_proto<V>>>,
|
||||
ctrl: chan<ctrl_proto<K2, V>>, key: K2, val: V) {
|
||||
let c;
|
||||
alt treemap::find(im, key) {
|
||||
|
@ -109,15 +110,15 @@ mod map_reduce {
|
|||
|
||||
map(input, bind emit(intermediates, ctrl, _, _));
|
||||
|
||||
fn finish<~K, ~V>(_k: K, v: chan<reduce_proto<V>>) {
|
||||
fn finish<unique K, unique V>(_k: K, v: chan<reduce_proto<V>>) {
|
||||
send(v, release);
|
||||
}
|
||||
treemap::traverse(intermediates, finish);
|
||||
send(ctrl, mapper_done);
|
||||
}
|
||||
|
||||
fn reduce_task<~K,
|
||||
~V>(-reduce: reducer<K, V>, -key: K,
|
||||
fn reduce_task<unique K,
|
||||
unique V>(-reduce: reducer<K, V>, -key: K,
|
||||
-out: chan<chan<reduce_proto<V>>>) {
|
||||
let p = port();
|
||||
|
||||
|
@ -126,7 +127,8 @@ mod map_reduce {
|
|||
let ref_count = 0;
|
||||
let is_done = false;
|
||||
|
||||
fn get<~V>(p: port<reduce_proto<V>>, &ref_count: int, &is_done: bool)
|
||||
fn get<unique V>(p: port<reduce_proto<V>>,
|
||||
&ref_count: int, &is_done: bool)
|
||||
-> option<V> {
|
||||
while !is_done || ref_count > 0 {
|
||||
alt recv(p) {
|
||||
|
@ -148,8 +150,8 @@ mod map_reduce {
|
|||
reduce(key, bind get(p, ref_count, is_done));
|
||||
}
|
||||
|
||||
fn map_reduce<~K1, ~K2,
|
||||
~V>(map: mapper<K1, K2, V>, reduce: reducer<K2, V>,
|
||||
fn map_reduce<unique K1, unique K2,
|
||||
unique V>(map: mapper<K1, K2, V>, reduce: reducer<K2, V>,
|
||||
inputs: [K1]) {
|
||||
let ctrl = port();
|
||||
|
||||
|
@ -192,7 +194,9 @@ mod map_reduce {
|
|||
}
|
||||
}
|
||||
|
||||
fn finish<~K, ~V>(_k: K, v: chan<reduce_proto<V>>) { send(v, done); }
|
||||
fn finish<unique K, unique V>(_k: K, v: chan<reduce_proto<V>>) {
|
||||
send(v, done);
|
||||
}
|
||||
treemap::traverse(reducers, finish);
|
||||
|
||||
for t in tasks { task::join(t); }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// error-pattern: needed unique type
|
||||
|
||||
fn f<~T>(i: T) {
|
||||
fn f<unique T>(i: T) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -4,7 +4,7 @@ resource r(i: @mutable int) {
|
|||
*i = *i + 1;
|
||||
}
|
||||
|
||||
fn f<@T>(i: [T], j: [T]) {
|
||||
fn f<T>(i: [T], j: [T]) {
|
||||
// Shouldn't be able to do this copy of j
|
||||
let k = i + j;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// error-pattern: Unsatisfied precondition constraint
|
||||
fn send<~T>(ch: _chan<T>, -data: T) { log ch; log data; fail; }
|
||||
fn send<unique T>(ch: _chan<T>, -data: T) { log ch; log data; fail; }
|
||||
type _chan<T> = int;
|
||||
|
||||
// Tests that "log message;" is flagged as using
|
||||
|
|
|
@ -4,8 +4,8 @@ fn test00_start(ch: chan_t<int>, message: int) { send(ch, message); }
|
|||
type task_id = int;
|
||||
type port_id = int;
|
||||
|
||||
type chan_t<~T> = {task: task_id, port: port_id};
|
||||
type chan_t<unique T> = {task: task_id, port: port_id};
|
||||
|
||||
fn send<~T>(ch: chan_t<T>, -data: T) { fail; }
|
||||
fn send<unique T>(ch: chan_t<T>, -data: T) { fail; }
|
||||
|
||||
fn main() { fail "quux"; }
|
||||
|
|
|
@ -5,7 +5,7 @@ import std::comm::port;
|
|||
import std::comm::send;
|
||||
import std::comm::recv;
|
||||
|
||||
fn echo<~T>(c: chan<T>, oc: chan<chan<T>>) {
|
||||
fn echo<unique T>(c: chan<T>, oc: chan<chan<T>>) {
|
||||
// Tests that the type argument in port gets
|
||||
// visited
|
||||
let p = port::<T>();
|
||||
|
|
|
@ -2,6 +2,6 @@ tag option<T> { some(T); none; }
|
|||
|
||||
type r<T> = {mutable v: [option<T>]};
|
||||
|
||||
fn f<@T>() -> [T] { ret []; }
|
||||
fn f<T>() -> [T] { ret []; }
|
||||
|
||||
fn main() { let r: r<int> = {mutable v: []}; r.v = f(); }
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
|
||||
// -*- rust -*-
|
||||
fn f<@T, @U>(x: T, y: U) -> {a: T, b: U} { ret {a: x, b: y}; }
|
||||
fn f<T, U>(x: T, y: U) -> {a: T, b: U} { ret {a: x, b: y}; }
|
||||
|
||||
fn main() { log f({x: 3, y: 4, z: 5}, 4).a.x; log f(5, 6).a; }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// because it would have to convert them to shared closures
|
||||
// xfail-test
|
||||
|
||||
fn f<@T>(x: [T]) -> T { ret x[0]; }
|
||||
fn f<T>(x: [T]) -> T { ret x[0]; }
|
||||
|
||||
fn g(act: fn([int]) -> int) -> int { ret act([1, 2, 3]); }
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
type box<T> = {c: @T};
|
||||
|
||||
fn unbox<@T>(b: box<T>) -> T { ret *b.c; }
|
||||
fn unbox<T>(b: box<T>) -> T { ret *b.c; }
|
||||
|
||||
fn main() {
|
||||
let foo: int = 17;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// -*- rust -*-
|
||||
type compare<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: T, eq: compare<T>) {
|
||||
let actual: T = alt true { true { expected } };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// -*- rust -*-
|
||||
type compare<T> = fn@(~T, ~T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: ~T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: ~T, eq: compare<T>) {
|
||||
let actual: ~T = alt true { true { expected } };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// -*- rust -*-
|
||||
type compare<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: T, eq: compare<T>) {
|
||||
let actual: T = alt true { true { expected } };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// -*- rust -*-
|
||||
type compare<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: T, eq: compare<T>) {
|
||||
let actual: T = alt true { true { expected } };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// -*- rust -*-
|
||||
type compare<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: T, eq: compare<T>) {
|
||||
let actual: T = { expected };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// -*- rust -*-
|
||||
type compare<T> = fn@(~T, ~T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: ~T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: ~T, eq: compare<T>) {
|
||||
let actual: ~T = { expected };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// -*- rust -*-
|
||||
type compare<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: T, eq: compare<T>) {
|
||||
let actual: T = { expected };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Tests for standalone blocks as expressions with dynamic type sizes
|
||||
type compare<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: T, eq: compare<T>) {
|
||||
let actual: T = { expected };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// -*- rust -*-
|
||||
type compare<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: T, not_expected: T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: T, not_expected: T, eq: compare<T>) {
|
||||
let actual: T = if true { expected } else { not_expected };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Tests for if as expressions with dynamic type sizes
|
||||
type compare<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_generic<@T>(expected: T, not_expected: T, eq: compare<T>) {
|
||||
fn test_generic<T>(expected: T, not_expected: T, eq: compare<T>) {
|
||||
let actual: T = if true { expected } else { not_expected };
|
||||
assert (eq(expected, actual));
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
fn fix_help<A, @B>(f: fn(fn@(A) -> B, A) -> B, x: A) -> B {
|
||||
fn fix_help<A, B>(f: fn(fn@(A) -> B, A) -> B, x: A) -> B {
|
||||
ret f(bind fix_help(f, _), x);
|
||||
}
|
||||
|
||||
fn fix<A, @B>(f: fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
|
||||
fn fix<A, B>(f: fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
|
||||
ret bind fix_help(f, _);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
fn fix_help<A, ~B>(f: fn(fn@(A) -> B, A) -> B, x: A) -> B {
|
||||
fn fix_help<A, unique B>(f: fn(fn@(A) -> B, A) -> B, x: A) -> B {
|
||||
ret f(bind fix_help(f, _), x);
|
||||
}
|
||||
|
||||
fn fix<A, ~B>(f: fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
|
||||
fn fix<A, unique B>(f: fn(fn@(A) -> B, A) -> B) -> fn@(A) -> B {
|
||||
ret bind fix_help(f, _);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This is what the signature to spawn should look like with bare functions
|
||||
|
||||
fn spawn<~T>(val: T, f: fn(T)) {
|
||||
fn spawn<unique T>(val: T, f: fn(T)) {
|
||||
f(val);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
obj ob<@K>(k: K) {
|
||||
obj ob<K>(k: K) {
|
||||
fn foo(it: block(~{a: K})) { it(~{a: k}); }
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
fn id<@T>(t: T) -> T { ret t; }
|
||||
fn id<T>(t: T) -> T { ret t; }
|
||||
|
||||
fn main() {
|
||||
let expected = @100;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
fn id<~T>(t: T) -> T { ret t; }
|
||||
fn id<unique T>(t: T) -> T { ret t; }
|
||||
|
||||
fn main() {
|
||||
let expected = ~100;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
fn id<@T>(t: T) -> T { ret t; }
|
||||
fn id<T>(t: T) -> T { ret t; }
|
||||
|
||||
fn main() {
|
||||
let t = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
fn id<@T>(t: T) -> T { ret t; }
|
||||
fn id<T>(t: T) -> T { ret t; }
|
||||
|
||||
fn main() {
|
||||
let t = {_0: 1, _1: 2, _2: 3, _3: 4, _4: 5, _5: 6, _6: 7};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
fn box<@T>(x: {x: T, y: T, z: T}) -> @{x: T, y: T, z: T} { ret @x; }
|
||||
fn box<T>(x: {x: T, y: T, z: T}) -> @{x: T, y: T, z: T} { ret @x; }
|
||||
|
||||
fn main() {
|
||||
let x: @{x: int, y: int, z: int} = box::<int>({x: 1, y: 2, z: 3});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
|
||||
fn g<@X>(x: X) -> X { ret x; }
|
||||
fn g<X>(x: X) -> X { ret x; }
|
||||
|
||||
fn f<@T>(t: T) -> {a: T, b: T} {
|
||||
fn f<T>(t: T) -> {a: T, b: T} {
|
||||
type pair = {a: T, b: T};
|
||||
|
||||
let x: pair = {a: t, b: t};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
|
||||
fn f<@T>(t: T) { let t1: T = t; }
|
||||
fn f<T>(t: T) { let t1: T = t; }
|
||||
|
||||
fn main() { let x = {x: @10, y: @12}; f(x); }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
type recbox<T> = {x: @T};
|
||||
|
||||
fn reclift<@T>(t: T) -> recbox<T> { ret {x: @t}; }
|
||||
fn reclift<T>(t: T) -> recbox<T> { ret {x: @t}; }
|
||||
|
||||
fn main() {
|
||||
let foo: int = 17;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
type recbox<T> = {x: ~T};
|
||||
|
||||
fn reclift<@T>(t: T) -> recbox<T> { ret {x: ~t}; }
|
||||
fn reclift<T>(t: T) -> recbox<T> { ret {x: ~t}; }
|
||||
|
||||
fn main() {
|
||||
let foo: int = 17;
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
// -*- rust -*-
|
||||
|
||||
// Issue #45: infer type parameters in function applications
|
||||
fn id<@T>(x: T) -> T { ret x; }
|
||||
fn id<T>(x: T) -> T { ret x; }
|
||||
|
||||
fn main() { let x: int = 42; let y: int = id(x); assert (x == y); }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
fn f<@T>(x: ~T) -> ~T { ret x; }
|
||||
fn f<T>(x: ~T) -> ~T { ret x; }
|
||||
|
||||
fn main() { let x = f(~3); log *x; }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
|
||||
// -*- rust -*-
|
||||
fn id<@T>(x: T) -> T { ret x; }
|
||||
fn id<T>(x: T) -> T { ret x; }
|
||||
|
||||
type triple = {x: int, y: int, z: int};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
obj handle<@T>(data: T) {
|
||||
obj handle<T>(data: T) {
|
||||
fn get() -> T { ret data; }
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
obj buf<@T>(data: {_0: T, _1: T, _2: T}) {
|
||||
obj buf<T>(data: {_0: T, _1: T, _2: T}) {
|
||||
fn get(i: int) -> T {
|
||||
if i == 0 {
|
||||
ret data._0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fn get_third<@T>(t: (T, T, T)) -> T { let (_, _, x) = t; ret x; }
|
||||
fn get_third<T>(t: (T, T, T)) -> T { let (_, _, x) = t; ret x; }
|
||||
|
||||
fn main() {
|
||||
log get_third((1, 2, 3));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
fn box<@T>(x: {x: T, y: T, z: T}) -> ~{x: T, y: T, z: T} { ret ~x; }
|
||||
fn box<T>(x: {x: T, y: T, z: T}) -> ~{x: T, y: T, z: T} { ret ~x; }
|
||||
|
||||
fn main() {
|
||||
let x: ~{x: int, y: int, z: int} = box::<int>({x: 1, y: 2, z: 3});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
fn quux<@T>(x: T) -> T { let f = bind id::<T>(_); ret f(x); }
|
||||
fn quux<T>(x: T) -> T { let f = bind id::<T>(_); ret f(x); }
|
||||
|
||||
fn id<@T>(x: T) -> T { ret x; }
|
||||
fn id<T>(x: T) -> T { ret x; }
|
||||
|
||||
fn main() { assert (quux(10) == 10); }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std;
|
||||
import std::option;
|
||||
|
||||
fn f<@T>(&o: option::t<T>) {
|
||||
fn f<T>(&o: option::t<T>) {
|
||||
assert o == option::none;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fn double<@T>(a: T) -> [T] { ret [a] + [a]; }
|
||||
fn double<T>(a: T) -> [T] { ret [a] + [a]; }
|
||||
|
||||
fn double_int(a: int) -> [int] { ret [a] + [a]; }
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ tag option<T> {
|
|||
|
||||
type smallintmap<T> = @{mutable v: [mutable option<T>]};
|
||||
|
||||
fn mk<@T>() -> smallintmap<T> {
|
||||
fn mk<T>() -> smallintmap<T> {
|
||||
let v: [mutable option<T>] = [mutable];
|
||||
ret @{mutable v: v};
|
||||
}
|
||||
|
||||
fn f<@T,@U>() {
|
||||
fn f<T,U>() {
|
||||
let sim = mk::<U>();
|
||||
log_err sim;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
tag myvec<X> = [X];
|
||||
|
||||
fn myvec_deref<@X>(mv: myvec<X>) -> [X] { ret *mv; }
|
||||
fn myvec_deref<X>(mv: myvec<X>) -> [X] { ret *mv; }
|
||||
|
||||
fn myvec_elt<@X>(mv: myvec<X>) -> X { ret mv[0]; }
|
||||
fn myvec_elt<X>(mv: myvec<X>) -> X { ret mv[0]; }
|
||||
|
||||
fn main() {
|
||||
let mv = myvec([1, 2, 3]);
|
||||
|
|
|
@ -2,19 +2,19 @@ use std;
|
|||
|
||||
import std::list::*;
|
||||
|
||||
pure fn pure_length_go<@T>(ls: list<T>, acc: uint) -> uint {
|
||||
pure fn pure_length_go<T>(ls: list<T>, acc: uint) -> uint {
|
||||
alt ls { nil. { acc } cons(_, tl) { pure_length_go(*tl, acc + 1u) } }
|
||||
}
|
||||
|
||||
pure fn pure_length<@T>(ls: list<T>) -> uint { pure_length_go(ls, 0u) }
|
||||
pure fn pure_length<T>(ls: list<T>) -> uint { pure_length_go(ls, 0u) }
|
||||
|
||||
pure fn nonempty_list<@T>(ls: list<T>) -> bool { pure_length(ls) > 0u }
|
||||
pure fn nonempty_list<T>(ls: list<T>) -> bool { pure_length(ls) > 0u }
|
||||
|
||||
// Of course, the compiler can't take advantage of the
|
||||
// knowledge that ls is a cons node. Future work.
|
||||
// Also, this is pretty contrived since nonempty_list
|
||||
// could be a "tag refinement", if we implement those.
|
||||
fn safe_head<@T>(ls: list<T>) : nonempty_list(ls) -> T { car(ls) }
|
||||
fn safe_head<T>(ls: list<T>) : nonempty_list(ls) -> T { car(ls) }
|
||||
|
||||
fn main() {
|
||||
let mylist = cons(@1u, @nil);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
tag option<T> { some(T); none; }
|
||||
|
||||
fn get<@T>(opt: option<T>) -> &T {
|
||||
fn get<T>(opt: option<T>) -> &T {
|
||||
alt opt {
|
||||
some(x) { ret x; }
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
tag option<T> { none; some(T); }
|
||||
|
||||
fn f<@T>() -> option<T> { ret none; }
|
||||
fn f<T>() -> option<T> { ret none; }
|
||||
|
||||
fn main() { f::<int>(); }
|
||||
|
|
|
@ -4,9 +4,9 @@ import std::comm::send;
|
|||
import std::comm::port;
|
||||
|
||||
// tests that ctrl's type gets inferred properly
|
||||
type command<~K, ~V> = {key: K, val: V};
|
||||
type command<unique K, unique V> = {key: K, val: V};
|
||||
|
||||
fn cache_server<~K, ~V>(c: chan<chan<command<K, V>>>) {
|
||||
fn cache_server<unique K, unique V>(c: chan<chan<command<K, V>>>) {
|
||||
let ctrl = port();
|
||||
send(c, chan(ctrl));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fn swap<@T>(v: [mutable T], i: int, j: int) { v[i] <-> v[j]; }
|
||||
fn swap<T>(v: [mutable T], i: int, j: int) { v[i] <-> v[j]; }
|
||||
|
||||
fn main() {
|
||||
let a: [mutable int] = [mutable 0, 1, 2, 3, 4, 5, 6];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn p_foo<T>(pinned: T) { }
|
||||
fn s_foo<@T>(shared: T) { }
|
||||
fn u_foo<~T>(unique: T) { }
|
||||
fn s_foo<T>(shared: T) { }
|
||||
fn u_foo<unique T>(unique: T) { }
|
||||
|
||||
resource r(i: int) { }
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ fn range(lo: uint, hi: uint, it: block(uint)) {
|
|||
while lo_ < hi { it(lo_); lo_ += 1u; }
|
||||
}
|
||||
|
||||
fn create_index<@T>(index: [{a: T, b: uint}], hash_fn: fn(T) -> uint) {
|
||||
fn create_index<T>(index: [{a: T, b: uint}], hash_fn: fn(T) -> uint) {
|
||||
range(0u, 256u) {|_i| let bucket: [T] = []; }
|
||||
}
|
||||
|
||||
|
|
|
@ -5,24 +5,24 @@ import std::list::*;
|
|||
|
||||
// Can't easily be written as a "pure fn" because there's
|
||||
// no syntax for specifying that f is pure.
|
||||
fn pure_foldl<@T, @U>(ls: list<T>, u: U, f: block(T, U) -> U) -> U {
|
||||
fn pure_foldl<T, U>(ls: list<T>, u: U, f: block(T, U) -> U) -> U {
|
||||
alt ls { nil. { u } cons(hd, tl) { f(hd, pure_foldl(*tl, f(hd, u), f)) } }
|
||||
}
|
||||
|
||||
// Shows how to use an "unchecked" block to call a general
|
||||
// fn from a pure fn
|
||||
pure fn pure_length<@T>(ls: list<T>) -> uint {
|
||||
pure fn pure_length<T>(ls: list<T>) -> uint {
|
||||
fn count<T>(_t: T, &&u: uint) -> uint { u + 1u }
|
||||
unchecked{ pure_foldl(ls, 0u, bind count(_, _)) }
|
||||
}
|
||||
|
||||
pure fn nonempty_list<@T>(ls: list<T>) -> bool { pure_length(ls) > 0u }
|
||||
pure fn nonempty_list<T>(ls: list<T>) -> bool { pure_length(ls) > 0u }
|
||||
|
||||
// Of course, the compiler can't take advantage of the
|
||||
// knowledge that ls is a cons node. Future work.
|
||||
// Also, this is pretty contrived since nonempty_list
|
||||
// could be a "tag refinement", if we implement those.
|
||||
fn safe_head<@T>(ls: list<T>) : nonempty_list(ls) -> T { car(ls) }
|
||||
fn safe_head<T>(ls: list<T>) : nonempty_list(ls) -> T { car(ls) }
|
||||
|
||||
fn main() {
|
||||
let mylist = cons(@1u, @nil);
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
use std;
|
||||
import std::unsafe;
|
||||
|
||||
fn null<@T>() -> *T unsafe { unsafe::reinterpret_cast(0) }
|
||||
fn null<T>() -> *T unsafe { unsafe::reinterpret_cast(0) }
|
||||
|
||||
fn main() { null::<int>(); }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fn f<@T>(t: T) -> T {
|
||||
fn f<T>(t: T) -> T {
|
||||
let t1 = t;
|
||||
t1
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Issue #976
|
||||
|
||||
fn f<@T>(x: ~T) {
|
||||
fn f<T>(x: ~T) {
|
||||
let _x2 = x;
|
||||
}
|
||||
fn main() { }
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
fn unique() {
|
||||
|
||||
fn f<~T>(i: T, j: T) {
|
||||
fn f<unique T>(i: T, j: T) {
|
||||
assert i == j;
|
||||
}
|
||||
|
||||
fn g<~T>(i: T, j: T) {
|
||||
fn g<unique T>(i: T, j: T) {
|
||||
assert i != j;
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,11 @@ fn unique() {
|
|||
|
||||
fn shared() {
|
||||
|
||||
fn f<@T>(i: T, j: T) {
|
||||
fn f<T>(i: T, j: T) {
|
||||
assert i == j;
|
||||
}
|
||||
|
||||
fn g<@T>(i: T, j: T) {
|
||||
fn g<T>(i: T, j: T) {
|
||||
assert i != j;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
|
||||
fn push<@T>(&v: [mutable? T], t: T) { v += [t]; }
|
||||
fn push<T>(&v: [mutable? T], t: T) { v += [t]; }
|
||||
|
||||
fn main() { let v = [1, 2, 3]; push(v, 1); }
|
||||
|
|
|
@ -81,7 +81,7 @@ fn test_boxes(a: @int, b: @int, c: @int, d: @int) {
|
|||
|
||||
type eqfn<T> = fn@(T, T) -> bool;
|
||||
|
||||
fn test_parameterized<@T>(e: eqfn<T>, a: T, b: T, c: T, d: T) {
|
||||
fn test_parameterized<T>(e: eqfn<T>, a: T, b: T, c: T, d: T) {
|
||||
let deq: deque::t<T> = deque::create::<T>();
|
||||
assert (deq.size() == 0u);
|
||||
deq.add_front(a);
|
||||
|
@ -113,7 +113,7 @@ fn test_parameterized<@T>(e: eqfn<T>, a: T, b: T, c: T, d: T) {
|
|||
|
||||
tag taggy { one(int); two(int, int); three(int, int, int); }
|
||||
|
||||
tag taggypar<@T> { onepar(int); twopar(int, int); threepar(int, int, int); }
|
||||
tag taggypar<T> { onepar(int); twopar(int, int); threepar(int, int, int); }
|
||||
|
||||
type reccy = {x: int, y: int, t: taggy};
|
||||
|
||||
|
@ -138,7 +138,7 @@ fn test() {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn taggypareq<@T>(a: taggypar<T>, b: taggypar<T>) -> bool {
|
||||
fn taggypareq<T>(a: taggypar<T>, b: taggypar<T>) -> bool {
|
||||
alt a {
|
||||
onepar::<T>(a1) {
|
||||
alt b { onepar::<T>(b1) { ret a1 == b1; } _ { ret false; } }
|
||||
|
|
|
@ -80,7 +80,7 @@ fn test_join_convenient() {
|
|||
#[ignore]
|
||||
fn spawn_polymorphic() {
|
||||
// FIXME #1038: Can't spawn palymorphic functions
|
||||
/*fn foo<~T>(x: T) { log_err x; }
|
||||
/*fn foo<unique T>(x: T) { log_err x; }
|
||||
|
||||
task::spawn(true, foo);
|
||||
task::spawn(42, foo);*/
|
||||
|
|
Loading…
Add table
Reference in a new issue