15#if !defined INDEX_BITS
16 #if !defined __clang_analyzer__
17 #error "The number of bits (8,16,32,64) to use for the arena's key"
23 #if !defined __clang_analyzer__
24 #error "The value type to place in the arena must be defined"
31 #define VALUE_DELETE value_delete
33 #define VALUE_CLONE value_clone
36#if !defined VALUE_DELETE
37 #define VALUE_DELETE(value) (void)value
40#if !defined VALUE_CLONE
41 #define VALUE_CLONE(value) (*(value))
45 #define INDEX_TYPE uint8_t
46 #define MAX_CAPACITY (UINT8_MAX + 1ULL)
47 #define MAX_INDEX (UINT8_MAX - 1ULL)
48 #define INDEX_NONE UINT8_MAX
50 #define INDEX_TYPE uint16_t
51 #define MAX_CAPACITY (UINT16_MAX + 1ULL)
52 #define MAX_INDEX (UINT16_MAX - 1ULL)
53 #define INDEX_NONE UINT16_MAX
55 #define INDEX_TYPE uint32_t
56 #define MAX_CAPACITY (UINT32_MAX + 1ULL)
57 #define MAX_INDEX (UINT32_MAX - 1ULL)
58 #define INDEX_NONE UINT32_MAX
60 #define INDEX_TYPE uint64_t
62 #define MAX_CAPACITY UINT64_MAX
63 #define MAX_INDEX (UINT64_MAX - 1ULL)
64 #define INDEX_NONE UINT64_MAX
67#define SLOT NS(SELF, slot)
69#define CHECK_ACCESS_INDEX(self, index) ((index).index < (self)->exclusive_end)
73#define RESIZE_FACTOR 2
76#define INDEX NS(SELF, index)
121 .capacity = (INDEX_TYPE)capacity,
122 .free_list = INDEX_NONE,
131 if (self->free_list != INDEX_NONE) {
132 INDEX_TYPE free_index = self->free_list;
133 SLOT* slot = &self->slots[free_index];
139 return (
INDEX){.index = free_index};
142 if (self->exclusive_end == self->capacity) {
147 self->slots = new_alloc;
150 INDEX_TYPE new_index = self->exclusive_end;
151 SLOT* slot = &self->slots[new_index];
155 self->exclusive_end++;
156 return (
INDEX){.index = new_index};
164 SLOT* slot = &self->slots[index.index];
182 SLOT* slot = &self->slots[index.index];
200 for (INDEX_TYPE index = 0; index < self->exclusive_end; index++) {
201 if (self->slots[index].present) {
206 slots[index].
next_free = self->slots[index].next_free;
212 .capacity = self->capacity,
213 .free_list = self->free_list,
214 .exclusive_end = self->exclusive_end,
215 .count = self->count,
216 .alloc = self->alloc,
228 if (self->free_list == INDEX_NONE) {
244 SLOT* entry = &self->slots[index.index];
246 *destination = entry->
value;
249 self->free_list = index.index;
268 SLOT* entry = &self->slots[index.index];
273 self->free_list = index.index;
280#define IV_PAIR NS(SELF, iv)
286#define ITER NS(SELF, iter)
289 INDEX_TYPE next_index;
293static bool NS(ITER,
empty)(ITER
const* iter) {
298 return iter->next_index == INDEX_NONE || iter->next_index >= iter->arena->exclusive_end;
307 iter->curr = (
IV_PAIR){.index = (
INDEX){.index = iter->next_index},
308 .value = &iter->arena->slots[iter->next_index].value};
310 while (iter->next_index < INDEX_NONE && iter->next_index < iter->arena->exclusive_end &&
311 !iter->arena->slots[iter->next_index].present) {
320 INDEX_TYPE index = 0;
321 while (index < INDEX_NONE && index < self->exclusive_end && !self->slots[index].present) {
328 .curr = (
IV_PAIR){.index = (
INDEX){.index = INDEX_NONE}, .value = NULL},
336 while ((entry =
NS(ITER,
next)(&iter))) {
346#define IV_PAIR_CONST NS(SELF, iv_const)
353 .index = {.index = INDEX_NONE},
357#define ITER_CONST NS(SELF, iter_const)
360 INDEX_TYPE next_index;
364static bool NS(ITER_CONST,
empty)(ITER_CONST
const* iter) {
366 return iter->next_index == INDEX_NONE || iter->next_index >= iter->arena->exclusive_end;
372 if (
NS(ITER_CONST,
empty)(iter)) {
377 .value = &iter->arena->slots[iter->next_index].value};
379 while (iter->next_index != INDEX_NONE && iter->next_index < iter->arena->exclusive_end &&
380 !iter->arena->slots[iter->next_index].present) {
389 INDEX_TYPE index = 0;
390 while (index < INDEX_NONE && index < self->exclusive_end && !self->slots[index].present) {
416#undef CHECK_ACCESS_INDEX
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, VALUE value)
static bool full(SELF const *self)
static ITER_CONST get_iter_const(SELF const *self)
static bool empty(ITER const *iter)
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 VALUE remove(SELF *self, INDEX index)
#define CHECK_ACCESS_INDEX(self, index)
static VALUE * try_write(SELF *self, INDEX index)
static IV_PAIR_CONST iv_const_empty
static bool delete_entry(SELF *self, INDEX index)
static VALUE const * read(SELF const *self, INDEX index)
static VALUE * write(SELF *self, INDEX index)
static value_t value_clone(value_t const *self)
static void value_delete(value_t *UNUSED(self))
static bool try_remove(SELF *self, INDEX index, VALUE *destination)
static SELF clone(SELF const *self)
static VALUE const * try_read(SELF const *self, INDEX index)