Derive-C
Loading...
Searching...
No Matches
template.h File Reference

Go to the source code of this file.

Data Structures

struct  value_t
struct  SELF
 An allocator that prints to stdout when it allocates or frees memory. More...
struct  IV_PAIR_CONST
struct  ITER_CONST
struct  IV_PAIR
struct  ITER

Macros

#define INDEX_BITS   32
 A block based arena that allocated in block doubling in size. TODO(oliverkillane): look at bumaplo.
#define VALUE   value_t
#define VALUE_DELETE   value_delete
#define VALUE_CLONE   value_clone
#define VALUE_DEBUG   value_debug
#define INITIAL_BLOCK_INDEX_BITS   8
#define SLOT   NS(NAME, slot)
#define SLOT_INDEX_TYPE   INDEX_TYPE
#define SLOT_VALUE   VALUE
#define SLOT_VALUE_CLONE   VALUE_CLONE
#define SLOT_VALUE_DELETE   VALUE_DELETE
#define INTERNAL_NAME   SLOT
#define INVARIANT_CHECK(self)
#define IV_PAIR_CONST   NS(SELF, iv_const)
#define ITER_CONST   NS(SELF, iter_const)
#define IV_PAIR   NS(SELF, iv)
#define ITER   NS(SELF, iter)

Typedefs

typedef IV_PAIR_CONST item

Functions

static void VALUE_DELETE (value_t *)
static value_t VALUE_CLONE (value_t const *self)
static void VALUE_DEBUG (VALUE const *, dc_debug_fmt, FILE *)
 DC_STATIC_ASSERT (sizeof(VALUE), "VALUE must be a non-zero sized type")
 DC_STATIC_ASSERT (INITIAL_BLOCK_INDEX_BITS< INDEX_BITS, "INITIAL_BLOCK_INDEX_BITS must be less than INDEX_BITS")
 DC_STATIC_ASSERT (INITIAL_BLOCK_INDEX_BITS > 0, "INITIAL_BLOCK_INDEX_BITS must be greater than zero")
static DC_PUBLIC SELF new (ref alloc_ref)
static DC_PUBLIC INDEX insert (SELF *self, VALUE value)
static DC_PUBLIC VALUE const * try_read (SELF const *self, INDEX index)
static DC_PUBLIC VALUE const * read (SELF const *self, INDEX index)
static DC_PUBLIC VALUEtry_write (SELF *self, INDEX index)
static DC_PUBLIC VALUEwrite (SELF *self, INDEX index)
static DC_PUBLIC size_t size (SELF const *self)
static DC_PUBLIC SELF clone (SELF const *self)
static DC_PUBLIC bool try_remove (SELF *self, INDEX index, VALUE *destination)
static DC_PUBLIC VALUE remove (SELF *self, INDEX index)
static DC_PUBLIC void delete (SELF *self)
static DC_PUBLIC IV_PAIR_CONST iv_const_empty ()
static DC_PUBLIC bool empty_item (IV_PAIR_CONST const *item)
static DC_PUBLIC IV_PAIR_CONST next (ITER_CONST *iter)
static DC_PUBLIC bool empty (ITER_CONST const *iter)
static DC_PUBLIC ITER_CONST get_iter_const (SELF const *self)
static DC_PUBLIC void debug (SELF const *self, dc_debug_fmt fmt, FILE *stream)
static DC_PUBLIC IV_PAIR iv_empty ()
static DC_PUBLIC bool empty_item (IV_PAIR const *item)
static DC_PUBLIC IV_PAIR next (ITER *iter)
static DC_PUBLIC bool empty (ITER const *iter)
static DC_PUBLIC ITER get_iter (SELF *self)
 DC_TRAIT_ARENA (SELF)

Variables

static const size_t max_entries = MAX_INDEX

Macro Definition Documentation

◆ INDEX_BITS

#define INDEX_BITS   32

A block based arena that allocated in block doubling in size. TODO(oliverkillane): look at bumaplo.

Blocks of doubling size are used to allocate elements.

BitMask Index Entries Offset Block
XXXXX000 0 8 0 0
XXXXX111 7 7 0
XXXX1000 8 8 0 1
XXXX1111 15 7 1
XXX10000 16 16 0 2
XXX11111 31 15 2
XX100000 32 32 0 3
XX111111 63 31 3
X1000000 64 64 0 4
X1111111 127 63 4
10000000 128 128 0 5
11111111 255 127 5

