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

Go to the source code of this file.

Data Structures

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

Macros

#define INDEX_BITS   8
#define BLOCK_INDEX_BITS   7
#define VALUE   value_t
#define VALUE_DELETE   value_delete
#define VALUE_CLONE   value_clone
#define VALUE_DEBUG   value_debug
#define SLOT   NS(NAME, slot)
#define SLOT_INDEX_TYPE   INDEX_TYPE
#define SLOT_VALUE   VALUE
#define SLOT_VALUE_CLONE   VALUE_CLONE
#define SLOT_VALUE_CLONE   VALUE_CLONE
#define SLOT_VALUE_DELETE   VALUE_DELETE
#define INTERNAL_NAME   SLOT
#define INVARIANT_CHECK(self)
#define ITER   NS(SELF, iter)
#define IV_PAIR   NS(ITER, item)
#define ITER_INVARIANT_CHECK(iter)
#define ITER_CONST   NS(SELF, iter_const)
#define IV_PAIR_CONST   NS(ITER_CONST, item)
#define ITER_CONST_INVARIANT_CHECK(iter)

Typedefs

typedef VALUE value_t
typedef ALLOC alloc_t
typedef SLOT PRIV(block)[DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS)]

Functions

 DC_STATIC_ASSERT (BLOCK_INDEX_BITS > 0, "Cannot have zero block index bits")
 DC_STATIC_ASSERT (INDEX_BITS > 0, "Cannot have zero index bits")
 DC_STATIC_ASSERT (INDEX_BITS > BLOCK_INDEX_BITS, "The number of bits for offset within a block must be " "less than the number of bits used for an index")
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")
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 SELF clone (SELF const *self)
static DC_PUBLIC size_t size (SELF const *self)
static DC_PUBLIC bool full (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 INDEX_TYPE PRIV next_index_value (SELF const *self, INDEX_TYPE from_index)
static DC_PUBLIC IV_PAIR iv_empty ()
static DC_PUBLIC bool empty_item (IV_PAIR const *item)
static DC_PUBLIC bool empty (ITER const *iter)
static DC_PUBLIC IV_PAIR next (ITER *iter)
static DC_PUBLIC ITER get_iter (SELF *self)
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 bool empty (ITER_CONST const *iter)
static DC_PUBLIC IV_PAIR_CONST next (ITER_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)
 DC_TRAIT_ARENA (SELF)

Variables

static DC_PUBLIC const size_t max_entries = MAX_INDEX

Macro Definition Documentation

◆ BLOCK_INDEX_BITS

#define BLOCK_INDEX_BITS   7

Definition at line 20 of file template.h.

◆ INDEX_BITS

#define INDEX_BITS   8

Definition at line 13 of file template.h.

◆ INTERNAL_NAME

#define INTERNAL_NAME   SLOT

Definition at line 72 of file template.h.

◆ INVARIANT_CHECK

#define INVARIANT_CHECK ( self)
Value:
DC_ASSUME(self); \
DC_ASSUME(((self))->count <= MAX_INDEX); \
DC_ASSUME(((self)->block_current_exclusive_end) <= \
DC_ASSUME(DC_WHEN((self)->free_list == INDEX_NONE, \
(self)->count == \
(DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS) * (self)->block_current + \
(self)->block_current_exclusive_end)), \
"All slots are full if the free list is empty");
#define DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS)
Definition utils.h:12
#define BLOCK_INDEX_BITS
Definition template.h:20
#define DC_WHEN(cond, expr)
Definition panic.h:52
#define DC_ASSUME(expr,...)
Definition panic.h:57

Definition at line 90 of file template.h.

90#define INVARIANT_CHECK(self) \
91 DC_ASSUME(self); \
92 DC_ASSUME(((self))->count <= MAX_INDEX); \
93 DC_ASSUME(((self)->block_current_exclusive_end) <= \
94 DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS)); \
95 DC_ASSUME(DC_WHEN((self)->free_list == INDEX_NONE, \
96 (self)->count == \
97 (DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS) * (self)->block_current + \
98 (self)->block_current_exclusive_end)), \
99 "All slots are full if the free list is empty");

◆ ITER

