14#error "Key type must be defined to for a hashmap template"
17} derive_c_parameter_key;
18#define K derive_c_parameter_key
19static void derive_c_parameter_key_delete(derive_c_parameter_key*) {}
20#define K_DELETE derive_c_parameter_key_delete
24#error "Value type must be defined to for a hashmap template"
27} derive_c_parameter_value;
28#define V derive_c_parameter_value
29static void derive_c_parameter_value_delete(derive_c_parameter_value*) {}
30#define V_DELETE derive_c_parameter_value_delete
34#error "The hash function for K must be defined"
35static size_t derive_c_parameter_hash(derive_c_parameter_key
const* key);
36#define HASH derive_c_parameter_hash
40#error "The equality function for K must be defined"
41static bool derive_c_parameter_eq(derive_c_parameter_key
const* key_1,
42 derive_c_parameter_key
const* key_2);
43#define EQ derive_c_parameter_eq
51#define V_DELETE(value)
54#define KEY_ENTRY NAME(SELF, key_entry)
79 V* values = (
V*)malloc(
sizeof(
V) * real_capacity);
82 .capacity = real_capacity,
101 V* values = (
V*)malloc(
sizeof(
V) * self->capacity);
104 for (
size_t i = 0; i < self->capacity; i++) {
105 if (self->keys[i].present) {
106 keys[i] = self->keys[i];
107 values[i] = self->values[i];
111 return (
SELF){.capacity = self->capacity, .items = self->items, .keys = keys, .values = values};
121 if (target_capacity > self->capacity) {
123 for (
size_t index = 0; index < self->capacity; index++) {
141 uint16_t distance_from_desired = 0;
142 size_t hash =
HASH(&key);
144 V* placed_entry = NULL;
150 if (
EQ(&entry->
key, &key)) {
155 K switch_key = entry->
key;
157 V switch_value = self->values[index];
161 self->values[index] = value;
164 distance_from_desired = switch_distance_from_desired;
165 value = switch_value;
168 placed_entry = &self->values[index];
172 distance_from_desired++;
178 self->values[index] = value;
180 placed_entry = &self->values[index];
196 size_t hash =
HASH(&key);
202 if (
EQ(&entry->
key, &key)) {
203 return &self->values[index];
221 size_t hash =
HASH(&key);
227 if (
EQ(&entry->
key, &key)) {
228 return &self->values[index];
246 size_t hash =
HASH(&key);
252 if (
EQ(&entry->
key, &key)) {
255 *destination = self->values[index];
264 size_t free_index = index;
268 KEY_ENTRY* check_entry = &self->keys[check_index];
271 free_entry->
key = check_entry->
key;
273 self->values[free_index] = self->values[check_index];
275 free_index = check_index;
276 free_entry = check_entry;
279 check_entry = &self->keys[check_index];
316#define KV_PAIR NAME(SELF, kv)
323#define ITER NAME(SELF, iter)
333 if (iter->index < iter->map->capacity) {
334 KV_PAIR ret_val = {.key = &iter->map->keys[iter->index].key,
335 .value = &iter->map->values[iter->index]};
338 while (iter->index < iter->map->capacity && !iter->map->keys[iter->index].present) {
344 return (
KV_PAIR){.key = NULL, .value = NULL};
355 return iter->index >= iter->map->capacity;
360 size_t first_index = 0;
361 while (first_index < self->capacity && !self->keys[first_index].present) {
366 .index = first_index,
375 for (
size_t i = 0; i < self->capacity; i++) {
376 if (self->keys[i].present) {
389#define KV_PAIR_CONST NAME(SELF, kv_const)
396#define ITER_CONST NAME(SELF, iter_const)
406 if (iter->index < iter->map->capacity) {
407 KV_PAIR_CONST ret_val = {.key = &iter->map->keys[iter->index].key,
408 .value = &iter->map->values[iter->index]};
411 while (iter->index < iter->map->capacity && !iter->map->keys[iter->index].present) {
426static bool NAME(ITER_CONST,
empty)(ITER_CONST
const* iter) {
428 return iter->index >= iter->map->capacity;
433 size_t first_index = 0;
434 while (first_index < self->capacity && !self->keys[first_index].present) {
439 .index = first_index,
static INDEX insert(SELF *self, V value)
static bool try_remove(SELF *self, INDEX index, V *destination)
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 IV_PAIR next(ITER *iter)
static INDEX_TYPE size(SELF const *self)
static V const * try_read(SELF const *self, INDEX index)
static SELF new_with_capacity_for(INDEX_TYPE items)
static V * write(SELF *self, INDEX index)
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)
static void extend_capacity_for(SELF *self, size_t expected_items)
static V * try_insert(SELF *self, K key, V value)
#define DEBUG_ASSERT(expr)
uint16_t distance_from_desired
gdb_marker derive_c_hashmap
static size_t const INITIAL_CAPACITY
static size_t modulus_capacity(size_t index, size_t capacity)
static size_t apply_capacity_policy(size_t capacity)