Definition at line 41 of file template.h.

◆ INITIAL_BLOCK_INDEX_BITS

#define INITIAL_BLOCK_INDEX_BITS   8

Definition at line 78 of file template.h.

◆ INTERNAL_NAME

#define INTERNAL_NAME   SLOT

Definition at line 97 of file template.h.

◆ INVARIANT_CHECK

#define INVARIANT_CHECK ( self)
Value:
DC_ASSUME(self); \
DC_ASSUME(DC_ARENA_GEO_BLOCK_TO_SIZE((self)->block_current, INITIAL_BLOCK_INDEX_BITS) >= \
(self)->block_current_exclusive_end); \
DC_ASSUME((self)->count <= MAX_INDEX);
#define DC_ARENA_GEO_BLOCK_TO_SIZE(BLOCK, INITIAL_BLOCK_INDEX_BITS)
Definition utils.h:12
#define DC_ASSUME(expr,...)
Definition panic.h:57

Definition at line 117 of file template.h.

117#define INVARIANT_CHECK(self) \
118 DC_ASSUME(self); \
119 DC_ASSUME(DC_ARENA_GEO_BLOCK_TO_SIZE((self)->block_current, INITIAL_BLOCK_INDEX_BITS) >= \
120 (self)->block_current_exclusive_end); \
121 DC_ASSUME((self)->count <= MAX_INDEX);

◆ ITER

#define ITER   NS(SELF, iter)

Definition at line 509 of file template.h.

◆ ITER_CONST

#define ITER_CONST   NS(SELF, iter_const)

Definition at line 346 of file template.h.

◆ IV_PAIR

#define IV_PAIR   NS(SELF, iv)

Definition at line 496 of file template.h.

◆ IV_PAIR_CONST

#define IV_PAIR_CONST   NS(SELF, iv_const)

Definition at line 333 of file template.h.

◆ SLOT

#define SLOT   NS(NAME, slot)

Definition at line 91 of file template.h.

◆ SLOT_INDEX_TYPE

#define SLOT_INDEX_TYPE   INDEX_TYPE

Definition at line 93 of file template.h.

◆ SLOT_VALUE

#define SLOT_VALUE   VALUE

Definition at line 94 of file template.h.

◆ SLOT_VALUE_CLONE

#define SLOT_VALUE_CLONE   VALUE_CLONE

Definition at line 95 of file template.h.

◆ SLOT_VALUE_DELETE

#define SLOT_VALUE_DELETE   VALUE_DELETE

Definition at line 96 of file template.h.

◆ VALUE

#define VALUE   value_t

Definition at line 51 of file template.h.

◆ VALUE_CLONE

#define VALUE_CLONE   value_clone

Definition at line 54 of file template.h.

◆ VALUE_DEBUG

#define VALUE_DEBUG   value_debug

Definition at line 56 of file template.h.

◆ VALUE_DELETE

#define VALUE_DELETE   value_delete

Definition at line 52 of file template.h.

Typedef Documentation

◆ item

Definition at line 347 of file template.h.

Function Documentation

◆ clone()

DC_PUBLIC SELF clone ( SELF const * self)
static

Definition at line 240 of file template.h.

240 {
241 INVARIANT_CHECK(self);
242
243 SELF new_self = {
244 .free_list = self->free_list,
245 .count = self->count,
246 .alloc_ref = self->alloc_ref,
247 .derive_c_arena_blocks = dc_gdb_marker_new(),
248 .iterator_invalidation_tracker = mutation_tracker_new(),
249 .block_current_exclusive_end = self->block_current_exclusive_end,
250 .block_current = self->block_current,
251 .blocks = {},
252 };
253
254 for (size_t block_index = 0; block_index <= self->block_current; block_index++) {
255 size_t block_items = DC_ARENA_GEO_BLOCK_TO_SIZE(block_index, INITIAL_BLOCK_INDEX_BITS);
256 SLOT* block_slots =
257 (SLOT*)NS(ALLOC, allocate_uninit)(self->alloc_ref, block_items * sizeof(SLOT));
258 new_self.blocks[block_index] = block_slots;
259
260 size_t const to_offset =
261 block_index == self->block_current ? self->block_current_exclusive_end : block_items;
262
263 for (size_t offset = 0; offset < to_offset; offset++) {
264 SLOT* src_slot = &self->blocks[block_index][offset];
265 SLOT* dst_slot = &new_self.blocks[block_index][offset];
266 NS(SLOT, clone_from)(src_slot, dst_slot);
267 }
268 }
269
270 return new_self;
271}
static DC_PUBLIC void * allocate_uninit(SELF *self, size_t size)
Definition template.h:92
#define ALLOC
Definition template.h:31
#define SLOT
Definition template.h:65
#define INVARIANT_CHECK(self)
Definition template.h:90
#define SELF
Definition def.h:52
static DC_PUBLIC dc_gdb_marker dc_gdb_marker_new()
Definition gdb_marker.h:8
static DC_PUBLIC mutation_tracker mutation_tracker_new()
#define NS(pre, post)
Definition namespace.h:14
BLOCK_VECTOR blocks
Definition template.h:46
static DC_INTERNAL void clone_from(SELF const *from_slot, SELF *to_slot)
Definition template.h:94