#define ITER   NS(SELF, iter)

Definition at line 322 of file template.h.

◆ ITER_CONST

#define ITER_CONST   NS(SELF, iter_const)

Definition at line 411 of file template.h.

◆ ITER_CONST_INVARIANT_CHECK

#define ITER_CONST_INVARIANT_CHECK ( iter)
Value:
DC_ASSUME(iter); \
DC_DEBUG_ASSERT( \
DC_WHEN((iter)->next_index != INDEX_NONE, \
NS(SELF, try_read)(iter->arena, (INDEX){.index = (iter)->next_index}) != NULL), \
"The next index is either valid, or the iterator is empty");
static DC_PUBLIC VALUE const * try_read(SELF const *self, INDEX index)
Definition template.h:180
#define SELF
Definition def.h:52
#define NS(pre, post)
Definition namespace.h:14

Definition at line 420 of file template.h.

420#define ITER_CONST_INVARIANT_CHECK(iter) \
421 DC_ASSUME(iter); \
422 DC_DEBUG_ASSERT( \
423 DC_WHEN((iter)->next_index != INDEX_NONE, \
424 NS(SELF, try_read)(iter->arena, (INDEX){.index = (iter)->next_index}) != NULL), \
425 "The next index is either valid, or the iterator is empty");

◆ ITER_INVARIANT_CHECK

#define ITER_INVARIANT_CHECK ( iter)
Value:
DC_ASSUME(iter); \
DC_DEBUG_ASSERT( \
DC_WHEN((iter)->next_index != INDEX_NONE, \
NS(SELF, try_read)(iter->arena, (INDEX){.index = (iter)->next_index}) != NULL), \
"The next index is either valid, or the iterator is empty");

Definition at line 331 of file template.h.

331#define ITER_INVARIANT_CHECK(iter) \
332 DC_ASSUME(iter); \
333 DC_DEBUG_ASSERT( \
334 DC_WHEN((iter)->next_index != INDEX_NONE, \
335 NS(SELF, try_read)(iter->arena, (INDEX){.index = (iter)->next_index}) != NULL), \
336 "The next index is either valid, or the iterator is empty");

◆ IV_PAIR

#define IV_PAIR   NS(ITER, item)

Definition at line 323 of file template.h.

◆ IV_PAIR_CONST

#define IV_PAIR_CONST   NS(ITER_CONST, item)

Definition at line 412 of file template.h.

◆ SLOT

#define SLOT   NS(NAME, slot)

Definition at line 65 of file template.h.

◆ SLOT_INDEX_TYPE

#define SLOT_INDEX_TYPE   INDEX_TYPE

Definition at line 67 of file template.h.

◆ SLOT_VALUE

#define SLOT_VALUE   VALUE

Definition at line 68 of file template.h.

◆ SLOT_VALUE_CLONE [1/2]

#define SLOT_VALUE_CLONE   VALUE_CLONE

Definition at line 69 of file template.h.

◆ SLOT_VALUE_CLONE [2/2]

#define SLOT_VALUE_CLONE   VALUE_CLONE

Definition at line 69 of file template.h.

◆ SLOT_VALUE_DELETE

#define SLOT_VALUE_DELETE   VALUE_DELETE

Definition at line 71 of file template.h.

◆ VALUE

#define VALUE   value_t

Definition at line 33 of file template.h.

◆ VALUE_CLONE

#define VALUE_CLONE   value_clone

Definition at line 39 of file template.h.

◆ VALUE_DEBUG

#define VALUE_DEBUG   value_debug

Definition at line 41 of file template.h.

◆ VALUE_DELETE

#define VALUE_DELETE   value_delete

Definition at line 37 of file template.h.

Typedef Documentation

◆ alloc_t

typedef ALLOC alloc_t

Definition at line 63 of file template.h.

◆ PRIV

Definition at line 75 of file template.h.

◆ value_t

typedef VALUE value_t

Definition at line 62 of file template.h.

Function Documentation

◆ clone()

DC_PUBLIC SELF clone ( SELF const * self)
static

Definition at line 215 of file template.h.

