4#if !defined(SKIP_INCLUDES)
11#if !defined INDEX_BITS
12 #if !defined PLACEHOLDERS
13TEMPLATE_ERROR(
"The number of bits (8,16,32,64) to use for the arena's key")
19 #if !defined PLACEHOLDERS
20TEMPLATE_ERROR(
"The value type to place in the arena must be defined")
26 #define VALUE_DELETE value_delete
28 #define VALUE_CLONE value_clone
30 #define VALUE_DEBUG value_debug
36#if !defined VALUE_DELETE
37 #define VALUE_DELETE DC_NO_DELETE
40#if !defined VALUE_CLONE
41 #define VALUE_CLONE DC_COPY_CLONE
44#if !defined VALUE_DEBUG
45 #define VALUE_DEBUG DC_DEFAULT_DEBUG
51#define CHECK_ACCESS_INDEX(self, index) ((index).index < (self)->exclusive_end)
55#define RESIZE_FACTOR 2
60#define SLOT NS(NAME, slot)
62#define SLOT_INDEX_TYPE INDEX_TYPE
63#define SLOT_VALUE VALUE
64#define SLOT_VALUE_CLONE VALUE_CLONE
65#define SLOT_VALUE_CLONE VALUE_CLONE
66#define SLOT_VALUE_DELETE VALUE_DELETE
67#define INTERNAL_NAME SLOT
90#define INVARIANT_CHECK(self) \
92 DC_ASSUME((self)->count <= (self)->capacity); \
93 DC_ASSUME((self)->exclusive_end >= (self)->count); \
94 DC_ASSUME((self)->count <= MAX_INDEX);
110 .free_list = INDEX_NONE,
124 if (self->free_list != INDEX_NONE) {
126 SLOT* slot = &self->slots[free_index];
128 self->free_list = slot->next_free;
129 slot->present =
true;
133 return (INDEX){.index = free_index};
136 if (self->exclusive_end == self->capacity) {
142 self->slots = new_alloc;
144 for (
size_t index = self->exclusive_end; index < self->
capacity; index++) {
150 SLOT* slot = &self->slots[new_index];
151 slot->present =
true;
155 self->exclusive_end++;
156 return (INDEX){.index = new_index};
164 SLOT* slot = &self->slots[index.index];
165 if (!slot->present) {
182 SLOT* slot = &self->slots[index.index];
183 if (!slot->present) {
200 for (
INDEX_TYPE index = 0; index < self->exclusive_end; index++) {
201 if (self->slots[index].present) {
203 slots[index].present =
true;
207 slots[index].present =
false;
208 slots[index].next_free = self->slots[index].next_free;
214 .capacity = self->capacity,
215 .free_list = self->free_list,
216 .exclusive_end = self->exclusive_end,
217 .count = self->count,
218 .alloc = self->alloc,
231 if (self->capacity == CAPACITY_EXCLUSIVE_UPPER) {
232 if (self->free_list == INDEX_NONE) {
249 SLOT* entry = &self->slots[index.index];
250 if (entry->present) {
251 *destination = entry->
value;
252 entry->present =
false;
254 entry->next_free = self->free_list;
255 self->free_list = index.index;
271#define IV_PAIR NS(SELF, iv)
279 return (
IV_PAIR){.index = (INDEX){.index = INDEX_NONE}, .value = NULL};
282#define ITER NS(SELF, iter)
299 return iter->next_index == INDEX_NONE || iter->next_index >= iter->arena->exclusive_end;
306 while (iter->next_index < INDEX_NONE && iter->next_index < iter->arena->exclusive_end) {
308 .index = (INDEX){.index = iter->next_index},
309 .value = &iter->arena->slots[iter->next_index].value,
314 while (iter->next_index < INDEX_NONE && iter->next_index < iter->arena->exclusive_end &&
315 !iter->arena->slots[iter->next_index].present) {
319 if (result.
value && result.
value == &iter->arena->slots[result.
index.index].value &&
320 iter->arena->slots[result.
index.index].present) {
331 while (index < INDEX_NONE && index < self->exclusive_end && !self->slots[index].present) {
357#define IV_PAIR_CONST NS(SELF, iv_const)
365 return (
IV_PAIR_CONST){.index = (INDEX){.index = INDEX_NONE}, .value = NULL};
368#define ITER_CONST NS(SELF, iter_const)
385 return iter->next_index == INDEX_NONE || iter->next_index >= iter->arena->exclusive_end;
392 while (iter->next_index < INDEX_NONE && iter->next_index < iter->arena->exclusive_end) {
394 .index = (INDEX){.index = iter->next_index},
395 .value = &iter->arena->slots[iter->next_index].value,
398 while (iter->next_index != INDEX_NONE && iter->next_index < iter->arena->exclusive_end &&
399 !iter->arena->slots[iter->next_index].present) {
403 if (result.
value && iter->arena->slots[result.
index.index].present) {
414 while (index < INDEX_NONE && index < self->exclusive_end && !self->slots[index].present) {
466#undef INVARIANT_CHECK
469#undef CHECK_ACCESS_INDEX
static void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
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 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 IV_PAIR next(ITER *iter)
static INDEX_TYPE size(SELF const *self)
#define INVARIANT_CHECK(self)
static VALUE remove(SELF *self, INDEX index)
static bool empty_item(IV_PAIR const *item)
static IV_PAIR_CONST iv_const_empty()
static VALUE * try_write(SELF *self, INDEX index)
static VALUE const * read(SELF const *self, INDEX index)
static VALUE * write(SELF *self, INDEX index)
static bool try_remove(SELF *self, INDEX index, VALUE *destination)
static const size_t max_entries
static SELF clone(SELF const *self)
static VALUE const * try_read(SELF const *self, INDEX index)
static IV_PAIR iv_empty()
static SELF new_with_capacity_for(INDEX_TYPE items, ALLOC *alloc)
#define CHECK_ACCESS_INDEX(self, index)
#define DC_TRAIT_ARENA(SELF)
dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
static void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
static dc_gdb_marker dc_gdb_marker_new()
static DC_INLINE DC_CONST size_t dc_math_next_power_of_2(size_t x)
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)
#define EXPAND_STRING(NAME)
#define DC_ASSERT(expr,...)
#define DC_ASSUME(expr,...)
#define TEMPLATE_ERROR(...)
With the user provided name, even in nested templates.
mutation_tracker iterator_invalidation_tracker
dc_gdb_marker derive_c_arena_basic
Debug format helpers for debug printin data structures.
tracks a specific version of a value, so that this can be compared later to check modification For ex...
static void memory_tracker_present(SELF const *slot)
static void memory_tracker_empty(SELF const *slot)
static FILE * stream(SELF *self)
Opens a file for.