◆ DC_STATIC_ASSERT() [1/3]

DC_STATIC_ASSERT ( INITIAL_BLOCK_INDEX_BITS ,
0 ,
"INITIAL_BLOCK_INDEX_BITS must be greater than zero"  )

◆ DC_STATIC_ASSERT() [2/3]

DC_STATIC_ASSERT ( )

◆ DC_STATIC_ASSERT() [3/3]

DC_STATIC_ASSERT ( sizeof(VALUE) ,
"VALUE must be a non-zero sized type"  )

◆ DC_TRAIT_ARENA()

DC_TRAIT_ARENA ( SELF )

◆ debug()

DC_PUBLIC void debug ( SELF const * self,
dc_debug_fmt fmt,
FILE * stream )
static

Definition at line 428 of file template.h.

428 {
429 fprintf(stream, DC_EXPAND_STRING(SELF) "@%p {\n", (void*)self);
430 fmt = dc_debug_fmt_scope_begin(fmt);
431 dc_debug_fmt_print(fmt, stream, "count: %lu,\n", self->count);
432
433 if (self->free_list == INDEX_NONE) {
434 dc_debug_fmt_print(fmt, stream, "free_list: INDEX_NONE,\n");
435 } else {
436 dc_debug_fmt_print(fmt, stream, "free_list: %lu,\n", (size_t)self->free_list);
437 }
438
439 dc_debug_fmt_print(fmt, stream, "alloc: ");
440 NS(ALLOC, debug)(NS(NS(ALLOC, ref), deref)(self->alloc_ref), fmt, stream);
441 fprintf(stream, ",\n");
442
443 dc_debug_fmt_print(fmt, stream, "blocks: [\n");
444 fmt = dc_debug_fmt_scope_begin(fmt);
445 for (size_t block = 0; block <= self->block_current; block++) {
446 dc_debug_fmt_print(fmt, stream, "{\n");
447 fmt = dc_debug_fmt_scope_begin(fmt);
448
449 size_t const capacity = DC_ARENA_GEO_BLOCK_TO_SIZE(block, INITIAL_BLOCK_INDEX_BITS);
450 size_t const to_offset =
451 block == self->block_current ? self->block_current_exclusive_end : capacity;
452
453 dc_debug_fmt_print(fmt, stream, "block_index: %lu,\n", block);
454 dc_debug_fmt_print(fmt, stream, "block_ptr: %p,\n", (void*)self->blocks[block]);
455 dc_debug_fmt_print(fmt, stream, "capacity: %lu,\n", capacity);
456 dc_debug_fmt_print(fmt, stream, "size: %lu,\n", to_offset);
457 dc_debug_fmt_print(fmt, stream, "slots: [\n");
458 fmt = dc_debug_fmt_scope_begin(fmt);
459
460 for (size_t offset = 0; offset < to_offset; offset++) {
461 SLOT* slot = &self->blocks[block][offset];
462 dc_debug_fmt_print(fmt, stream, "{\n");
463 fmt = dc_debug_fmt_scope_begin(fmt);
464
465 dc_debug_fmt_print(fmt, stream, "present: %s,\n", slot->present ? "true" : "false");
466 if (slot->present) {
467 dc_debug_fmt_print(fmt, stream, "value: ");
468 VALUE_DEBUG(&slot->value, fmt, stream);
469 fprintf(stream, ",\n");
470 } else {
471 dc_debug_fmt_print(fmt, stream, "next_free: %lu,\n", (size_t)slot->next_free);
472 }
473
474 fmt = dc_debug_fmt_scope_end(fmt);
475 dc_debug_fmt_print(fmt, stream, "},\n");
476 }
477
478 fmt = dc_debug_fmt_scope_end(fmt);
479 dc_debug_fmt_print(fmt, stream, "],\n");
480
481 /* Close the block's scope and print its closing brace */
482 fmt = dc_debug_fmt_scope_end(fmt);
483 dc_debug_fmt_print(fmt, stream, "},\n");
484 }
485
486 fmt = dc_debug_fmt_scope_end(fmt);
487 dc_debug_fmt_print(fmt, stream, "],\n");
488
489 fmt = dc_debug_fmt_scope_end(fmt);
490 dc_debug_fmt_print(fmt, stream, "}");
491}
static DC_PUBLIC void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
Definition template.h:212
#define VALUE_DEBUG
Definition template.h:41
static DC_PUBLIC void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
Definition fmt.h:32
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
Definition fmt.h:57
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
Definition fmt.h:50
#define DC_EXPAND_STRING(NAME)
Definition namespace.h:6
VALUE value
Definition template.h:78
static DC_PUBLIC FILE * stream(SELF *self)
Definition template.h:108

