import mem import vector import serialize 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 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 { var toRet: unpack_dummy toRet.first = &first toRet.second = &second return toRet } obj unpack_dummy { var first: *T var second: *U fun operator=(p: ref pair) { *first = p.first *second = p.second } } obj pair (Object, Serializable) { var first: T var second: U fun construct(firstIn: T, secondIn: 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(): vector::vector { return serialize::serialize(first) + serialize::serialize(second) } fun unserialize(it: ref vector::vector, 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 } // 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 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): vector::vector { var ret.construct( (end-begin)/step + 1 ) : vector::vector 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 } }