▲ 48 r/Zig

Is there any good maintained project written in zig for study?

Hello, I am looking for a maintained project written in zig, which uses modern zig v0.16. if anyone knows please let me know in the comments. Mainly I have 2 motives for this:

  1. Learning purpose and for best practice

  2. I am a youtube content creator so if any good project so maybe I can make a video on it.(btw I am a very small youtuber so please don't expect from my channel for any kind of promotion)

Thx!

reddit.com
u/pbarot2009 — 5 days ago

Compiler or Transpliner?

Hi, I am working on an experiment programing language, I am wondering about the backed, what I choose either C backend means Transpliner or a LLVM(or custom Backed/linker) for it.

Which is recommended and good practice?

reddit.com
u/pbarot2009 — 1 month ago

I tried to make Vectors in C, any suggestions?

#ifndef VECTOR_H
#define VECTOR_H

#include <stdlib.h> 
#include <stdio.h>   
#include <string.h>

/**
 * Vector(T): declare a vector of element type T.
 *
 * Expands to an anonymous struct type: { T *data; size_t length; size_t capacity; }
 * Always zero-initialize: `Vector(int) v = {0};`
 *
 * Because the struct is anonymous, each `Vector(int) v;` declaration is its
 * own distinct type to the compiler, fine for locals, but you can't use
 * "Vector(int)" as a named function parameter type without typedef'ing it
 * yourself first (i.e. `typedef Vector(int) IntVec;`).
 */
#define Vector(T) struct { T *data; size_t length; size_t capacity; }

/**
 * vector_push(v, value); append value to the end of the vector.
 * Amortized O(1): capacity doubles (starting at 4) when full.
 * v must be a pointer to a Vector(T).
 */
#define vector_push(v, value)                                                \
    do {                                                                     \
        __typeof__(v) _v = (v);                                             \
        if (_v->length >= _v->capacity) {                                   \
            size_t _new_cap = _v->capacity == 0 ? 4 : _v->capacity * 2;     \
            __typeof__(_v->data) _new_data =                                \
                realloc(_v->data, _new_cap * sizeof(*_v->data));            \
            if (!_new_data) {                                               \
                fprintf(stderr, "vector_push: out of memory\n");            \
                abort();                                                    \
            }                                                                \
            _v->data = _new_data;                                          \
            _v->capacity = _new_cap;                                       \
        }                                                                    \
        _v->data[_v->length++] = (value);                                   \
    } while (0)

/**
 * vector_get(v, index); return the element at index, bounds-checked.
 * Aborts with a diagnostic on out-of-range access rather than reading
 * undefined memory.
 */
#define vector_get(v, index)                                                 \
    (*({                                                                     \
        __typeof__(v) _v = (v);                                             \
        size_t _i = (index);                                                \
        if (_i >= _v->length) {                                             \
            fprintf(stderr, "vector_get: index %zu out of bounds (length %zu)\n", \
                    _i, _v->length);                                        \
            abort();                                                        \
        }                                                                    \
        &_v->data[_i];                                                      \
    }))

/**
 * vector_set(v, index, value); overwrite the element at index, bounds-checked.
 */
#define vector_set(v, index, value)                                          \
    do {                                                                     \
        __typeof__(v) _v = (v);                                             \
        size_t _i = (index);                                                \
        if (_i >= _v->length) {                                             \
            fprintf(stderr, "vector_set: index %zu out of bounds (length %zu)\n", \
                    _i, _v->length);                                        \
            abort();                                                        \
        }                                                                    \
        _v->data[_i] = (value);                                             \
    } while (0)

/**
 * vector_pop(v) removes and returns the last element, Aborts if empty.
 */
#define vector_pop(v)                                                         \
    ({                                                                       \
        __typeof__(v) _v = (v);                                             \
        if (_v->length == 0) {                                              \
            fprintf(stderr, "vector_pop: pop on empty vector\n");           \
            abort();                                                        \
        }                                                                    \
        _v->data[--_v->length];                                             \
    })

/**
 * vector_insert(v, index, value)    inserts value at index, shifting later
 * elements right by one. index may equal length (same as push). O(n).
 */
#define vector_insert(v, index, value)                                       \
    do {                                                                     \
        __typeof__(v) _v = (v);                                             \
        size_t _i = (index);                                                \
        if (_i > _v->length) {                                              \
            fprintf(stderr, "vector_insert: index %zu out of bounds (length %zu)\n", \
                    _i, _v->length);                                        \
            abort();                                                        \
        }                                                                    \
        if (_v->length >= _v->capacity) {                                   \
            size_t _new_cap = _v->capacity == 0 ? 4 : _v->capacity * 2;     \
            __typeof__(_v->data) _new_data =                                \
                realloc(_v->data, _new_cap * sizeof(*_v->data));            \
            if (!_new_data) {                                               \
                fprintf(stderr, "vector_insert: out of memory\n");          \
                abort();                                                    \
            }                                                                \
            _v->data = _new_data;                                          \
            _v->capacity = _new_cap;                                       \
        }                                                                    \
        memmove(&_v->data[_i + 1], &_v->data[_i],                           \
                (_v->length - _i) * sizeof(*_v->data));                     \
        _v->data[_i] = (value);                                             \
        _v->length++;                                                      \
    } while (0)

/**
 * vector_remove(v, index); remove element at index, shifting later
 * elements left by one, returning the removed value. O(n).
 * If order doesn't matter, a swap-remove (copy last element over the
 * removed slot) is O(1); a good exercise to add yourself.
 */
#define vector_remove(v, index)                                              \
    ({                                                                       \
        __typeof__(v) _v = (v);                                             \
        size_t _i = (index);                                                \
        if (_i >= _v->length) {                                             \
            fprintf(stderr, "vector_remove: index %zu out of bounds (length %zu)\n", \
                    _i, _v->length);                                        \
            abort();                                                        \
        }                                                                    \
        __typeof__(_v->data[0]) _removed = _v->data[_i];                    \
        memmove(&_v->data[_i], &_v->data[_i + 1],                           \
                (_v->length - _i - 1) * sizeof(*_v->data));                 \
        _v->length--;                                                      \
        _removed;                                                          \
    })

/**
 * vector_clear(v) resets length to 0, keep capacity (buffer not freed).
 * Use when reusing a vector's storage across loop iterations.
 */
#define vector_clear(v)                                                      \
    do { (v)->length = 0; } while (0)

/**
 * vector_reserve(v, min_capacity) ensures capacity >= min_capacity in
 * a single grow. Use before a known batch of pushes to avoid repeated
 * reallocation.
 */
#define vector_reserve(v, min_capacity)                                      \
    do {                                                                     \
        __typeof__(v) _v = (v);                                             \
        size_t _min = (min_capacity);                                       \
        if (_v->capacity < _min) {                                          \
            __typeof__(_v->data) _new_data =                                \
                realloc(_v->data, _min * sizeof(*_v->data));                \
            if (!_new_data) {                                               \
                fprintf(stderr, "vector_reserve: out of memory\n");         \
                abort();                                                    \
            }                                                                \
            _v->data = _new_data;                                          \
            _v->capacity = _min;                                           \
        }                                                                    \
    } while (0)

/**
 * vector_free(v); release the backing buffer, reset to zero state.
 * Safe to push into again afterward (it'll reallocate from scratch).
 */
#define vector_free(v)                                                       \
    do {                                                                     \
        free((v)->data);                                                    \
        (v)->data = NULL;                                                   \
        (v)->length = 0;                                                    \
        (v)->capacity = 0;                                                  \
    } while (0)

#endif // VECTOR_H

Example:

#include "vector.h"
#include <stdio.h>

int main_old(void) {
    printf("=== vector_push / vector_get ===\n");
    Vector(int) v = {0};
    for (int i = 0; i < 10; i++) {
        vector_push(&v, i * i);
    }
    printf("length=%zu capacity=%zu\n", v.length, v.capacity);
    for (size_t i = 0; i < v.length; i++) {
        printf("%d ", vector_get(&v, i));
    }
    printf("\n");
    printf("\n=== vector_set ===\n");
    vector_set(&v, 0, 999);
    printf("index 0 after set = %d\n", vector_get(&v, 0));
    printf("\n=== vector_pop ===\n");
    int popped = vector_pop(&v);
    printf("popped=%d, new length=%zu\n", popped, v.length);
    printf("\n=== vector_insert ===\n");
    vector_insert(&v, 0, -1);
    printf("index 0 after insert = %d, length=%zu\n", vector_get(&v, 0), v.length);
    printf("\n=== vector_remove ===\n");
    int removed = vector_remove(&v, 0);
    printf("removed=%d, new index 0 = %d, length=%zu\n", removed, vector_get(&v, 0), v.length);

    printf("\n=== vector_reserve ===\n");
    vector_reserve(&v, 100);
    printf("capacity after reserve(100) = %zu\n", v.capacity);

    printf("\n=== vector_clear ===\n");
    vector_clear(&v);
    printf("length=%zu, capacity kept=%zu\n", v.length, v.capacity);

    printf("\n=== vector_free ===\n");
    vector_free(&v);
    printf("data=%p length=%zu capacity=%zu\n", (void *)v.data, v.length, v.capacity);

    printf("\n=== Vector(double) same macros but different type ===\n");
    Vector(double) dv = {0};
    vector_push(&dv, 3.14);
    vector_push(&dv, 2.71);
    printf("%f %f\n", vector_get(&dv, 0), vector_get(&dv, 1));
    vector_free(&dv);

    printf("\n=== Vector(struct) works on aggregate types too ===\n");
    typedef struct { int x, y; } Point;
    Vector(Point) pv = {0};
    vector_push(&pv, ((Point){1, 2}));
    vector_push(&pv, ((Point){3, 4}));
    Point p = vector_get(&pv, 1);
    printf("pv[1] = (%d, %d)\n", p.x, p.y);
    vector_free(&pv);

    return 0;
}

Note: I used C23 features here, show me something that I missed or something.

Also if you have suggestions for better performance please tell me.

reddit.com
u/pbarot2009 — 1 month ago