◆ delete()

DC_PUBLIC void delete ( SELF * self)
static

Definition at line 310 of file template.h.

310 {
311 INVARIANT_CHECK(self);
312
313 for (uint8_t block = 0; block <= self->block_current; block++) {
314 size_t const to_offset = block == self->block_current
317
318 for (size_t offset = 0; offset < to_offset; offset++) {
319 SLOT* slot = &self->blocks[block][offset];
320 if (slot->present) {
321 VALUE_DELETE(&slot->value);
322 }
323 }
324
325 size_t block_size =
328 self->blocks[block], block_size);
329 NS(ALLOC, deallocate)(self->alloc_ref, self->blocks[block], block_size);
330 }
331}
static DC_PUBLIC void deallocate(SELF *self, void *ptr, size_t size)
Definition template.h:127
#define VALUE_DELETE
Definition template.h:37
static DC_PUBLIC void dc_memory_tracker_set(dc_memory_tracker_level level, dc_memory_tracker_capability cap, const volatile void *addr, size_t size)
@ DC_MEMORY_TRACKER_LVL_CONTAINER
@ DC_MEMORY_TRACKER_CAP_WRITE
INDEX_TYPE block_current
Definition template.h:82
INDEX_TYPE block_current_exclusive_end
Definition template.h:83
ref alloc_ref
Definition template.h:49

◆ empty() [1/2]

DC_PUBLIC bool empty ( ITER const * iter)
static

Definition at line 551 of file template.h.

551 {
552 DC_ASSUME(iter);
553 mutation_version_check(&iter->version);
554
555 // Scan forward to see if there are any present slots remaining
556 INDEX_TYPE search_index = iter->next_index;
557 while (search_index < MAX_INDEX) {
558 uint8_t block = DC_ARENA_GEO_INDEX_TO_BLOCK(search_index, INITIAL_BLOCK_INDEX_BITS);
559 size_t offset = DC_ARENA_GEO_INDEX_TO_OFFSET(search_index, block, INITIAL_BLOCK_INDEX_BITS);
560
561 // Check if we're past the valid range
562 if ((block == iter->arena->block_current &&
563 offset >= iter->arena->block_current_exclusive_end) ||
564 (block > iter->arena->block_current)) {
565 return true;
566 }
567
568 SLOT* slot = &iter->arena->blocks[block][offset];
569 if (slot->present) {
570 return false;
571 }
572
573 search_index++;
574 }
575
576 return true;
577}
#define DC_ARENA_GEO_INDEX_TO_OFFSET(IDX, BLOCK, INITIAL_BLOCK_INDEX_BITS)
Definition utils.h:9
#define DC_ARENA_GEO_INDEX_TO_BLOCK(IDX, INITIAL_BLOCK_INDEX_BITS)
Definition utils.h:4
static DC_PUBLIC void mutation_version_check(mutation_version const *self)

◆ empty() [2/2]

DC_PUBLIC bool empty ( ITER_CONST const * iter)
static

Definition at line 390 of file template.h.

