From 2016dceaa9cfc65ee80ee7e433331390f4263744 Mon Sep 17 00:00:00 2001 From: bigfoot547 Date: Mon, 12 Jan 2026 16:30:37 -0600 Subject: download jobs --- lib/vector.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 lib/vector.c (limited to 'lib/vector.c') diff --git a/lib/vector.c b/lib/vector.c new file mode 100644 index 0000000..eb7233c --- /dev/null +++ b/lib/vector.c @@ -0,0 +1,122 @@ +#include "vector.h" +#include +#include +#include + +struct vl__vector_tag { + size_t cap, sz, len; + void *data; /* cap * len */ +}; + +vl_vector *vl_vector_new(size_t sz) +{ + return vl_vector_new_ex(sz, 16); +} + +vl_vector *vl_vector_new_ex(size_t sz, size_t init_cap) +{ + vl_vector *vec = calloc(1, sizeof(vl_vector)); + if (!vec) return NULL; + + if (init_cap < 16) init_cap = 16; + + vec->cap = init_cap; + vec->len = 0; + vec->sz = sz; + + void *data = calloc(init_cap, sz); + if (!data) { + free(vec); + return NULL; + } + + vec->data = data; + + return vec; +} + +void vl_vector_free(vl_vector *vec) +{ + if (!vec) return; + + free(vec->data); + free(vec); +} + +static int vec_grow(vl_vector *vec, size_t newlen) +{ + void *temp = reallocarray(vec->data, newlen, vec->sz); + if (!temp) return -1; + vec->data = temp; + + return 0; +} + +static size_t next_po2(size_t sz) +{ + assert(sz > 0); + return (size_t)(1 << (64 - __builtin_clzll((unsigned long long)sz))); +} + +static int ensure_fits(vl_vector *vec, size_t toadd) +{ + if (vec->len + toadd <= vec->cap) { + return 0; + } + + size_t newcap = next_po2(vec->len + toadd); + return vec_grow(vec, newcap); +} + +/* will abort if realloc fails to shrink the allocation (should never happen) */ +void vl_vector_shrink_to_size(vl_vector *vec) +{ + if (vec_grow(vec, vec->len) < 0) abort(); +} + +#define vl_newvec(_t) vl_vector_new(sizeof(_t)) +#define vl_newvec_ex(_t, _ic) vl_vector_new_ex(sizeof(_t), _ic) + +int vl_vector_push(vl_vector *vec, void *data) +{ + return vl_vector_push_vec(vec, data, 1); +} + +int vl_vector_push_vec(vl_vector *vec, void *data, size_t n) +{ + if (ensure_fits(vec, n) < 0) { + return -1; + } + + unsigned char *d = vec->data; + memcpy(d + (vec->len * vec->sz), data, n * vec->sz); + vec->len += n; + return 0; +} + +int vl_vector_push_2d(vl_vector *vec, void **data, size_t n) +{ + if (ensure_fits(vec, n) < 0) { + return -1; + } + + unsigned char *d = vec->data; + for (size_t i = 0; i < n; ++i) { + memcpy(d + ((vec->len + i) * vec->sz), data[i], vec->sz); + } + + vec->len += n; + + return 0; +} + +size_t vl_vector_size(const vl_vector *vec) +{ + return vec->len; +} + +void *vl_vector_values(const vl_vector *vec, size_t *psz) +{ + if (psz) *psz = vec->len; + return vec->data; +} -- cgit v1.2.3-70-g09d2