215 {
216 INVARIANT_CHECK(self);
217
218 PRIV(NS(SELF, block))** blocks = (PRIV(NS(SELF, block))**)NS(ALLOC, allocate_uninit)(
219 self->alloc_ref, sizeof(PRIV(NS(SELF, block))*) * (self->block_current + 1));
220
221 for (INDEX_TYPE b = 0; b <= self->block_current; b++) {
222 blocks[b] = (PRIV(NS(SELF, block))*)NS(ALLOC, allocate_uninit)(
223 self->alloc_ref, sizeof(PRIV(NS(SELF, block))));
224 }
225
226 for (INDEX_TYPE b = 0; b < self->block_current; b++) {
227 PRIV(NS(SELF, block))* to_block = blocks[b];
228 PRIV(NS(SELF, block)) const* from_block = self->blocks[b];
229 for (INDEX_TYPE i = 0; i < DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS); i++) {
230 NS(SLOT, clone_from)(&(*from_block)[i], &(*to_block)[i]);
231 }
232 }
233
234 PRIV(NS(SELF, block))* to_current_block = blocks[self->block_current];
235 PRIV(NS(SELF, block)) const* from_current_block = self->blocks[self->block_current];
236 for (INDEX_TYPE i = 0; i < self->block_current_exclusive_end; i++) {
237 NS(SLOT, clone_from)(&(*from_current_block)[i], &(*to_current_block)[i]);
238 }
239
240 return (SELF){
241 .count = self->count,
242 .free_list = self->free_list,
243 .blocks = blocks,
244 .block_current = self->block_current,
245 .block_current_exclusive_end = self->block_current_exclusive_end,
246 .alloc_ref = self->alloc_ref,
247 .derive_c_arena_basic = dc_gdb_marker_new(),
248 .iterator_invalidation_tracker = mutation_tracker_new(),
249 };
250}
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
static DC_PUBLIC dc_gdb_marker dc_gdb_marker_new()
Definition gdb_marker.h:8
static DC_PUBLIC mutation_tracker mutation_tracker_new()
#define PRIV(name)
Definition namespace.h:20
static DC_INTERNAL void clone_from(SELF const *from_slot, SELF *to_slot)
Definition template.h:94

◆ DC_STATIC_ASSERT() [1/4]

DC_STATIC_ASSERT ( BLOCK_INDEX_BITS ,
0 ,
"Cannot have zero block index bits"  )

◆ DC_STATIC_ASSERT() [2/4]

DC_STATIC_ASSERT ( INDEX_BITS ,
0 ,
"Cannot have zero index bits"  )

◆ DC_STATIC_ASSERT() [3/4]

DC_STATIC_ASSERT ( INDEX_BITS ,
BLOCK_INDEX_BITS ,
"The number of bits for offset within a block must be " "less than the number of bits used for an index"  )

◆ DC_STATIC_ASSERT() [4/4]

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 482 of file template.h.

