Ctrl K
ComunidadGuías…

std/vec.zc

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot

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();
    }
}