19#if !defined INDEX_BITS
20 #if !defined PLACEHOLDERS
21 #error "The number of bits (8,16,32,64) to use for the arena's key"
27 #if !defined PLACEHOLDERS
28 #error "The value type to place in the arena must be defined"
35 #define VALUE_DELETE value_delete
37 #define VALUE_CLONE value_clone
42#if !defined VALUE_DELETE
43 #define VALUE_DELETE(value) (void)value
46#if !defined VALUE_CLONE
47 #define VALUE_CLONE(value) (*(value))
51 #define INDEX_TYPE uint8_t
52 #define CAPACITY_EXCLUSIVE_UPPER (UINT8_MAX + 1ULL)
53 #define MAX_INDEX (UINT8_MAX - 1ULL)
54 #define INDEX_NONE UINT8_MAX
56 #define INDEX_TYPE uint16_t
57 #define CAPACITY_EXCLUSIVE_UPPER (UINT16_MAX + 1ULL)
58 #define MAX_INDEX (UINT16_MAX - 1ULL)
59 #define INDEX_NONE UINT16_MAX
61 #define INDEX_TYPE uint32_t
62 #define CAPACITY_EXCLUSIVE_UPPER (UINT32_MAX + 1ULL)
63 #define MAX_INDEX (UINT32_MAX - 1ULL)
64 #define INDEX_NONE UINT32_MAX
66 #define INDEX_TYPE uint64_t
68 #define CAPACITY_EXCLUSIVE_UPPER UINT64_MAX
69 #define MAX_INDEX (UINT64_MAX - 1ULL)
70 #define INDEX_NONE UINT64_MAX
73#define SLOT NS(SELF, slot)
75#define CHECK_ACCESS_INDEX(self, index) ((index).index < (self)->exclusive_end)
79#define RESIZE_FACTOR 2
82#define INDEX NS(SELF, index_t)
142#define INVARIANT_CHECK(self) \
144 ASSUME((self)->count <= (self)->capacity); \
145 ASSUME((self)->exclusive_end >= (self)->count); \
146 ASSUME((self)->count <= MAX_INDEX);
151 ASSERT(capacity <= CAPACITY_EXCLUSIVE_UPPER);
155 for (
INDEX_TYPE index = 0; index < capacity; index++) {
162 .free_list = INDEX_NONE,
173 ASSERT(self->count < MAX_INDEX);
176 if (self->free_list != INDEX_NONE) {
178 SLOT* slot = &self->slots[free_index];
185 return (
INDEX){.index = free_index};
188 if (self->exclusive_end == self->capacity) {
193 self->slots = new_alloc;
195 for (
size_t index = self->exclusive_end; index < self->capacity; index++) {
201 SLOT* slot = &self->slots[new_index];
206 self->exclusive_end++;
207 return (
INDEX){.index = new_index};
215 SLOT* slot = &self->slots[index.index];
233 SLOT* slot = &self->slots[index.index];
251 for (
INDEX_TYPE index = 0; index < self->exclusive_end; index++) {
252 if (self->slots[index].present) {
259 slots[index].
next_free = self->slots[index].next_free;
265 .capacity = self->capacity,
266 .free_list = self->free_list,
267 .exclusive_end = self->exclusive_end,
268 .count = self->count,
269 .alloc = self->alloc,
282 if (self->capacity == CAPACITY_EXCLUSIVE_UPPER) {
283 if (self->free_list == INDEX_NONE) {
300 SLOT* entry = &self->slots[index.index];
302 *destination = entry->
value;
306 self->free_list = index.index;
330 SLOT* entry = &self->slots[index.index];
336 self->free_list = index.index;
343#define IV_PAIR NS(SELF, iv)
349#define ITER NS(SELF, iter)
361static bool NS(ITER,
empty)(ITER
const* iter) {
367 return iter->next_index == INDEX_NONE || iter->next_index >= iter->arena->exclusive_end;
377 iter->curr = (
IV_PAIR){.index = (
INDEX){.index = iter->next_index},
378 .value = &iter->arena->slots[iter->next_index].value};
380 while (iter->next_index < INDEX_NONE && iter->next_index < iter->arena->exclusive_end &&
381 !iter->arena->slots[iter->next_index].present) {
391 while (index < INDEX_NONE && index < self->exclusive_end && !self->slots[index].present) {
398 .curr = (
IV_PAIR){.index = (
INDEX){.index = INDEX_NONE}, .value = NULL},
407 while ((entry =
NS(ITER,
next)(&iter))) {
417#define IV_PAIR_CONST NS(SELF, iv_const)
424 .index = {.index = INDEX_NONE},
428#define ITER_CONST NS(SELF, iter_const)
440static bool NS(ITER_CONST,
empty)(ITER_CONST
const* iter) {
443 return iter->next_index == INDEX_NONE || iter->next_index >= iter->arena->exclusive_end;
450 if (
NS(ITER_CONST,
empty)(iter)) {
455 .value = &iter->arena->slots[iter->next_index].value};
457 while (iter->next_index != INDEX_NONE && iter->next_index < iter->arena->exclusive_end &&
458 !iter->arena->slots[iter->next_index].present) {
468 while (index < INDEX_NONE && index < self->exclusive_end && !self->slots[index].present) {
490#undef CAPACITY_EXCLUSIVE_UPPER
495#undef CHECK_ACCESS_INDEX
499#undef INVARIANT_CHECK
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 INDEX insert(SELF *self, VALUE value)
static bool empty_item(IV_PAIR const *const *item)
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 INDEX_TYPE size(SELF const *self)
static IV_PAIR const * next(ITER *iter)
#define INVARIANT_CHECK(self)
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 void memory_tracker_present(SLOT const *slot)
static VALUE * write(SELF *self, INDEX index)
static size_t max_entries
static value_t value_clone(value_t const *self)
static void value_delete(value_t *self)
static bool try_remove(SELF *self, INDEX index, VALUE *destination)
static SELF clone(SELF const *self)
static void memory_tracker_empty(SLOT const *slot)
static VALUE const * try_read(SELF const *self, INDEX index)
#define TRAIT_ARENA(SELF)
static gdb_marker gdb_marker_new()
static INLINE CONST size_t next_power_of_2(size_t x)
@ MEMORY_TRACKER_LVL_CONTAINER
static void memory_tracker_set(memory_tracker_level level, memory_tracker_capability cap, const volatile void *addr, size_t size)
@ MEMORY_TRACKER_CAP_NONE
@ MEMORY_TRACKER_CAP_WRITE
@ MEMORY_TRACKER_CAP_READ_WRITE
static mutation_tracker mutation_tracker_new()
static void mutation_version_check(mutation_version const *self)
static mutation_version mutation_tracker_get(mutation_tracker const *self)
static void mutation_tracker_mutate(mutation_tracker *self)
mutation_tracker iterator_invalidation_tracker
gdb_marker derive_c_arena_basic
tracks a specific version of a value, so that this can be compared later to check modification For ex...