482 {
483 fprintf(stream, DC_EXPAND_STRING(SELF) "@%p {\n", (void*)self);
484 fmt = dc_debug_fmt_scope_begin(fmt);
485 dc_debug_fmt_print(fmt, stream, "count: %lu,\n", self->count);
486 dc_debug_fmt_print(fmt, stream, "free_list: %lu,\n", (size_t)self->free_list);
487
488 dc_debug_fmt_print(fmt, stream, "alloc: ");
489 NS(ALLOC, debug)(NS(NS(ALLOC, ref), deref)(self->alloc_ref), fmt, stream);
490 fprintf(stream, ",\n");
491
492 dc_debug_fmt_print(fmt, stream, "current_block: %lu\n", (size_t)self->block_current);
493 dc_debug_fmt_print(fmt, stream, "block_current_exclusive_end: %lu\n",
494 (size_t)self->block_current_exclusive_end);
495 dc_debug_fmt_print(fmt, stream, "blocks: [\n");
496 fmt = dc_debug_fmt_scope_begin(fmt);
497
498 for (INDEX_TYPE b = 0; b <= self->block_current; b++) {
499
500 dc_debug_fmt_print(fmt, stream, "block[%lu]: @%p [\n", (size_t)b, (void*)self->blocks[b]);
501 fmt = dc_debug_fmt_scope_begin(fmt);
502
503 INDEX_TYPE block_entry_exclusive_end = b == self->block_current
504 ? self->block_current_exclusive_end
506
507 for (INDEX_TYPE i = 0; i < block_entry_exclusive_end; i++) {
508 /* Previously used self->blocks[b][i] which computes wrong address.
509 Use the dereference-then-index form to get the SLOT. */
510 SLOT* entry = &(*self->blocks[b])[i];
511
512 if (entry->present) {
514 fmt, stream, "[index=%lu] ",
516 VALUE_DEBUG(&entry->value, fmt, stream);
517 fprintf(stream, ",\n");
518 } else {
520 fmt, stream, "[index=%lu]{ next_free=%lu }\n",
522 (size_t)entry->next_free);
523 }
524 }
525
526 fmt = dc_debug_fmt_scope_end(fmt);
527 dc_debug_fmt_print(fmt, stream, "],\n");
528 }
529
530 fmt = dc_debug_fmt_scope_end(fmt);
531 dc_debug_fmt_print(fmt, stream, "],\n");
532
533 fmt = dc_debug_fmt_scope_end(fmt);
534 dc_debug_fmt_print(fmt, stream, "}");
535}
static DC_PUBLIC void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
Definition template.h:212
#define DC_ARENA_CHUNKED_BLOCK_OFFSET_TO_INDEX(BLOCK, OFFSET, BLOCK_INDEX_BITS)
Definition utils.h:9
#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 391 of file template.h.

391 {
392 INVARIANT_CHECK(self);
393 ITER iter = NS(SELF, get_iter)(self);
394
395 for (IV_PAIR entry = NS(ITER, next)(&iter); !NS(ITER, empty_item)(&entry);
396 entry = NS(ITER, next)(&iter)) {
397 VALUE_DELETE(entry.value);
398 }
399
400 for (INDEX_TYPE b = 0; b <= self->block_current; b++) {
401 NS(ALLOC, deallocate)(self->alloc_ref, self->blocks[b], sizeof(PRIV(NS(SELF, block))));
402 }
403 NS(ALLOC, deallocate)(self->alloc_ref, (void*)self->blocks,
404 self->block_current * sizeof(PRIV(NS(SELF, block))*));
405}
static DC_PUBLIC void deallocate(SELF *self, void *ptr, size_t size)
Definition template.h:127
#define IV_PAIR
Definition template.h:323
static DC_PUBLIC IV_PAIR next(ITER *iter)
Definition template.h:355
static DC_PUBLIC bool empty_item(IV_PAIR const *item)
Definition template.h:347
#define ITER
Definition template.h:322
static DC_PUBLIC ITER get_iter(SELF *self)
Definition template.h:373
#define VALUE_DELETE
Definition template.h:37
INDEX_TYPE block_current
Definition template.h:82
BLOCK_VECTOR blocks
Definition template.h:46
ref alloc_ref
Definition template.h:49

◆ empty() [1/2]

DC_PUBLIC bool empty ( ITER const * iter)
static

Definition at line 349 of file template.h.

349 {
351 mutation_version_check(&iter->version);
352 return iter->next_index == INDEX_NONE;
353}
#define ITER_INVARIANT_CHECK(iter)
Definition template.h:331
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 440 of file template.h.

440 {
442 mutation_version_check(&iter->version);
443 return iter->next_index == INDEX_NONE;
444}
#define ITER_CONST_INVARIANT_CHECK(iter)
Definition template.h:420

◆ empty_item() [1/2]

DC_PUBLIC bool empty_item ( IV_PAIR const * item)
static

Definition at line 347 of file template.h.

