import mem:*; import util:*; import io:*; fun vector(in:T):vector { var out.construct():vector out.add(in) return out } fun vector():vector { var out.construct():vector return out } obj vector (Object) { var data: T*; var size: int; var available: int; fun construct(): vector* { size = 0; available = 8; data = new(8); return this; } fun construct(newSize: int): vector*{ size = newSize; available = newSize; data = new(newSize); return this; } fun copy_construct(old: vector*): void { construct() for (var i = 0; i < old->size; i++;) addEnd(old->get(i)) } fun destruct(): void { if (data) delete(data, size); //data = 1337 data = 0 } fun operator=(other:vector):void { destruct() copy_construct(&other) } fun operator+(other:vector):vector { var newVec.construct():vector 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 } fun operator+=(other:vector):void { for (var i = 0; i < other.size; i++;) addEnd(other.get(i)) } fun clone(): vector { var newVec.construct(): vector for (var i = 0; i < size; i++;) newVec.addEnd(data[i]) return newVec } fun resize(newSize: int): bool { var newData: T* = new(newSize); if (!newData) return false; for (var i: int = 0; i < lesser(size, newSize); i++;) maybe_copy_construct(&newData[i], &data[i]); delete(data, size); data = newData; available = newSize; size = lesser(size, newSize) return true; } fun slice(start: int, end: int): vector { var new.construct(): vector if (start < 0) start += size + 1 if (end < 0) end += size + 1 for (var i = start; i < end; i++;) new.add(data[i]) return new } fun at(index: int): T { return get(index); } fun operator[](index: int): T { return get(index); } fun get(index: int): T { if (index < 0 || index >= size) { println("Vector access out of bounds! Retuning 0th element as sanest option"); print("Vector tried to access element: "); println(index); print("Max Index of vector: "); println(size-1); return data[0]; } return data[index]; } fun getBackingMemory(): T* { return data; } fun set(index: int, dataIn: T): void { if (index < 0 || index >= size) return; data[index] = dataIn; } fun add_all(dataIn: vector): void { for (var i = 0; i < dataIn.size; i++;) addEnd(dataIn[i]); } fun add(dataIn: T): void { addEnd(dataIn); } fun addEnd(dataIn: T): void { size++; if (size >= available) resize(size*2); maybe_copy_construct(&data[size-1], &dataIn); } fun do(func: fun(T):void):void { for (var i = 0; i < size; i++;) func(data[i]) } fun do(func: fun(T,U):void, extraParam: U):void { for (var i = 0; i < size; i++;) func(data[i], extraParam) } fun in_place(func: fun(T):T):void { for (var i = 0; i < size; i++;) data[i] = func(data[i]) } fun map(func: fun(T):U):vector { var newVec.construct(): vector for (var i = 0; i < size; i++;) newVec.addEnd(func(data[i])) return newVec } fun flatten_map(func: fun(T):vector):vector { var newVec.construct(): vector 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 } fun flatten_map(func: fun(T,V):vector, extraParam:V):vector { var newVec.construct(): vector for (var i = 0; i < size; i++;) { var to_add = func(data[i], extraParam) for (var j = 0; j < to_add.size; j++;) newVec.addEnd(to_add.get(j)) } return newVec } fun filter(func: fun(T):bool):vector { var newVec.construct(): vector for (var i = 0; i < size; i++;) if (func(data[i])) newVec.addEnd(data[i]) return newVec } fun filter(func: fun(T,U):bool, extraParam: U):vector { var newVec.construct(): vector for (var i = 0; i < size; i++;) if (func(data[i], extraParam)) 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 } };