growl/next/core/dynarray.h
2026-02-09 10:42:23 -03:00

42 lines
1.5 KiB
C

#ifndef GROWL_DYNARRAY_H
#define GROWL_DYNARRAY_H
// See https://nullprogram.com/blog/2023/10/05/
#include <growl.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#define push(s, a) \
({ \
typeof(s) s_ = (s); \
typeof(a) a_ = (a); \
if (s_->count >= s_->capacity) { \
__grow(s_, sizeof(*s_->data), _Alignof(*s_->data), a_); \
} \
s_->data + s_->count++; \
})
static void __grow(void *slice, ptrdiff_t size, ptrdiff_t align, GrowlArena *a) {
struct {
uint8_t *data;
ptrdiff_t len;
ptrdiff_t cap;
} replica;
memcpy(&replica, slice, sizeof(replica));
if (!replica.data) {
replica.cap = 1;
replica.data = growl_arena_alloc(a, 2 * size, align, replica.cap);
} else if (a->free == replica.data + size * replica.cap) {
growl_arena_alloc(a, size, 1, replica.cap);
} else {
void *data = growl_arena_alloc(a, 2 * size, align, replica.cap);
memcpy(data, replica.data, size * replica.len);
replica.data = data;
}
replica.cap *= 2;
memcpy(slice, &replica, sizeof(replica));
}
#endif // GROWL_DYNARRAY_H