import mem import io import os import str import set import map import vec import serialize // maybe my favorite function fun do_nothing() {} fun is_object(): bool return false fun is_object(): bool return true fun error(message: *char) error(str::str(message)); fun error(message: str::str) { io::printlnerr("****ERROR****") io::printlnerr(message) os::exit(-1) } fun assert(works: bool, message: *char) { if (!works) error(message) } fun assert(works: bool, message: str::str) { if (!works) error(message) } fun deref_equality(a: *T, b: *T): bool { if ( (a && b && !(*a == *b)) || (a && !b) || (!a && b) ) return false return true } fun max(a: T, b: T): T { if (a > b) return a; return b; } fun min(a: T, b: T): T { if (a > b) return b; return a; } fun hash(item: T): ulong return item.hash() fun hash(item: *T): ulong return (item) cast ulong fun hash(item: char): ulong return (item) cast ulong fun hash(item: uchar): ulong return (item) cast ulong fun hash(item: short): ulong return (item) cast ulong fun hash(item: ushort): ulong return (item) cast ulong fun hash(item: int): ulong return (item) cast ulong fun hash(item: uint): ulong return (item) cast ulong fun hash(item: long): ulong return (item) cast ulong fun hash(item: ulong): ulong return (item) cast ulong // default hash fun hash(item: T): ulong { io::println("using empty hash - please do not do!") return (0) cast ulong } fun make_pair(first: T, second: U): pair { var it.construct(first, second): pair return it } // little ugly, but it works fun unpack(first: ref T, second: ref U): unpack_dummy_pair { var toRet: unpack_dummy_pair toRet.first = &first toRet.second = &second return toRet } obj unpack_dummy_pair { var first: *T var second: *U fun operator=(p: ref pair) { *first = p.first *second = p.second } } obj pair (Object, Serializable, Hashable) { var first: T var second: U fun construct(firstIn: ref T, secondIn: ref U): *pair { mem::maybe_copy_construct(&first, &firstIn) mem::maybe_copy_construct(&second, &secondIn) return this } fun construct(): *pair { mem::maybe_construct(&first) mem::maybe_construct(&second) return this } fun copy_construct(old: *pair):void { mem::maybe_copy_construct(&first, &old->first) mem::maybe_copy_construct(&second, &old->second) } fun destruct():void { mem::maybe_destruct(&first) mem::maybe_destruct(&second) } fun serialize(): vec::vec { return serialize::serialize(first) + serialize::serialize(second) } fun unserialize(it: ref vec::vec, pos: int): int { // can't use unpack :( (b/c we can't make an already constructed empty one) var first_pair = serialize::unserialize(it, pos) var second_pair = serialize::unserialize(it, first_pair.second) mem::maybe_copy_construct(&first, &first_pair.first) mem::maybe_copy_construct(&second, &second_pair.first) return second_pair.second } fun hash():ulong return hash(first) ^ hash(second) // the old unnecessary template to prevent generation // if not used trick (in this case, changing out U with V) fun operator==(other: ref pair): bool { return first == other.first && second == other.second } } fun make_triple(first: T, second: U, third: V): triple { var it.construct(first, second, third): triple return it } // little ugly, but it works fun unpack(first: ref T, second: ref U, third: ref V): unpack_dummy_triple { var toRet: unpack_dummy_triple toRet.first = &first toRet.second = &second toRet.third = &third return toRet } obj unpack_dummy_triple { var first: *T var second: *U var third: *V fun operator=(p: ref triple) { *first = p.first *second = p.second *third = p.third } } obj triple (Object, Serializable, Hashable) { var first: T var second: U var third: V fun construct(firstIn: ref T, secondIn: ref U, thirdIn: ref V): *triple { mem::maybe_copy_construct(&first, &firstIn) mem::maybe_copy_construct(&second, &secondIn) mem::maybe_copy_construct(&third, &thirdIn) return this } fun construct(): *triple { mem::maybe_construct(&first) mem::maybe_construct(&second) mem::maybe_construct(&third) return this } fun copy_construct(old: *triple):void { mem::maybe_copy_construct(&first, &old->first) mem::maybe_copy_construct(&second, &old->second) mem::maybe_copy_construct(&third, &old->third) } fun destruct():void { mem::maybe_destruct(&first) mem::maybe_destruct(&second) mem::maybe_destruct(&third) } fun serialize(): vec::vec { return serialize::serialize(first) + serialize::serialize(second) + serialize::serialize(third) } fun unserialize(it: ref vec::vec, pos: int): int { // can't use unpack :( (b/c we can't make an already constructed empty one) var first_pair = serialize::unserialize(it, pos) var second_pair = serialize::unserialize(it, first_pair.second) var third_pair = serialize::unserialize(it, second_pair.second) mem::maybe_copy_construct(&first, &first_pair.first) mem::maybe_copy_construct(&second, &second_pair.first) mem::maybe_copy_construct(&third, &third_pair.first) return third_pair.second } fun hash():ulong return hash(first) ^ hash(second) ^ hash(third) // the old unnecessary template to prevent generation // if not used trick (in this case, changing out V with X) fun operator==(other: ref triple): bool { return first == other.first && second == other.second && third == other.third } } fun range(end:int): range { var toRet.construct(0, end, 1): range return toRet } fun range(begin: int, end:int): range { var toRet.construct(begin, end, 1): range return toRet } fun range(begin: int, end:int, step: int): range { var toRet.construct(begin, end, step): range return toRet } obj range { var begin: int var end: int var step: int fun construct(beginIn: int, endIn: int, stepIn: int) : *range { begin = beginIn end = endIn step = stepIn } fun for_each(func: fun(int):void):void { for (var i = begin; i < end; i+= step;) func(i) } fun map(func: fun(int): T): vec::vec { var ret.construct( (end-begin)/step + 1 ) : vec::vec for (var i = begin; i < end; i+= step;) ret.addEnd(func(i)) return ret } fun any_true(func: fun(int):bool):bool { for (var i = begin; i < end; i+= step;) if (func(i)) return true return false } } // a function that allows the safe deletion of recursive and complicated data structures fun safe_recursive_delete(first: *T, addingFunc: fun(*T): set::set<*T>) { var toDelete = set::set<*T>() var next = set::set(first) while (toDelete != next) { toDelete = next toDelete.for_each( fun(it: *T) next.add(addingFunc(it)); ) } toDelete.for_each( fun(it: *T) mem::delete(it); ) } // a function that allows the safe cloning of recursive and complicated data structures // cloneing func is the func that does the cloning, it takes in a recursive clone function and // a register clone function fun safe_recursive_clone(first: *T, cloningFunc: fun(*T, fun(*T):*T, fun(*T):void): void): *T { var rec_map = map::map<*T,*T>() // can't do type infrence if you need the type inside the expression... var rec_it: fun(*T):*T = fun(it: *T): *T { if (!rec_map.contains_key(it)) cloningFunc(it, rec_it, fun(cloned: *T) { rec_map[it] = cloned; }) return rec_map[it] } return rec_it(first) }