347{ 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 436 of file template.h.

436 {
437 return item->value == NULL;
438}

◆ full()

DC_PUBLIC bool full ( SELF const * self)
static

Definition at line 257 of file template.h.

257 {
258 INVARIANT_CHECK(self);
259 return self->count < MAX_INDEX;
260}

◆ get_iter()

DC_PUBLIC ITER get_iter ( SELF * self)
static

Definition at line 373 of file template.h.

373 {
374 INVARIANT_CHECK(self);
375
376 // Check if index 0 is present, otherwise find the next valid index
377 INDEX_TYPE first_index;
378 if (self->block_current_exclusive_end > 0 && (*self->blocks[0])[0].present) {
379 first_index = 0;
380 } else {
381 first_index = PRIV(NS(SELF, next_index_value))(self, 0);
382 }
383
384 return (ITER){
385 .arena = self,
386 .next_index = first_index,
388 };
389}
static DC_PUBLIC INDEX_TYPE PRIV next_index_value(SELF const *self, INDEX_TYPE from_index)
Definition template.h:302
static DC_PUBLIC mutation_version mutation_tracker_get(mutation_tracker const *self)
mutation_tracker iterator_invalidation_tracker
Definition template.h:87
INDEX_TYPE block_current_exclusive_end
Definition template.h:83

◆ get_iter_const()

DC_PUBLIC ITER_CONST get_iter_const ( SELF const * self)
static

Definition at line 464 of file template.h.

464 {
465 INVARIANT_CHECK(self);
466
467 // Check if index 0 is present, otherwise find the next valid index
468 INDEX_TYPE first_index;
469 if (self->block_current_exclusive_end > 0 && (*self->blocks[0])[0].present) {
470 first_index = 0;
471 } else {
472 first_index = PRIV(NS(SELF, next_index_value))(self, 0);
473 }
474
475 return (ITER_CONST){
476 .arena = self,
477 .next_index = first_index,
478 .version = mutation_tracker_get(&self->iterator_invalidation_tracker),
479 };
480}
#define ITER_CONST
Definition template.h:411

◆ insert()

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

Definition at line 126 of file template.h.

126 {
127 INVARIANT_CHECK(self);
129 DC_ASSERT(self->count < MAX_INDEX,
130 "Arena is full, cannot insert {count=%lu, max_index=%lu, value=%s}",
131 (size_t)self->count, (size_t)MAX_INDEX, DC_DEBUG(VALUE_DEBUG, &value));
132
133 if (self->free_list != INDEX_NONE) {
134 INDEX_TYPE free_index = self->free_list;
135 INDEX_TYPE block = DC_ARENA_CHUNKED_INDEX_TO_BLOCK(free_index, BLOCK_INDEX_BITS);
136 INDEX_TYPE offset = DC_ARENA_CHUNKED_INDEX_TO_OFFSET(free_index, BLOCK_INDEX_BITS);
137
138 SLOT* slot = &(*self->blocks[block])[offset];
139
140 DC_ASSUME(!slot->present);
141 self->free_list = slot->next_free;
142
143 NS(SLOT, fill)(slot, value);
144
145 self->count++;
146 return (INDEX){.index = free_index};
147 }
148
150 self->block_current++;
152
153 size_t blocks_current_size = self->block_current * sizeof(PRIV(NS(SELF, block))*);
154 size_t blocks_new_size = blocks_current_size + sizeof(PRIV(NS(SELF, block))*);
155
156 self->blocks = (PRIV(NS(SELF, block))**)NS(ALLOC, reallocate)(
157 self->alloc_ref, (void*)self->blocks, blocks_current_size, blocks_new_size);
158
159 PRIV(NS(SELF, block))* new_block = (PRIV(NS(SELF, block))*)NS(ALLOC, allocate_uninit)(
160 self->alloc_ref, sizeof(PRIV(NS(SELF, block))));
161
162 self->blocks[self->block_current] = new_block;
163
164 for (size_t offset = 0; offset < DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS); offset++) {
165 NS(SLOT, memory_tracker_empty)(&(*new_block)[offset]);
166 }
167 }
168
169 SLOT* slot = &(*self->blocks[self->block_current])[self->block_current_exclusive_end];
170 NS(SLOT, fill)(slot, value);
171
172 INDEX_TYPE index = (INDEX_TYPE)DC_ARENA_CHUNKED_BLOCK_OFFSET_TO_INDEX(
174 self->count++;
176
177 return (INDEX){.index = index};
178}
static DC_PUBLIC void * reallocate(SELF *self, void *ptr, size_t old_size, size_t new_size)
Definition template.h:137
#define DC_ARENA_CHUNKED_INDEX_TO_OFFSET(INDEX, BLOCK_INDEX_BITS)
Definition utils.h:6
#define DC_ARENA_CHUNKED_INDEX_TO_BLOCK(INDEX, BLOCK_INDEX_BITS)
Definition utils.h:4
#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
static DC_INTERNAL void memory_tracker_empty(SELF const *slot)
Definition template.h:64

