2015-01-07 03:03:14 -05:00
|
|
|
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:*;
|
2014-06-30 01:57:50 -07:00
|
|
|
|
2015-06-27 10:04:09 -04:00
|
|
|
fun vector<T>():vector<T> {
|
|
|
|
|
var out.construct():vector<T>
|
|
|
|
|
return out
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-09 20:02:02 -04:00
|
|
|
fun vector<T>(in:T):vector<T> {
|
|
|
|
|
var out.construct():vector<T>
|
|
|
|
|
out.add(in)
|
|
|
|
|
return out
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-24 20:40:18 -04:00
|
|
|
obj vector<T> (Object, Serializable) {
|
2015-07-04 17:02:51 -04:00
|
|
|
var data: *T;
|
2015-05-09 06:24:56 -04:00
|
|
|
var size: int;
|
|
|
|
|
var available: int;
|
2014-07-06 23:42:25 -07:00
|
|
|
|
2015-07-04 17:02:51 -04:00
|
|
|
fun construct(): *vector<T> {
|
2014-06-30 01:57:50 -07:00
|
|
|
size = 0;
|
|
|
|
|
available = 8;
|
|
|
|
|
data = new<T>(8);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2015-08-04 14:57:56 -04:00
|
|
|
fun construct(ammt: int): *vector<T> {
|
|
|
|
|
size = 0;
|
|
|
|
|
available = ammt;
|
|
|
|
|
data = new<T>(ammt);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2015-05-16 12:05:23 -04:00
|
|
|
|
2015-07-04 17:02:51 -04:00
|
|
|
fun copy_construct(old: *vector<T>): void {
|
2015-08-04 14:57:56 -04:00
|
|
|
construct(old->size)
|
|
|
|
|
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>)
|
|
|
|
|
}
|
2015-05-30 04:43:01 -04:00
|
|
|
}
|
2015-08-24 20:40:18 -04:00
|
|
|
fun serialize(): vector<char> {
|
|
|
|
|
var toRet = serialize(size)
|
|
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
toRet += serialize(data[i])
|
|
|
|
|
return toRet
|
|
|
|
|
}
|
2015-08-26 03:45:34 -04:00
|
|
|
fun unserialize(it: ref vector<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
|
|
|
|
|
}
|
2015-05-30 04:43:01 -04:00
|
|
|
|
2015-05-09 06:24:56 -04:00
|
|
|
fun destruct(): void {
|
2015-06-01 01:43:23 -04:00
|
|
|
if (data)
|
2015-06-05 00:34:24 -04:00
|
|
|
delete(data, size);
|
2015-06-14 18:13:52 -04:00
|
|
|
//data = 1337
|
2015-06-01 01:43:23 -04:00
|
|
|
data = 0
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-11 00:45:18 -07:00
|
|
|
fun set_size(s: int) {
|
|
|
|
|
size = s
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-05 04:51:10 -04:00
|
|
|
fun operator=(other:ref vector<T>):void {
|
|
|
|
|
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
|
|
|
}
|
2015-06-01 01:43:23 -04:00
|
|
|
}
|
|
|
|
|
|
2016-05-05 04:51:10 -04:00
|
|
|
fun operator+(other: ref vector<T>):vector<T> {
|
|
|
|
|
var newVec.construct(size+other.size):vector<T>
|
|
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
newVec.addEnd(get(i))
|
2015-06-01 01:43:23 -04:00
|
|
|
for (var i = 0; i < other.size; i++;)
|
2015-06-05 00:34:24 -04:00
|
|
|
newVec.addEnd(other.get(i))
|
2015-06-01 01:43:23 -04:00
|
|
|
return newVec
|
|
|
|
|
}
|
2016-05-05 04:51:10 -04:00
|
|
|
fun operator+(other: ref T):vector<T> {
|
2016-01-07 02:52:22 -05:00
|
|
|
var newVec.copy_construct(this):vector<T>
|
|
|
|
|
newVec.addEnd(other)
|
|
|
|
|
return newVec
|
|
|
|
|
}
|
2015-06-01 01:43:23 -04:00
|
|
|
|
2016-05-05 04:51:10 -04:00
|
|
|
fun operator+=(other: ref T):void {
|
2015-07-04 03:21:36 -04:00
|
|
|
addEnd(other)
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-05 04:51:10 -04:00
|
|
|
fun operator+=(other: ref vector<T>):void {
|
2015-06-01 01:43:23 -04:00
|
|
|
for (var i = 0; i < other.size; i++;)
|
|
|
|
|
addEnd(other.get(i))
|
2014-06-30 01:57:50 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-27 00:58:33 -04:00
|
|
|
fun clone(): vector<T> {
|
2015-08-06 17:38:41 -04:00
|
|
|
var newVec.construct(size): vector<T>
|
2015-05-27 00:58:33 -04:00
|
|
|
for (var i = 0; i < size; i++;)
|
2015-06-05 00:34:24 -04:00
|
|
|
newVec.addEnd(data[i])
|
2015-05-27 00:58:33 -04:00
|
|
|
return newVec
|
|
|
|
|
}
|
2015-08-06 17:38:41 -04:00
|
|
|
fun reverse(): vector<T> {
|
|
|
|
|
var newVec.construct(size): vector<T>
|
|
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
newVec.addEnd(data[(size-i)-1])
|
|
|
|
|
return newVec
|
|
|
|
|
}
|
2015-05-27 00:58:33 -04:00
|
|
|
|
2015-05-09 06:24:56 -04:00
|
|
|
fun resize(newSize: int): bool {
|
2015-07-04 17:02:51 -04:00
|
|
|
var newData: *T = new<T>(newSize);
|
2014-06-30 01:57:50 -07:00
|
|
|
if (!newData)
|
|
|
|
|
return false;
|
2015-08-06 17:38:41 -04:00
|
|
|
for (var i: int = 0; i < min<int>(size, newSize); i++;)
|
2015-06-05 00:34:24 -04:00
|
|
|
maybe_copy_construct(&newData[i], &data[i]);
|
|
|
|
|
delete(data, size);
|
2015-03-11 01:58:10 -04:00
|
|
|
data = newData;
|
|
|
|
|
available = newSize;
|
2015-08-06 17:38:41 -04:00
|
|
|
size = min(size, newSize)
|
2014-06-30 01:57:50 -07:00
|
|
|
return true;
|
|
|
|
|
}
|
2015-01-07 03:03:14 -05:00
|
|
|
|
2015-06-14 18:13:52 -04:00
|
|
|
fun slice(start: int, end: int): vector<T> {
|
|
|
|
|
if (start < 0)
|
|
|
|
|
start += size + 1
|
|
|
|
|
if (end < 0)
|
|
|
|
|
end += size + 1
|
2016-02-06 23:09:46 -05:00
|
|
|
var new.construct(end-start): vector<T>
|
2015-06-14 18:13:52 -04:00
|
|
|
for (var i = start; i < end; i++;)
|
|
|
|
|
new.add(data[i])
|
|
|
|
|
return new
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-15 00:53:53 -04:00
|
|
|
fun at(index: int): ref T { return get(index); }
|
|
|
|
|
fun operator[](index: int): ref T { return get(index); }
|
2015-08-06 17:38:41 -04:00
|
|
|
fun first(): ref T {
|
|
|
|
|
return get(0)
|
|
|
|
|
}
|
|
|
|
|
fun last(): ref T {
|
|
|
|
|
return get(size-1)
|
|
|
|
|
}
|
2015-07-15 00:53:53 -04:00
|
|
|
fun get(index: int): ref T {
|
2014-07-28 01:52:15 -07:00
|
|
|
if (index < 0 || index >= size) {
|
2015-03-16 14:01:15 -04:00
|
|
|
println("Vector access out of bounds! Retuning 0th element as sanest option");
|
|
|
|
|
print("Vector tried to access element: ");
|
|
|
|
|
println(index);
|
2015-05-16 00:03:36 -04:00
|
|
|
print("Max Index of vector: ");
|
2015-05-16 12:05:23 -04:00
|
|
|
println(size-1);
|
2016-05-13 18:34:06 -04:00
|
|
|
while(true) {}
|
2014-07-28 01:52:15 -07:00
|
|
|
return data[0];
|
|
|
|
|
}
|
2014-06-30 01:57:50 -07:00
|
|
|
return data[index];
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-04 17:02:51 -04:00
|
|
|
fun getBackingMemory(): *T { return data; }
|
2015-03-11 01:58:10 -04:00
|
|
|
|
2015-06-27 10:04:09 -04:00
|
|
|
// 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
|
|
|
|
|
// on an object that we want to put in a vector. 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.
|
2015-08-05 03:43:34 -04:00
|
|
|
fun find<U>(value: ref U): int {
|
2015-06-27 10:04:09 -04:00
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
if (data[i] == value)
|
|
|
|
|
return i;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2015-07-06 13:48:19 -04:00
|
|
|
// ditto
|
2015-08-05 03:43:34 -04:00
|
|
|
fun contains<U>(item: ref U): bool {
|
2015-07-06 13:48:19 -04:00
|
|
|
return find(item) != -1
|
|
|
|
|
}
|
2015-06-27 10:04:09 -04:00
|
|
|
|
2015-08-03 18:37:42 -04:00
|
|
|
// yep
|
2015-08-05 03:43:34 -04:00
|
|
|
fun operator==<U>(other: ref vector<U>):bool {
|
2015-08-03 18:37:42 -04:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-05 04:51:10 -04:00
|
|
|
fun set(index: int, dataIn: ref T): void {
|
2014-07-03 01:52:44 -07:00
|
|
|
if (index < 0 || index >= size)
|
2014-06-30 01:57:50 -07:00
|
|
|
return;
|
|
|
|
|
data[index] = dataIn;
|
|
|
|
|
}
|
2015-08-05 03:43:34 -04:00
|
|
|
fun add_all(dataIn: ref vector<T>): void {
|
2015-06-14 11:13:30 -04:00
|
|
|
for (var i = 0; i < dataIn.size; i++;)
|
|
|
|
|
addEnd(dataIn[i]);
|
|
|
|
|
}
|
2015-07-06 13:48:19 -04:00
|
|
|
// same darn trick
|
2016-05-05 04:51:10 -04:00
|
|
|
fun add_unique<U>(dataIn: ref U): void {
|
2015-07-06 13:48:19 -04:00
|
|
|
if (!contains(dataIn))
|
|
|
|
|
addEnd(dataIn)
|
|
|
|
|
}
|
2015-08-05 03:43:34 -04:00
|
|
|
fun add(dataIn: ref T): void { addEnd(dataIn); }
|
|
|
|
|
fun addEnd(dataIn: ref T): void {
|
2015-07-04 12:59:05 -04:00
|
|
|
if (size+1 >= available)
|
|
|
|
|
resize((size+1)*2);
|
|
|
|
|
maybe_copy_construct(&data[size], &dataIn);
|
2015-03-11 01:58:10 -04:00
|
|
|
size++;
|
2014-06-30 01:57:50 -07:00
|
|
|
}
|
2015-06-27 18:06:02 -04:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-05 03:43:34 -04:00
|
|
|
fun for_each(func: fun(ref T):void):void {
|
|
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
func(data[i])
|
|
|
|
|
}
|
2015-06-28 20:25:27 -04:00
|
|
|
fun for_each(func: fun(T):void):void {
|
2015-05-30 04:43:01 -04:00
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
func(data[i])
|
|
|
|
|
}
|
2016-02-29 19:18:22 -05:00
|
|
|
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])
|
|
|
|
|
}
|
2015-05-27 00:58:33 -04:00
|
|
|
fun in_place(func: fun(T):T):void {
|
|
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
data[i] = func(data[i])
|
|
|
|
|
}
|
2016-02-06 23:09:46 -05:00
|
|
|
fun map<U>(func: fun(ref T):U):vector<U> {
|
|
|
|
|
var newVec.construct(size): vector<U>
|
|
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
newVec.addEnd(func(data[i]))
|
|
|
|
|
return newVec
|
|
|
|
|
}
|
2015-05-27 00:58:33 -04:00
|
|
|
fun map<U>(func: fun(T):U):vector<U> {
|
2015-08-06 17:38:41 -04:00
|
|
|
var newVec.construct(size): vector<U>
|
2015-05-27 00:58:33 -04:00
|
|
|
for (var i = 0; i < size; i++;)
|
2015-06-05 00:34:24 -04:00
|
|
|
newVec.addEnd(func(data[i]))
|
2015-05-27 00:58:33 -04:00
|
|
|
return newVec
|
|
|
|
|
}
|
2015-06-08 21:47:02 -04:00
|
|
|
fun flatten_map<U>(func: fun(T):vector<U>):vector<U> {
|
2015-08-06 17:38:41 -04:00
|
|
|
var newVec.construct(size): vector<U>
|
2015-06-08 21:47:02 -04:00
|
|
|
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
|
|
|
|
|
}
|
2016-03-19 21:45:07 -04:00
|
|
|
fun find_first_satisfying(func: fun(T):bool): T return filter(func)[0]
|
2015-06-09 20:02:02 -04:00
|
|
|
fun filter(func: fun(T):bool):vector<T> {
|
|
|
|
|
var newVec.construct(): vector<T>
|
|
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
if (func(data[i]))
|
|
|
|
|
newVec.addEnd(data[i])
|
|
|
|
|
return newVec
|
|
|
|
|
}
|
2015-06-08 21:47:02 -04:00
|
|
|
fun any_true(func: fun(T):bool):bool {
|
|
|
|
|
for (var i = 0; i < size; i++;)
|
|
|
|
|
if (func(data[i]))
|
|
|
|
|
return true
|
|
|
|
|
return false
|
|
|
|
|
}
|
2016-02-06 23:09:46 -05:00
|
|
|
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]
|
|
|
|
|
}
|
2015-06-28 20:25:27 -04:00
|
|
|
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
|
|
|
|
|
}
|
2014-06-30 01:57:50 -07:00
|
|
|
};
|
2015-05-09 06:24:56 -04:00
|
|
|
|