Files
kraken/stdlib/util.krak
2015-08-29 21:45:55 -04:00

124 lines
3.1 KiB
Plaintext

import mem
import vector
import serialize
fun max<T>(a: T, b: T): T {
if (a > b)
return a;
return b;
}
fun min<T>(a: T, b: T): T {
if (a > b)
return b;
return a;
}
fun make_pair<T,U>(first: T, second: U): pair<T,U> {
var it.construct(first, second): pair<T,U>
return it
}
// little ugly, but it works
fun unpack<T,U>(first: ref T, second: ref U): unpack_dummy<T,U> {
var toRet: unpack_dummy<T,U>
toRet.first = &first
toRet.second = &second
return toRet
}
obj unpack_dummy<T,U> {
var first: *T
var second: *U
fun operator=(p: ref pair<T,U>) {
*first = p.first
*second = p.second
}
}
obj pair<T,U> (Object, Serializable) {
var first: T
var second: U
fun construct(firstIn: ref T, secondIn: ref U): *pair<T,U> {
mem::maybe_copy_construct(&first, &firstIn)
mem::maybe_copy_construct(&second, &secondIn)
return this
}
fun construct(): *pair<T,U> {
mem::maybe_construct(&first)
mem::maybe_construct(&second)
return this
}
fun copy_construct(old: *pair<T,U>):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<char> {
return serialize::serialize(first) + serialize::serialize(second)
}
fun unserialize(it: ref vector::vector<char>, pos: int): int {
// can't use unpack :( (b/c we can't make an already constructed empty one)
var first_pair = serialize::unserialize<T>(it, pos)
var second_pair = serialize::unserialize<U>(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==<V>(other: ref pair<T,V>): 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<T>(func: fun(int): T): vector::vector<T> {
var ret.construct( (end-begin)/step + 1 ) : vector::vector<T>
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
}
}