◆ iv_const_empty()

DC_PUBLIC IV_PAIR_CONST iv_const_empty ( )
static

Definition at line 432 of file template.h.

432 {
433 return (IV_PAIR_CONST){.index = (INDEX){.index = INDEX_NONE}, .value = NULL};
434}
#define IV_PAIR_CONST
Definition template.h:412

◆ iv_empty()

DC_PUBLIC IV_PAIR iv_empty ( )
static

Definition at line 343 of file template.h.

343 {
344 return (IV_PAIR){.index = (INDEX){.index = INDEX_NONE}, .value = NULL};
345}

◆ new()

DC_PUBLIC SELF new ( ref alloc_ref)
static

Definition at line 101 of file template.h.

101 {
102 PRIV(NS(SELF, block))* first_block = (PRIV(NS(SELF, block))*)NS(ALLOC, allocate_uninit)(
103 alloc_ref, sizeof(PRIV(NS(SELF, block))));
104 PRIV(NS(SELF, block))** blocks = (PRIV(NS(SELF, block))**)NS(ALLOC, allocate_uninit)(
105 alloc_ref, sizeof(PRIV(NS(SELF, block))*));
106
107 blocks[0] = first_block;
108
109 for (INDEX_TYPE offset = 0; offset < DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS); offset++) {
110 /* Properly index the slots within the allocated block */
111 NS(SLOT, memory_tracker_empty)(&(*first_block)[offset]);
112 }
113
114 return (SELF){
115 .count = 0,
116 .free_list = INDEX_NONE,
117 .blocks = blocks,
118 .block_current = 0,
119 .block_current_exclusive_end = 0,
120 .alloc_ref = alloc_ref,
121 .derive_c_arena_basic = dc_gdb_marker_new(),
122 .iterator_invalidation_tracker = mutation_tracker_new(),
123 };
124}

◆ next() [1/2]

DC_PUBLIC IV_PAIR next ( ITER * iter)
static

Definition at line 355 of file template.h.

355 {
358
359 if (iter->next_index == INDEX_NONE) {
360 return NS(SELF, iv_empty)();
361 }
362
363 INDEX index = {.index = iter->next_index};
364 IV_PAIR result = (IV_PAIR){
365 .index = index,
366 .value = NS(SELF, write)(iter->arena, index),
367 };
368
369 iter->next_index = PRIV(NS(SELF, next_index_value))(iter->arena, iter->next_index);
370 return result;
371}
static DC_PUBLIC IV_PAIR iv_empty()
Definition template.h:343
static DC_PUBLIC VALUE * write(SELF *self, INDEX index)
Definition template.h:209
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 446 of file template.h.

446 {
449
450 if (iter->next_index == INDEX_NONE) {
451 return NS(SELF, iv_const_empty)();
452 }
453
454 INDEX index = {.index = iter->next_index};
455 IV_PAIR_CONST result = (IV_PAIR_CONST){
456 .index = index,
457 .value = NS(SELF, read)(iter->arena, index),
458 };
459
460 iter->next_index = PRIV(NS(SELF, next_index_value))(iter->arena, iter->next_index);
461 return result;
462}
static DC_PUBLIC VALUE const * read(SELF const *self, INDEX index)
Definition template.h:199
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

◆ next_index_value()

DC_PUBLIC INDEX_TYPE PRIV next_index_value ( SELF const * self,
INDEX_TYPE from_index )
static

Definition at line 302 of file template.h.

