import "./core.zc" import "./mem.zc" import "./iter.zc" import "./sort.zc" struct Vec { data: T*; len: usize; cap: usize; } struct VecIter { data: T*; count: usize; idx: usize; } struct VecIterResult { ptr: T*; } impl VecIterResult { fn is_none(self) -> bool { return self.ptr == NULL; } fn unwrap(self) -> T* { if (self.ptr == NULL) { !"Panic: unwrap called on null VecIterResult"; exit(1); } return self.ptr; } } struct VecIterRef { data: T*; count: usize; idx: usize; } impl VecIter { /// Yields the next item, or `None` when exhausted. fn next(self) -> Option { if (self.idx < self.count) { let item = self.data[self.idx]; self.idx = self.idx + 1; return Option::Some(item); } return Option::None(); } /// Returns an iterator yielding copies. fn iterator(self) -> VecIter { return self; } // Drains the remaining items into a new Vec. /// Drains the remaining items into a new Vec. fn collect(self) -> Vec { let out = Vec::new(); let remaining = self.count - self.idx; if (remaining > 0) { out.grow_to_fit(remaining); } while (self.idx < self.count) { out.push(self.data[self.idx]); self.idx = self.idx + 1; } return out; } // Number of items still to be yielded. /// Number of items still to be yielded. fn count(self) -> usize { return self.count - self.idx; } // Calls `f` for each remaining item. /// Calls `f` for each remaining item. fn forEach(self, f: fn(T)) { while (self.idx < self.count) { f(self.data[self.idx]); self.idx = self.idx + 1; } } // Returns the first item for which `pred` returns true. /// Returns the first item accepted by `pred`. fn find(self, pred: fn(T) -> bool) -> Option { while (self.idx < self.count) { let item = self.data[self.idx]; self.idx = self.idx + 1; if (pred(item)) { return Option::Some(item); } } return Option::None(); } // Returns true when `pred` accepts at least one remaining item. /// Returns whether `pred` accepts at least one remaining item. fn any(self, pred: fn(T) -> bool) -> bool { while (self.idx < self.count) { let item = self.data[self.idx]; self.idx = self.idx + 1; if (pred(item)) { return true; } } return false; } // Returns true when `pred` accepts every remaining item. /// Returns whether `pred` accepts every remaining item. fn all(self, pred: fn(T) -> bool) -> bool { while (self.idx < self.count) { let item = self.data[self.idx]; self.idx = self.idx + 1; if (!pred(item)) { return false; } } return true; } // Collects the remaining items accepted by `pred` into a new Vec. /// Collects the remaining items accepted by `pred`. fn filter(self, pred: fn(T) -> bool) -> Vec { let out = Vec::new(); while (self.idx < self.count) { let item = self.data[self.idx]; self.idx = self.idx + 1; if (pred(item)) { out.push(item); } } return out; } // Reduces the remaining items with `f` starting from `init`. /// Reduces the remaining items with `f` from `init`. fn fold(self, init: T, f: fn(T, T) -> T) -> T { let acc = init; while (self.idx < self.count) { let item = self.data[self.idx]; self.idx = self.idx + 1; acc = f(acc, item); } return acc; } } impl VecIterRef { /// Yields the next item, or `None` when exhausted. fn next(self) -> VecIterResult { if (self.idx < self.count) { let item = &self.data[self.idx]; self.idx = self.idx + 1; return VecIterResult { ptr: item }; } return VecIterResult { ptr: NULL }; } /// Returns an iterator yielding copies. fn iterator(self) -> VecIterRef { return self; } // Number of items still to be yielded. /// Number of items still to be yielded. fn count(self) -> usize { return self.count - self.idx; } // Returns the first item for which `pred` returns true. /// Returns the first item accepted by `pred`. fn find(self, pred: fn(T*) -> bool) -> VecIterResult { while (self.idx < self.count) { let item = &self.data[self.idx]; self.idx = self.idx + 1; if (pred(item)) { return VecIterResult { ptr: item }; } } return VecIterResult { ptr: NULL }; } } impl Vec { /// Creates a new, empty Vec (no allocation until first push). fn new() -> Vec { return Vec { data: NULL, len: 0, cap: 0 }; } /// Creates a new Vec with an initial capacity. fn with_capacity(cap: usize) -> Vec { if (cap == 0) { return Vec { data: NULL, len: 0, cap: 0 }; } return Vec { data: alloc_n(cap), len: 0, cap: cap }; } fn grow(self) { let old_cap = self.cap; if (self.cap == 0) { self.cap = 8; } else { self.cap = self.cap * 2; } self.data = realloc_n(self.data, old_cap, self.cap); } /// Ensures capacity for at least `new_len` items. fn grow_to_fit(self, new_len: usize) { if self.cap >= new_len { return; } let old_cap = self.cap; if (self.cap == 0) { self.cap = 8; } while self.cap < new_len { self.cap = self.cap * 2; } self.data = realloc_n(self.data, old_cap, self.cap); } /// Returns an iterator yielding copies. fn iterator(self) -> VecIter { return VecIter { data: self.data, count: self.len, idx: 0 }; } /// Returns an iterator yielding item pointers. fn iter_ref(self) -> VecIterRef { return VecIterRef { data: self.data, count: self.len, idx: 0 }; } /// Appends an item. fn push(self, item: T) { if (self.len >= self.cap) { self.grow(); } self.data[self.len] = item; self.len = self.len + 1; } /// Inserts an item at `idx`. fn insert(self, idx: usize, item: T) { if (idx > self.len) { !"Panic: Insert index out of bounds"; exit(1); } if (self.len >= self.cap) { self.grow(); } // Shift elements right if (idx < self.len) { memmove(self.data + idx + 1, self.data + idx, (self.len - idx) * sizeof(T)); } self.data[idx] = item; self.len = self.len + 1; } /// Removes and returns the last item (0 if empty). fn pop(self) -> T { if (self.len == 0) { !"Panic: pop called on empty Vec"; exit(1); } self.len = self.len - 1; return self.data[self.len]; } /// Removes and returns the last item, or `None` when empty. fn pop_opt(self) -> Option { if (self.len == 0) { return Option::None(); } self.len = self.len - 1; return Option::Some(self.data[self.len]); } /// Removes and returns the item at `idx`. fn remove(self, idx: usize) -> T { if (idx >= self.len) { !"Panic: Remove index out of bounds"; exit(1); } let item = self.data[idx]; // Shift elements left if (idx < self.len - 1) { memmove(self.data + idx, self.data + idx + 1, (self.len - idx - 1) * sizeof(T)); } self.len = self.len - 1; return item; } // Appends all elements from another vector. // Consumes the other vector (move semantics). fn append(self, other: Vec) { let new_len = self.len + other.len; self.grow_to_fit(new_len); memcpy(self.data + self.len, other.data, other.len * sizeof(T)); self.len = new_len; other.forget(); } /// Returns a copy of the item at `idx`. fn get(self, idx: usize) -> T { if (idx >= self.len) { !"Panic: Index out of bounds"; exit(1); } return self.data[idx]; } fn index(self, idx: usize) -> T { return self.get(idx); } /// Returns a pointer to the item at `idx`. fn get_ref(self, idx: usize) -> T* { if (idx >= self.len) { !"Panic: Index out of bounds"; exit(1); } return &self.data[idx]; } fn last(self) -> T { if (self.len == 0) { !"Panic: last called on empty Vec"; exit(1); } return self.data[self.len - 1]; } /// Returns the number of items. fn length(self) -> usize { return self.len; } /// Returns whether an equal item exists. fn contains(self, item: T) -> bool { let i: usize = 0; while i < self.len { if memcmp(&self.data[i], &item, sizeof(T)) == 0 { return true; } i++; } return false; } /// Returns whether the Vec is empty. fn is_empty(self) -> bool { return self.len == 0; } /// Removes all items (keeps capacity). fn clear(self) { self.len = 0; } /// Frees the backing buffer. fn free(self) { if (self.data != NULL) { dealloc(self.data); } self.data = NULL; self.len = 0; self.cap = 0; } fn first(self) -> T { if (self.len == 0) { !"Panic: first called on empty Vec"; exit(1); } return self.data[0]; } /// Writes an item at `idx`. fn set(self, idx: usize, item: T) { if (idx >= self.len) { !"Panic: set index out of bounds"; exit(1); } self.data[idx] = item; } /// Reverses the Vec in place. fn reverse(self) { let i: usize = 0; let j = self.len - 1; while i < j { let tmp = self.data[i]; self.data[i] = self.data[j]; self.data[j] = tmp; i++; j--; } } // Structural equality check. // Returns true if both vectors have the same length and identical elements. fn eq(self, other: Vec*) -> bool { if self.len != (*other).len { return false; } let i: usize = 0; while i < self.len { if memcmp(&self.data[i], &(*other).data[i], sizeof(T)) != 0 { return false; } i = i + 1; } return true; } // Prevent Drop from freeing memory (simulates move) /// Detaches the backing buffer without freeing it. fn forget(self) { self.data = NULL; self.len = 0; self.cap = 0; } // Operator overload for `+` (Concatenation) // Returns a new vector containing elements from both v1 and v2. // Usage: let v3 = v1 + &v2; fn add(self, other: Vec*) -> Vec { let result = self.clone(); result.append(other.clone()); return result; } // Operator overload for `+=` (In-place concatenation) fn add_assign(self, other: Vec*) { self.append(other.clone()); } // Operator overload for `!=` (Inequality) fn neq(self, other: Vec*) -> bool { return !self.eq(other); } // Operator overload for `<<` (Push item into vector) fn shl(self, item: T) { self.push(item); } // Operator overload for `>>` (Pop item from vector into pointer) fn shr(self, out_item: T*) { if (out_item != NULL) { *out_item = self.pop(); } else { self.pop(); } } // Operator overload for `*` (Repeat vector N times) // Returns a new vector with elements repeated `count` times. // Usage: let v2 = v * 3; fn mul(self, count: usize) -> Vec { let result = Vec::with_capacity(self.len * count); let c: usize = 0; while c < count { result.append(self.clone()); c += 1; } return result; } // Operator overload for `*=` (In-place repeat) // Repeats the current elements in-place `count` times. // Usage: v *= 3; fn mul_assign(self, count: usize) { if (count == 0) { self.clear(); return; } if (count == 1) { return; } let original_len = self.len; self.grow_to_fit(self.len * count); let c: usize = 1; while c < count { memcpy(self.data + (original_len * c), self.data, original_len * sizeof(T)); self.len += original_len; c += 1; } } /// Returns a deep copy. fn clone(self) -> Vec { if (self.len == 0) { return Vec { data: NULL, len: 0, cap: 0 }; } let new_data = alloc_n(self.len); let i: usize = 0; while i < self.len { new_data[i] = self.data[i]; i = i + 1; } return Vec { data: new_data, len: self.len, cap: self.len }; } } impl Drop for Vec { fn drop(self) { self.free(); } }