#include "dynbuf.h" #include #ifndef GROWTH_FACTOR #define GROWTH_FACTOR 2 #endif #ifndef INITIAL_CAPACITY #define INITIAL_CAPACITY 4 #endif #ifdef GROWTH_POW2 #define ROUND_UP_POW2(x) round_up_pow2(x) static inline int round_up_pow2(int x) { if (x <= 1) return 1; x--; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return x + 1; } #else #define ROUND_UP_POW2(x) (x) #endif void dynbuf_init(Dynbuf *v, size_t elem_size) { v->elem_size = elem_size; v->length = 0; v->capacity = INITIAL_CAPACITY; v->data = malloc(v->capacity * elem_size); assert(v->data != NULL); } void dynbuf_free(Dynbuf *v) { free(v->data); v->data = NULL; v->length = 0; v->capacity = 0; v->elem_size = 0; } void dynbuf_push(Dynbuf *v, const void *elem) { if (v->length == v->capacity) { dynbuf_resize(v, ROUND_UP_POW2(v->capacity * GROWTH_FACTOR)); } memcpy((char *)v->data + v->length * v->elem_size, elem, v->elem_size); v->length++; } void dynbuf_resize(Dynbuf *v, size_t newcap) { printf("Resize to %zu\n", newcap); if (newcap > v->capacity) { v->capacity = newcap; v->data = realloc(v->data, v->capacity * v->elem_size); assert(v->data != NULL); } } void dynbuf_pop(Dynbuf *v) { if (v->length > 0) { v->length--; } } void *dynbuf_get(Dynbuf *v, size_t index) { assert(index < v->length); return (char *)v->data + index * v->elem_size; } inline size_t dynbuf_size(const Dynbuf *v) { return v->length; } inline size_t dynbuf_capacity(const Dynbuf *v) { return v->capacity; }