Files
kraken/stdlib/vec.krak

404 lines
11 KiB
Plaintext
Raw Normal View History

import mem:*;
import util:*;
2015-03-16 14:01:15 -04:00
import io:*;
2015-08-24 20:40:18 -04:00
import serialize:*;
import util:*;
2018-10-08 00:28:42 -04:00
import map:*;
2018-05-22 19:43:54 -04:00
fun vec<T>():vec<T> {
var out.construct():vec<T>
return out
}
2018-05-22 19:43:54 -04:00
fun vec<T>(in:T):vec<T> {
var out.construct():vec<T>
out.add(in)
return out
}
2018-05-22 19:43:54 -04:00
obj vec<T> (Object, Serializable) {
var data: *T;
var size: int;
var available: int;
2018-05-22 19:43:54 -04:00
fun construct(): *vec<T> {
size = 0;
available = 8;
data = new<T>(8);
return this;
}
2018-05-22 19:43:54 -04:00
fun construct(ammt: int): *vec<T> {
size = 0;
available = ammt;
data = new<T>(ammt);
return this;
}
2015-05-16 12:05:23 -04:00
2018-05-22 19:43:54 -04:00
fun copy_construct(old: *vec<T>): void {
construct(old->available)
size = old->size
2016-06-11 00:45:18 -07:00
if (is_object<T>()) {
for (var i = 0; i < old->size; i++;)
maybe_copy_construct(&data[i], &old->data[i]);
} else {
memmove((data) cast *void, (old->data) cast *void, size * #sizeof<T>)
}
}
2018-05-22 19:43:54 -04:00
fun swap(other: ref vec<T>) {
var temp_data = data
var temp_size = size
var temp_available = available
data = other.data
size = other.size
available = other.available
other.data = temp_data
other.size = temp_size
other.available = temp_available
}
2018-05-22 19:43:54 -04:00
fun serialize(): vec<char> {
2015-08-24 20:40:18 -04:00
var toRet = serialize(size)
for (var i = 0; i < size; i++;)
toRet += serialize(data[i])
return toRet
}
2018-05-22 19:43:54 -04:00
fun unserialize(it: ref vec<char>, pos: int): int {
2015-08-24 20:40:18 -04:00
unpack(size, pos) = unserialize<int>(it, pos)
data = new<T>(size)
available = size
for (var i = 0; i < size; i++;) {
var curr = unserialize<T>(it, pos)
pos = curr.second
maybe_copy_construct(&data[i], &curr.first);
}
return pos
}
fun destruct(): void {
if (data)
delete(data, size);
//data = 1337
data = 0
}
2016-06-11 00:45:18 -07:00
fun set_size(s: int) {
size = s
}
2018-05-22 19:43:54 -04:00
fun operator=(other:ref vec<T>):void {
2016-05-05 04:51:10 -04:00
if (size < other.size) {
destruct()
copy_construct(&other)
} else {
clear()
2016-06-11 00:45:18 -07:00
if (is_object<T>()) {
for (var i = 0; i < other.size; i++;)
addEnd(other.get(i))
} else {
size = other.size
memmove((data) cast *void, (other.data) cast *void, size * #sizeof<T>)
}
2016-05-05 04:51:10 -04:00
}
}
2018-05-22 19:43:54 -04:00
fun operator+(other: ref vec<T>):vec<T> {
var newVec.construct(size+other.size):vec<T>
2016-05-05 04:51:10 -04:00
for (var i = 0; i < size; i++;)
newVec.addEnd(get(i))
for (var i = 0; i < other.size; i++;)
newVec.addEnd(other.get(i))
return newVec
}
2018-05-22 19:43:54 -04:00
fun operator+(other: ref T):vec<T> {
var newVec.copy_construct(this):vec<T>
newVec.addEnd(other)
return newVec
}
2016-05-05 04:51:10 -04:00
fun operator+=(other: ref T):void {
addEnd(other)
}
2018-05-22 19:43:54 -04:00
fun operator+=(other: ref vec<T>):void {
for (var i = 0; i < other.size; i++;)
addEnd(other.get(i))
}
2018-05-22 19:43:54 -04:00
fun clone(): vec<T> {
var newVec.construct(size): vec<T>
for (var i = 0; i < size; i++;)
newVec.addEnd(data[i])
return newVec
}
2018-05-22 19:43:54 -04:00
fun reverse(): vec<T> {
var newVec.construct(size): vec<T>
for (var i = 0; i < size; i++;)
newVec.addEnd(data[(size-i)-1])
return newVec
}
fun resize(newSize: int): bool {
var newData: *T = new<T>(newSize);
if (!newData)
return false;
for (var i: int = 0; i < min<int>(size, newSize); i++;)
maybe_copy_construct(&newData[i], &data[i]);
delete(data, size);
data = newData;
available = newSize;
size = min(size, newSize)
return true;
}
2018-05-22 19:43:54 -04:00
fun slice(start: int, end: int): vec<T> {
if (start < 0)
start += size + 1
if (end < 0)
end += size + 1
2018-05-22 19:43:54 -04:00
var new.construct(end-start): vec<T>
for (var i = start; i < end; i++;)
new.add(data[i])
return new
}
fun at(index: int): ref T { return get(index); }
fun operator[](index: int): ref T { return get(index); }
fun first(): ref T {
return get(0)
}
fun last(): ref T {
return get(size-1)
}
fun get(index: int): ref T {
if (index < 0 || index >= size) {
2015-03-16 14:01:15 -04:00
print("Vector tried to access element: ");
println(index);
2018-05-22 19:43:54 -04:00
print("Max Index of vec: ");
2015-05-16 12:05:23 -04:00
println(size-1);
2016-05-13 18:34:06 -04:00
while(true) {}
return data[0];
}
return data[index];
}
fun getBackingMemory(): *T { return data; }
// This is a template for the interesting reason that structs
// can not be compared for equality in C, and maybe we haven't defined equality
2018-05-22 19:43:54 -04:00
// on an object that we want to put in a vec. In this way we avoid the problem
// by not generating this function unless it's called - we also get the ability to
// do a find index using a different type, which could be fun.
fun find<U>(value: ref U): int {
for (var i = 0; i < size; i++;)
if (data[i] == value)
return i;
return -1;
}
// ditto
fun contains<U>(item: ref U): bool {
return find(item) != -1
}
// yep
2018-05-22 19:43:54 -04:00
fun operator==<U>(other: ref vec<U>):bool {
if (size != other.size)
return false
for (var i = 0; i < size; i++;)
if (!(data[i] == other.data[i])) // it's !(==) because we want equality if our members are equal, and overloading etc
return false
return true
}
fun operator< <U>(other: ref vec<U>):bool {
if (size < other.size)
return true
if (size > other.size)
return false
for (var i = 0; i < size; i++;)
if (data[i] < other.data[i]) // it's !(==) because we want equality if our members are equal, and overloading etc
return true
return false
}
2016-05-05 04:51:10 -04:00
fun set(index: int, dataIn: ref T): void {
if (index < 0 || index >= size)
return;
data[index] = dataIn;
}
2018-05-22 19:43:54 -04:00
fun add_all(dataIn: ref vec<T>): void {
for (var i = 0; i < dataIn.size; i++;)
addEnd(dataIn[i]);
}
fun add_all_unique<U>(dataIn: ref vec<U>): void {
for (var i = 0; i < dataIn.size; i++;)
add_unique(dataIn[i]);
}
// same darn trick
2016-05-05 04:51:10 -04:00
fun add_unique<U>(dataIn: ref U): void {
if (!contains(dataIn))
addEnd(dataIn)
}
fun add(dataIn: ref T): void { addEnd(dataIn); }
fun addEnd(dataIn: ref T): void {
// if we resize, we need to be careful as the dataIn reference
// may come from this itself
if (size+1 > available) {
var temp = dataIn
resize((size+1)*2);
maybe_copy_construct(&data[size], &temp);
} else {
maybe_copy_construct(&data[size], &dataIn);
}
size++;
}
fun add(index: int, dataIn: ref T) {
if (size == 0) {
add(dataIn)
return
}
add(last())
for (var i = size-2; i > index; i--;) {
data[i] = data[i-1]
}
data[index] = dataIn
}
fun remove(index: int) {
maybe_destruct(&data[index])
for (var i = index+1; i < size; i++;) {
maybe_copy_construct(&data[i-1], &data[i])
maybe_destruct(&data[i])
}
size--
}
2015-08-06 02:42:40 -04:00
fun clear() {
for (var i = 0; i < size; i++;)
maybe_destruct(&data[i])
size = 0
}
fun for_each(func: fun(ref T):void):void {
for (var i = 0; i < size; i++;)
func(data[i])
}
fun for_each(func: fun(T):void):void {
for (var i = 0; i < size; i++;)
func(data[i])
}
fun for_each_reverse(func: fun(ref T):void):void {
for (var i = size-1; i >= 0; i--;)
func(data[i])
}
fun for_each_reverse(func: fun(T):void):void {
for (var i = size-1; i >= 0; i--;)
func(data[i])
}
fun in_place(func: fun(T):T):void {
for (var i = 0; i < size; i++;)
data[i] = func(data[i])
}
2018-05-22 19:43:54 -04:00
fun map<U>(func: fun(ref T):U):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;)
newVec.addEnd(func(data[i]))
return newVec
}
fun map<U>(func: run(ref T):U):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;)
newVec.addEnd(func(data[i]))
return newVec
}
2018-05-22 19:43:54 -04:00
fun map<U>(func: fun(T):U):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;)
newVec.addEnd(func(data[i]))
return newVec
}
fun map<U>(func: run(T):U):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;)
newVec.addEnd(func(data[i]))
return newVec
}
2018-05-22 19:43:54 -04:00
fun flatten_map<U>(func: fun(T):vec<U>):vec<U> {
var newVec.construct(size): vec<U>
for (var i = 0; i < size; i++;) {
var to_add = func(data[i])
for (var j = 0; j < to_add.size; j++;)
newVec.addEnd(to_add.get(j))
}
return newVec
}
2018-10-08 00:28:42 -04:00
fun associate<K,V>(func: fun(T):pair<K,V>): map<K,V> {
var to_ret = map<K,V>()
for (var i = 0; i < size; i++;) {
var kv = func(data[i])
to_ret[kv.first] = kv.second
}
return to_ret
}
fun find_first_satisfying(func: fun(T):bool): T return filter(func)[0]
2018-05-22 19:43:54 -04:00
fun filter(func: fun(T):bool):vec<T> {
var newVec.construct(): vec<T>
for (var i = 0; i < size; i++;)
if (func(data[i]))
newVec.addEnd(data[i])
return newVec
}
fun any_true(func: fun(T):bool):bool {
for (var i = 0; i < size; i++;)
if (func(data[i]))
return true
return false
}
fun max(func: fun(ref T, ref T):bool): T {
var maxIdx = 0
for (var i = 1; i < size; i++;)
if (func(data[maxIdx], data[i]))
maxIdx = i
return data[maxIdx]
}
fun max(func: fun(T,T):bool): T {
var maxIdx = 0
for (var i = 1; i < size; i++;)
if (func(data[maxIdx], data[i]))
maxIdx = i
return data[maxIdx]
}
2015-12-28 03:34:40 -05:00
fun reduce<U>(func: fun(T,U): U, initial: U): U {
for (var i = 0; i < size; i++;)
initial = func(data[i], initial)
return initial
}
fun sorted<U>(less_than: run(ref U, ref U): bool): vec<T> {
if size < 2 {
return *this
} else {
var left = slice(0, size/2).sorted(less_than)
var right = slice(size/2, -1).sorted(less_than)
var to_ret.construct(size): vec<T>
var l = 0
var r = 0
while (l < left.size || r < right.size) {
if l == left.size {
to_ret.add(right[r++])
} else if r == right.size {
to_ret.add(left[l++])
} else if less_than(left[l], right[r]) {
to_ret.add(left[l++])
} else {
to_ret.add(right[r++])
}
}
return to_ret
}
}
fun pop(): T {
var to_ret = data[size-1]
remove(size-1)
return to_ret
}
};