390 {
391 DC_ASSUME(iter);
392 mutation_version_check(&iter->version);
393
394 // Scan forward to see if there are any present slots remaining
395 INDEX_TYPE search_index = iter->next_index;
396 while (search_index < MAX_INDEX) {
397 uint8_t block = DC_ARENA_GEO_INDEX_TO_BLOCK(search_index, INITIAL_BLOCK_INDEX_BITS);
398 size_t offset = DC_ARENA_GEO_INDEX_TO_OFFSET(search_index, block, INITIAL_BLOCK_INDEX_BITS);
399
400 // Check if we're past the valid range
401 if ((block == iter->arena->block_current &&
402 offset >= iter->arena->block_current_exclusive_end) ||
403 (block > iter->arena->block_current)) {
404 return true;
405 }
406
407 SLOT* slot = &iter->arena->blocks[block][offset];
408 if (slot->present) {
409 return false;
410 }
411
412 search_index++;
413 }
414
415 return true;
416}

◆ empty_item() [1/2]

DC_PUBLIC bool empty_item ( IV_PAIR const * item)
static

Definition at line 512 of file template.h.

512{ return item->value == NULL; }
IV_PAIR item
Definition template.h:281

◆ empty_item() [2/2]

DC_PUBLIC bool empty_item ( IV_PAIR_CONST const * item)
static

Definition at line 349 of file template.h.

349 {
350 return item->value == NULL;
351}

◆ get_iter()

DC_PUBLIC ITER get_iter ( SELF * self)
static

Definition at line 579 of file template.h.

579 {
580 INVARIANT_CHECK(self);
581
582 return (ITER){
583 .arena = self,
584 .next_index = 0,
586 };
587}
#define ITER
Definition template.h:322
static DC_PUBLIC mutation_version mutation_tracker_get(mutation_tracker const *self)
mutation_tracker iterator_invalidation_tracker
Definition template.h:87

◆ get_iter_const()

DC_PUBLIC ITER_CONST get_iter_const ( SELF const * self)
static

Definition at line 418 of file template.h.

418 {
419 INVARIANT_CHECK(self);
420
421 return (ITER_CONST){
422 .arena = self,
423 .next_index = 0,
424 .version = mutation_tracker_get(&self->iterator_invalidation_tracker),
425 };
426}
#define ITER_CONST
Definition template.h:411

◆ insert()

DC_PUBLIC INDEX insert ( SELF * self,
VALUE value )
static

Definition at line 147 of file template.h.

