4#if !defined(SKIP_INCLUDES)
11 #if !defined PLACEHOLDERS
18 #if !defined PLACEHOLDERS
26 #define KEY_EQ DC_MEM_EQ
29#if !defined KEY_DELETE
30 #define KEY_DELETE DC_NO_DELETE
34 #define KEY_CLONE DC_COPY_CLONE
38 #define KEY_DEBUG DC_DEFAULT_DEBUG
42 #if !defined PLACEHOLDERS
51#if !defined VALUE_DELETE
52 #define VALUE_DELETE DC_NO_DELETE
55#if !defined VALUE_CLONE
56 #define VALUE_CLONE DC_COPY_CLONE
59#if !defined VALUE_DEBUG
60 #define VALUE_DEBUG DC_DEFAULT_DEBUG
68#define BITSET NS(NAME, bitset)
70#define EXCLUSIVE_END_INDEX CAPACITY
71#define INTERNAL_NAME BITSET
74#define INDEX_TYPE NS(BITSET, index_t)
85#define INVARIANT_CHECK(self) DC_ASSUME(self);
100 if (
NS(
BITSET,
get)(&self->presence, index) &&
KEY_EQ(&self->keys[index], &key)) {
101 return &self->values[index];
132 if (existing_value) {
139 self->keys[index] = key;
140 self->values[index] = value;
141 return &self->values[index];
159 if (
NS(
BITSET,
get)(&self->presence, index) &&
KEY_EQ(&self->keys[index], &key)) {
162 *dest = self->values[index];
208 NS(
BITSET,
delete)(&self->presence);
233#define ITER_CONST NS(SELF, iter_const)
234#define KV_PAIR_CONST NS(ITER_CONST, item)
248 return item->key == NULL &&
item->value == NULL;
253 INDEX_TYPE const next_index = iter->next_index;
260 while (iter->next_index <
CAPACITY &&
261 !
NS(
BITSET,
get)(&iter->map->presence, iter->next_index)) {
269 .key = &iter->map->keys[next_index],
270 .value = &iter->map->values[next_index],
284 .next_index = next_index,
292#define ITER NS(SELF, iter)
293#define KV_PAIR NS(ITER, item)
307 return item->key == NULL &&
item->value == NULL;
312 INDEX_TYPE const next_index = iter->next_index;
315 return (
KV_PAIR){.key = NULL, .value = NULL};
319 while (iter->next_index <
CAPACITY &&
320 !
NS(
BITSET,
get)(&iter->map->presence, iter->next_index)) {
325 return (
KV_PAIR){.key = NULL, .value = NULL};
328 .key = &iter->map->keys[next_index],
329 .value = &iter->map->values[next_index],
343 .next_index = next_index,
351#undef INVARIANT_CHECK
static void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
#define CAPACITY
A very simple bump allocator making use of a provided fixed size buffer (e.g. statically allocated).
static INDEX insert(SELF *self, VALUE value)
static ITER_CONST get_iter_const(SELF const *self)
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 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 SELF clone(SELF const *self)
static VALUE const * try_read(SELF const *self, INDEX index)
static void set(SELF *self, INDEX_TYPE index, bool value)
static VALUE * try_insert(SELF *self, KEY key, VALUE value)
#define KEY
A simple swiss table implementation. See the abseil docs for swss table here.
static void delete_entry(SELF *self, KEY key)
#define DC_TRAIT_MAP(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 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_UNREACHABLE(...)
#define DC_ASSERT(expr,...)
#define TEMPLATE_ERROR(...)
With the user provided name, even in nested templates.
mutation_tracker iterator_invalidation_tracker
dc_gdb_marker derive_c_map_staticlinear
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 FILE * stream(SELF *self)
Opens a file for.