From e5af28536bfb0f4c9131df56d2009ba5196f5e3a Mon Sep 17 00:00:00 2001 From: Lizzy Fleckenstein Date: Sun, 12 Apr 2026 20:57:06 +0200 Subject: init --- src/util/container.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/util/container.h (limited to 'src/util/container.h') diff --git a/src/util/container.h b/src/util/container.h new file mode 100644 index 0000000..8b89440 --- /dev/null +++ b/src/util/container.h @@ -0,0 +1,64 @@ +#ifndef ANIMTOOL_CONTAINER_H_ +#define ANIMTOOL_CONTAINER_H_ + +#include +#include +#include +#include + +#define option(type) struct { bool present; type data; } +#define array(type) struct { size_t len; type *ptr; } +#define arraybuf(type) struct { size_t len, cap; type *ptr; } +#define map(type) arraybuf(struct { str key; type val; }) + +#define array_typeck(a, b) ((void) ((a).ptr == (b).ptr)) + +#define array_eq(a, b) (array_typeck(a, b), \ + ((a).len == (b).len && !memcmp((a).ptr, (b).ptr, (a).len * sizeof *(a).ptr))) + +#define array_alloc(arr, e_len) (arr)->ptr = malloc(((arr)->len = (e_len)) * sizeof *(arr)->ptr) + +#define array_dup(dst, src) do { \ + array_typeck(*(dst), *(src)); \ + array_alloc(dst, (src)->len); \ + memcpy((dst)->ptr, (src)->ptr, (src)->len * sizeof(*(src)->ptr)); \ + } while(0) + +#define arraybuf_grow(arr, by) do { \ + if ((arr)->len + by > (arr)->cap) \ + (arr)->ptr = realloc((arr)->ptr, ((arr)->cap = stdc_bit_ceil((arr)->len) + by) * sizeof(*(arr)->ptr)); \ + else if (!(arr)->ptr) \ + (arr)->ptr = malloc((arr)->cap * sizeof(*(arr)->ptr)); \ + } while (0) + +#define arraybuf_insert(arr, val) do { \ + arraybuf_grow(arr, 1); \ + (arr)->ptr[(arr)->len++] = (val); \ + } while (0) + +#define arraybuf_cast(arr) { .len = (arr).len, .ptr = (arr).ptr } +#define array_assign(a, b) do { (a)->len = (b).len; (a)->ptr = (b).ptr; } while(0) + +#define map_find(arr, e_key, p_val) do { \ + for (size_t i = 0; i < (arr)->len; i++) \ + if (array_eq((arr)->ptr[i].key, e_key)) { \ + *(p_val) = &(arr)->ptr[i].val; \ + break; \ + } \ + } while (0) + +#define map_insert_end(arr, e_key, e_val) do { \ + arraybuf_grow(arr, 1); \ + (arr)->ptr[(arr)->len].key = (e_key); \ + (arr)->ptr[(arr)->len].val = (e_val); \ + (arr)->len++; \ + } while (0) + +#define map_insert(arr, e_key, e_val, p_succ) do { \ + typeof(&(arr)->ptr->val) _val = nullptr; \ + map_find(arr, e_key, &_val); \ + if ((*(p_succ) = !_val)) \ + map_insert_end(arr, e_key, e_val); \ + } while (0) + +#endif -- cgit v1.2.3