303 {
304 for (INDEX_TYPE next_index = from_index + 1;; next_index++) {
305 INDEX_TYPE block = DC_ARENA_CHUNKED_INDEX_TO_BLOCK(next_index, BLOCK_INDEX_BITS);
306 INDEX_TYPE offset = DC_ARENA_CHUNKED_INDEX_TO_OFFSET(next_index, BLOCK_INDEX_BITS);
307
308 if (block > self->block_current ||
309 (block == self->block_current && offset >= self->block_current_exclusive_end)) {
310 return INDEX_NONE;
311 }
312
313 /* Fix wrong indexing: use &(*self->blocks[block])[offset] rather than
314 self->blocks[block][offset] which indexes by block-sized strides. */
315 SLOT* slot = &(*self->blocks[block])[offset];
316 if (slot->present) {
317 return next_index;
318 }
319 }
320}

◆ read()

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

Definition at line 199 of file template.h.

199 {
200 VALUE const* value = NS(SELF, try_read)(self, index);
201 DC_ASSERT(value, "Cannot read item {index=%lu}", (size_t)index.index);
202 return value;
203}
#define VALUE
Definition template.h:35

◆ remove()

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

Definition at line 292 of file template.h.

292 {
293 INVARIANT_CHECK(self);
295
296 VALUE value;
297 DC_ASSERT(NS(SELF, try_remove)(self, index, &value),
298 "Failed to remove item, index not found {index=%lu}", (size_t)index.index);
299 return value;
300}
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
Examples
complex/prime_sieve.c.

Definition at line 252 of file template.h.

252 {
253 INVARIANT_CHECK(self);
254 return self->count;
255}

◆ try_read()

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

Definition at line 180 of file template.h.

180 {
181 INVARIANT_CHECK(self);
182
183 INDEX_TYPE block = DC_ARENA_CHUNKED_INDEX_TO_BLOCK(index.index, BLOCK_INDEX_BITS);
184 INDEX_TYPE offset = DC_ARENA_CHUNKED_INDEX_TO_OFFSET(index.index, BLOCK_INDEX_BITS);
185
186 if (block > self->block_current ||
187 (block == self->block_current && offset >= self->block_current_exclusive_end)) {
188 return NULL;
189 }
190
191 SLOT* slot = &(*self->blocks[block])[offset];
192
193 if (!slot->present) {
194 return NULL;
195 }
196 return &slot->value;
197}

◆ try_remove()

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

Definition at line 264 of file template.h.

264 {
265 INVARIANT_CHECK(self);
267
268 INDEX_TYPE block = DC_ARENA_CHUNKED_INDEX_TO_BLOCK(index.index, BLOCK_INDEX_BITS);
269 INDEX_TYPE offset = DC_ARENA_CHUNKED_INDEX_TO_OFFSET(index.index, BLOCK_INDEX_BITS);
270
271 /* Only treat offset vs block_current_exclusive_end for the last block */
272 if (block > self->block_current ||
273 (block == self->block_current && offset >= self->block_current_exclusive_end)) {
274 return false;
275 }
276
277 PRIV(NS(SELF, block))* current_block = self->blocks[block];
278 SLOT* entry = &(*current_block)[offset];
279
280 if (entry->present) {
281 *destination = entry->value;
282
283 NS(SLOT, set_empty)(entry, self->free_list);
284
285 self->free_list = index.index;
286 self->count--;
287 return true;
288 }
289 return false;
290}
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 205 of file template.h.

205 {
206 return (VALUE*)NS(SELF, try_read)(self, index);
207}

◆ VALUE_CLONE()

value_t VALUE_CLONE ( value_t const * self)
static

Definition at line 40 of file template.h.

40{ return *self; }

◆ VALUE_DEBUG()

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

Definition at line 42 of file template.h.

42{}

◆ VALUE_DELETE()

void VALUE_DELETE ( value_t * )
static

Definition at line 38 of file template.h.

38{}

◆ write()

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

Definition at line 209 of file template.h.

209 {
210 VALUE* value = NS(SELF, try_write)(self, index);
211 DC_ASSERT(value, "Cannot write item {index=%lu}", (size_t)index.index);
212 return value;
213}
static DC_PUBLIC VALUE * try_write(SELF *self, INDEX index)
Definition template.h:205

Variable Documentation

◆ max_entries

DC_PUBLIC const size_t max_entries = MAX_INDEX
static

Definition at line 262 of file template.h.