std/vec.zc
Rama main · réplica de lectura del repositorio original.
import "./core.zc"
import "./mem.zc"
import "./iter.zc"
import "./sort.zc"
struct Vec<T> {
data: T*;
len: usize;
cap: usize;
}
struct VecIter<T> {
data: T*;
count: usize;
idx: usize;
}
struct VecIterResult<T> {
ptr: T*;
}
impl VecIterResult<T> {
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<T> {
data: T*;
count: usize;
idx: usize;
}
impl VecIter<T> {
/// Yields the next item, or `None` when exhausted.
fn next(self) -> Option<T> {
if (self.idx < self.count) {
let item = self.data[self.idx];
self.idx = self.idx + 1;
return Option<T>::Some(item);
}
return Option<T>::None();
}
/// Returns an iterator yielding copies.
fn iterator(self) -> VecIter<T> {
return self;
}
// Drains the remaining items into a new Vec.
/// Drains the remaining items into a new Vec.
fn collect(self) -> Vec<T> {
let out = Vec<T>::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<T> {
while (self.idx < self.count) {
let item = self.data[self.idx];
self.idx = self.idx + 1;
if (pred(item)) {
return Option<T>::Some(item);
}
}
return Option<T>::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<T> {
let out = Vec<T>::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<T> {
/// Yields the next item, or `None` when exhausted.
fn next(self) -> VecIterResult<T> {
if (self.idx < self.count) {
let item = &self.data[self.idx];
self.idx = self.idx + 1;
return VecIterResult<T> { ptr: item };
}
return VecIterResult<T> { ptr: NULL };
}
/// Returns an iterator yielding copies.
fn iterator(self) -> VecIterRef<T> {
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<T> {
while (self.idx < self.count) {
let item = &self.data[self.idx];
self.idx = self.idx + 1;
if (pred(item)) {
return VecIterResult<T> { ptr: item };
}
}
return VecIterResult<T> { ptr: NULL };
}
}
impl Vec<T> {
/// Creates a new, empty Vec (no allocation until first push).
fn new() -> Vec<T> {
return Vec<T> { data: NULL, len: 0, cap: 0 };
}
/// Creates a new Vec with an initial capacity.
fn with_capacity(cap: usize) -> Vec<T> {
if (cap == 0) {
return Vec<T> { data: NULL, len: 0, cap: 0 };
}
return Vec<T> {
data: alloc_n<T>(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<T>(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<T>(self.data, old_cap, self.cap);
}
/// Returns an iterator yielding copies.
fn iterator(self) -> VecIter<T> {
return VecIter<T> {
data: self.data,
count: self.len,
idx: 0
};
}
/// Returns an iterator yielding item pointers.
fn iter_ref(self) -> VecIterRef<T> {
return VecIterRef<T> {
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<T> {
if (self.len == 0) {
return Option<T>::None();
}
self.len = self.len - 1;
return Option<T>::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<T>) {
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<T>(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<T>*) -> 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<T>*) -> Vec<T> {
let result = self.clone();
result.append(other.clone());
return result;
}
// Operator overload for `+=` (In-place concatenation)
fn add_assign(self, other: Vec<T>*) {
self.append(other.clone());
}
// Operator overload for `!=` (Inequality)
fn neq(self, other: Vec<T>*) -> 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<T> {
let result = Vec<T>::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<T> {
if (self.len == 0) {
return Vec<T> { data: NULL, len: 0, cap: 0 };
}
let new_data = alloc_n<T>(self.len);
let i: usize = 0;
while i < self.len {
new_data[i] = self.data[i];
i = i + 1;
}
return Vec<T> {
data: new_data,
len: self.len,
cap: self.len
};
}
}
impl Drop for Vec {
fn drop(self) {
self.free();
}
}