19#ifndef __clang_analyzer__
20#error "The number of bits (8,16,32,64) to use for the arena's key"
26#ifndef __clang_analyzer__
27#error "The value type to place in the arena must be defined"
31} derive_c_parameter_value;
32#define V derive_c_parameter_value
33void derive_c_parameter_value_delete(derive_c_parameter_value*
UNUSED(key)) {}
34#define V_DELETE derive_c_parameter_value_delete
38#define V_DELETE(value) (void)value
42#define INDEX_TYPE uint8_t
43#define MAX_CAPACITY (UINT8_MAX + 1ULL)
44#define MAX_INDEX (UINT8_MAX - 1ULL)
45#define INDEX_NONE UINT8_MAX
47#define INDEX_TYPE uint16_t
48#define MAX_CAPACITY (UINT16_MAX + 1ULL)
49#define MAX_INDEX (UINT16_MAX - 1ULL)
50#define INDEX_NONE UINT16_MAX
52#define INDEX_TYPE uint32_t
53#define MAX_CAPACITY (UINT32_MAX + 1ULL)
54#define MAX_INDEX (UINT32_MAX - 1ULL)
55#define INDEX_NONE UINT32_MAX
57#define INDEX_TYPE uint64_t
59#define MAX_CAPACITY UINT64_MAX
60#define MAX_INDEX (UINT64_MAX - 1ULL)
61#define INDEX_NONE UINT64_MAX
64#define SLOT NAME(SELF, SLOT)
66#define CHECK_ACCESS_INDEX(self, index) ((index).index < (self)->exclusive_end)
70#define RESIZE_FACTOR 2
73#define INDEX NAME(SELF, index)
118 .capacity = (INDEX_TYPE)capacity,
119 .free_list = INDEX_NONE,
128 if (self->free_list != INDEX_NONE) {
129 INDEX_TYPE free_index = self->free_list;
130 SLOT* slot = &self->slots[free_index];
136 return (
INDEX){.index = free_index};
139 if (self->exclusive_end == self->capacity) {
144 self->slots = new_alloc;
147 INDEX_TYPE new_index = self->exclusive_end;
148 SLOT* slot = &self->slots[new_index];
152 self->exclusive_end++;
153 return (
INDEX){.index = new_index};
161 SLOT* slot = &self->slots[index.index];
179 SLOT* slot = &self->slots[index.index];
196 memcpy(slots, self->slots, self->exclusive_end *
sizeof(
SLOT));
199 .capacity = self->capacity,
200 .free_list = self->free_list,
201 .exclusive_end = self->exclusive_end,
202 .count = self->count,
203 .alloc = self->alloc,
215 if (self->free_list == INDEX_NONE) {
231 SLOT* entry = &self->slots[index.index];
233 *destination = entry->
value;
236 self->free_list = index.index;
255 SLOT* entry = &self->slots[index.index];
260 self->free_list = index.index;
267#define IV_PAIR NAME(SELF, iv)
273#define ITER NAME(SELF, iter)
276 INDEX_TYPE next_index;
286 return iter->next_index == INDEX_NONE || iter->next_index >= iter->arena->exclusive_end;
295 iter->curr = (
IV_PAIR){.index = (
INDEX){.index = iter->next_index},
296 .value = &iter->arena->slots[iter->next_index].value};
298 while (iter->next_index < INDEX_NONE && iter->next_index < iter->arena->exclusive_end &&
299 !iter->arena->slots[iter->next_index].present) {
314 INDEX_TYPE index = 0;
315 while (index < INDEX_NONE && index < self->exclusive_end && !self->slots[index].present) {
323 .curr = (
IV_PAIR){.index = (
INDEX){.index = INDEX_NONE}, .value = NULL},
331 while ((entry =
NAME(ITER,
next)(&iter))) {
341#define IV_PAIR_CONST NAME(SELF, iv_const)
348 .index = {.index = INDEX_NONE},
352#define ITER_CONST NAME(SELF, iter_const)
355 INDEX_TYPE next_index;
360static bool NAME(ITER_CONST,
empty)(ITER_CONST
const* iter) {
362 return iter->next_index == INDEX_NONE || iter->next_index >= iter->arena->exclusive_end;
373 .value = &iter->arena->slots[iter->next_index].value};
375 while (iter->next_index != INDEX_NONE && iter->next_index < iter->arena->exclusive_end &&
376 !iter->arena->slots[iter->next_index].present) {
391 INDEX_TYPE index = 0;
392 while (index < INDEX_NONE && index < self->exclusive_end && !self->slots[index].present) {
413#undef CHECK_ACCESS_INDEX
#define ALLOC
An allocator that prints to stdout when it allocates or frees memory.
static void free(SELF *self, void *ptr)
static void * realloc(SELF *self, void *ptr, size_t size)
static void * calloc(SELF *self, size_t count, size_t size)
static size_t next_power_of_2(size_t x)
#define DEBUG_ASSERT(expr)
static INDEX insert(SELF *self, V value)
static bool try_remove(SELF *self, INDEX index, V *destination)
static bool full(SELF const *self)
static ITER_CONST get_iter_const(SELF const *self)
static bool empty(ITER const *iter)
static V remove(SELF *self, INDEX index)
static ITER get_iter(SELF *self)
static SELF new_with_capacity_for(INDEX_TYPE items, ALLOC *alloc)
static size_t max_capacity
static INDEX_TYPE size(SELF const *self)
static IV_PAIR const * next(ITER *iter)
static V const * try_read(SELF const *self, INDEX index)
#define CHECK_ACCESS_INDEX(self, index)
static V * write(SELF *self, INDEX index)
static IV_PAIR_CONST iv_const_empty
static bool delete_entry(SELF *self, INDEX index)
static SELF shallow_clone(SELF const *self)
static V * try_write(SELF *self, INDEX index)
static size_t position(ITER const *iter)
static V const * read(SELF const *self, INDEX index)
#define ALLOC
A simple vector.