147 {
148 INVARIANT_CHECK(self);
149 DC_ASSERT(self->count < MAX_INDEX,
150 "Arena is full, cannot insert {count=%lu, max_index=%lu, value=%s}",
151 (size_t)self->count, (size_t)MAX_INDEX, DC_DEBUG(VALUE_DEBUG, &value));
152
154
155 if (self->free_list != INDEX_NONE) {
156 INDEX_TYPE free_index = self->free_list;
157
158 uint8_t block = DC_ARENA_GEO_INDEX_TO_BLOCK(free_index, INITIAL_BLOCK_INDEX_BITS);
159 size_t offset = DC_ARENA_GEO_INDEX_TO_OFFSET(free_index, block, INITIAL_BLOCK_INDEX_BITS);
160 SLOT* free_slot = &self->blocks[block][offset];
161
162 DC_ASSUME(!free_slot->present, "The free list should only contain free slots");
163 self->free_list = free_slot->next_free;
164
165 NS(SLOT, fill)(free_slot, value);
166
167 self->count++;
168
169 return (INDEX){.index = free_index};
170 }
171
172 if (self->block_current_exclusive_end ==
174 DC_ASSUME(self->block_current < sizeof(self->blocks) / sizeof(SLOT*));
175
176 self->block_current++;
177 size_t block_items =
179 SLOT* block_slots =
180 (SLOT*)NS(ALLOC, allocate_uninit)(self->alloc_ref, block_items * sizeof(SLOT));
181
182 self->blocks[self->block_current] = block_slots;
184 }
185
186 size_t offset = self->block_current_exclusive_end;
187 NS(SLOT, fill)(&self->blocks[self->block_current][offset], value);
188 INDEX_TYPE new_index = (INDEX_TYPE)(DC_ARENA_GEO_BLOCK_OFFSET_TO_INDEX(
190
192 self->count++;
193
194 return (INDEX){.index = new_index};
195}
#define DC_ARENA_GEO_BLOCK_OFFSET_TO_INDEX(BLOCK, OFFSET, INITIAL_BLOCK_INDEX_BITS)
Definition utils.h:16
#define DC_DEBUG(DEBUG_FN, DEBUG_PTR)
Definition dump.h:92
static DC_PUBLIC void mutation_tracker_mutate(mutation_tracker *self)
#define DC_ASSERT(expr,...)
Definition panic.h:37
INDEX_TYPE free_list
Definition template.h:79
size_t count
Definition template.h:78
static DC_INTERNAL void fill(SELF *slot, SLOT_VALUE value)
Definition template.h:88

◆ iv_const_empty()

DC_PUBLIC IV_PAIR_CONST iv_const_empty ( )
static

Definition at line 339 of file template.h.

339 {
340 return (IV_PAIR_CONST){
341 .index = {.index = INDEX_NONE},
342 .value = NULL,
343 };
344}
#define IV_PAIR_CONST
Definition template.h:412

◆ iv_empty()

DC_PUBLIC IV_PAIR iv_empty ( )
static

Definition at line 502 of file template.h.

502 {
503 return (IV_PAIR){
504 .index = {.index = INDEX_NONE},
505 .value = NULL,
506 };
507}
#define IV_PAIR
Definition template.h:323

◆ new()

DC_PUBLIC SELF new ( ref alloc_ref)
static

Definition at line 123 of file template.h.

123 {
124 uint8_t initial_block = 0;
125 size_t initial_block_items =
127 SLOT* initial_block_slots =
128 (SLOT*)NS(ALLOC, allocate_uninit)(alloc_ref, initial_block_items * sizeof(SLOT));
129
130 SELF self = {
131 .free_list = INDEX_NONE,
132 .count = 0,
133 .alloc_ref = alloc_ref,
134 .derive_c_arena_blocks = dc_gdb_marker_new(),
135 .iterator_invalidation_tracker = mutation_tracker_new(),
136 .block_current_exclusive_end = 0,
137 .block_current = initial_block,
138 .blocks =
139 {
140 initial_block_slots,
141 },
142 };
143
144 return self;
145}

◆ next() [1/2]

DC_PUBLIC IV_PAIR next ( ITER * iter)
static

Definition at line 520 of file template.h.

520 {
521 DC_ASSUME(iter);
523
524 while (iter->next_index < MAX_INDEX) {
526 size_t offset =
528
529 if ((block == iter->arena->block_current &&
530 offset >= iter->arena->block_current_exclusive_end) ||
531 (block > iter->arena->block_current)) {
532 break;
533 }
534
535 SLOT* slot = &iter->arena->blocks[block][offset];
536 if (slot->present) {
537 IV_PAIR result = {
538 .index = (INDEX){.index = iter->next_index},
539 .value = &slot->value,
540 };
541 iter->next_index++;
542 return result;
543 }
544
545 iter->next_index++;
546 }
547
548 return NS(SELF, iv_empty)();
549}
static DC_PUBLIC IV_PAIR iv_empty()
Definition template.h:343
INDEX_TYPE next_index
Definition template.h:327
mutation_version version
Definition template.h:328
SELF * arena
Definition template.h:326

◆ next() [2/2]

DC_PUBLIC IV_PAIR_CONST next ( ITER_CONST * iter)
static

Definition at line 359 of file template.h.

359 {
360 DC_ASSUME(iter);
362
363 while (iter->next_index < MAX_INDEX) {
365 size_t offset =
367
368 if ((block == iter->arena->block_current &&
369 offset >= iter->arena->block_current_exclusive_end) ||
370 (block > iter->arena->block_current)) {
371 break;
372 }
373
374 SLOT* slot = &iter->arena->blocks[block][offset];
375 if (slot->present) {
376 IV_PAIR_CONST const result = {
377 .index = (INDEX){.index = iter->next_index},
378 .value = &slot->value,
379 };
380 iter->next_index++;
381 return result;
382 }
383
384 iter->next_index++;
385 }
386
387 return NS(SELF, iv_const_empty)();
388}
static DC_PUBLIC IV_PAIR_CONST iv_const_empty()
Definition template.h:432
INDEX_TYPE next_index
Definition template.h:416
mutation_version version
Definition template.h:417
SELF const * arena
Definition template.h:415

◆ read()

DC_PUBLIC VALUE const * read ( SELF const * self,
INDEX index )
static

Definition at line 219 of file template.h.

219 {
220 VALUE const* value = NS(SELF, try_read)(self, index);
221 DC_ASSERT(value, "Cannot read item, index not found {index=%lu}", (size_t)index.index);
222 return value;
223}
#define VALUE
Definition template.h:35
static DC_PUBLIC VALUE const * try_read(SELF const *self, INDEX index)
Definition template.h:180

◆ remove()

DC_PUBLIC VALUE remove ( SELF * self,
INDEX index )
static

Definition at line 300 of file template.h.

300 {
301 INVARIANT_CHECK(self);
303
304 VALUE value;
305 DC_ASSERT(NS(SELF, try_remove)(self, index, &value),
306 "Failed to remove item, index not found {index=%lu}", (size_t)index.index);
307 return value;
308}
static DC_PUBLIC bool try_remove(SELF *self, INDEX index, VALUE *destination)
Definition template.h:264

◆ size()

DC_PUBLIC size_t size ( SELF const * self)
static

Definition at line 235 of file template.h.

235 {
236 INVARIANT_CHECK(self);
237 return self->count;
238}

◆ try_read()

DC_PUBLIC VALUE const * try_read ( SELF const * self,
INDEX index )
static

Definition at line 197 of file template.h.

197 {
198 INVARIANT_CHECK(self);
199
200 uint8_t block = DC_ARENA_GEO_INDEX_TO_BLOCK(index.index, INITIAL_BLOCK_INDEX_BITS);
201 if (block > self->block_current) {
202 return NULL;
203 }
204
205 size_t offset = DC_ARENA_GEO_INDEX_TO_OFFSET(index.index, block, INITIAL_BLOCK_INDEX_BITS);
206
207 if (block == self->block_current && offset >= self->block_current_exclusive_end) {
208 return NULL;
209 }
210
211 SLOT* slot = &self->blocks[block][offset];
212 if (!slot->present) {
213 return NULL;
214 }
215
216 return &slot->value;
217}

◆ try_remove()

DC_PUBLIC bool try_remove ( SELF * self,
INDEX index,
VALUE * destination )
static

Definition at line 273 of file template.h.

273 {
274 INVARIANT_CHECK(self);
276
277 uint8_t block = DC_ARENA_GEO_INDEX_TO_BLOCK(index.index, INITIAL_BLOCK_INDEX_BITS);
278 if (block > self->block_current) {
279 return false;
280 }
281
282 size_t offset = DC_ARENA_GEO_INDEX_TO_OFFSET(index.index, block, INITIAL_BLOCK_INDEX_BITS);
283
284 if (block == self->block_current && offset >= self->block_current_exclusive_end) {
285 return false;
286 }
287
288 SLOT* slot = &self->blocks[block][offset];
289 if (slot->present) {
290 *destination = slot->value;
291
292 NS(SLOT, set_empty)(slot, self->free_list);
293 self->free_list = index.index;
294 self->count--;
295 return true;
296 }
297 return false;
298}
static DC_INTERNAL void set_empty(SELF *slot, SLOT_INDEX_TYPE next_free)
Definition template.h:73

◆ try_write()

DC_PUBLIC VALUE * try_write ( SELF * self,
INDEX index )
static

Definition at line 225 of file template.h.

225 {
226 return (VALUE*)NS(SELF, try_read)(self, index);
227}

◆ VALUE_CLONE()

value_t VALUE_CLONE ( value_t const * self)
static

Definition at line 55 of file template.h.

55{ return *self; }

◆ VALUE_DEBUG()

void VALUE_DEBUG ( VALUE const * ,
dc_debug_fmt ,
FILE *  )
static

Definition at line 57 of file template.h.

57{}

◆ VALUE_DELETE()

void VALUE_DELETE ( value_t * )
static

Definition at line 53 of file template.h.

53{}

◆ write()

DC_PUBLIC VALUE * write ( SELF * self,
INDEX index )
static

Definition at line 229 of file template.h.

229 {
230 VALUE* value = NS(SELF, try_write)(self, index);
231 DC_ASSERT(value, "Cannot write item, index not found {index=%lu}", (size_t)index.index);
232 return value;
233}
static DC_PUBLIC VALUE * try_write(SELF *self, INDEX index)
Definition template.h:205

Variable Documentation

◆ max_entries

const size_t max_entries = MAX_INDEX
static

Definition at line 86 of file template.h.