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   32
#define BLOCK_INDEX_BITS   8
#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 (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 *self)
static value_t VALUE_CLONE (value_t const *self)
static void VALUE_DEBUG (VALUE const *, dc_debug_fmt, FILE *stream)
 DC_STATIC_ASSERT (sizeof(VALUE), "VALUE must be a non-zero sized type")
static SELF new (ALLOC *alloc)
static INDEX insert (SELF *self, VALUE value)
static VALUE const * try_read (SELF const *self, INDEX index)
static VALUE const * read (SELF const *self, INDEX index)
static VALUEtry_write (SELF *self, INDEX index)
static VALUEwrite (SELF *self, INDEX index)
static SELF clone (SELF const *self)
static INDEX_TYPE size (SELF const *self)
static bool full (SELF const *self)
static bool try_remove (SELF *self, INDEX index, VALUE *destination)
static VALUE remove (SELF *self, INDEX index)
static INDEX_TYPE PRIV next_index_value (SELF const *self, INDEX_TYPE from_index)
static IV_PAIR iv_empty ()
static bool empty_item (IV_PAIR const *item)
static bool empty (ITER const *iter)
static IV_PAIR next (ITER *iter)
static ITER get_iter (SELF *self)
static void delete (SELF *self)
static IV_PAIR_CONST iv_const_empty ()
static bool empty_item (IV_PAIR_CONST const *item)
static bool empty (ITER_CONST const *iter)
static IV_PAIR_CONST next (ITER_CONST *iter)
static ITER_CONST get_iter_const (SELF const *self)
static void debug (SELF const *self, dc_debug_fmt fmt, FILE *stream)
 DC_TRAIT_ARENA (SELF)

Variables

static const size_t max_entries = MAX_INDEX

Macro Definition Documentation

◆ BLOCK_INDEX_BITS

#define BLOCK_INDEX_BITS   8

Definition at line 20 of file template.h.

◆ INDEX_BITS

#define INDEX_BITS   32

Definition at line 13 of file template.h.

◆ INTERNAL_NAME

#define INTERNAL_NAME   SLOT

Definition at line 70 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:51
#define DC_ASSUME(expr,...)
Definition panic.h:56

Definition at line 88 of file template.h.

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

◆ ITER

#define ITER   NS(SELF, iter)

Definition at line 320 of file template.h.

◆ ITER_CONST

#define ITER_CONST   NS(SELF, iter_const)

Definition at line 398 of file template.h.

◆ ITER_CONST_INVARIANT_CHECK

#define ITER_CONST_INVARIANT_CHECK ( iter)
Value:
DC_ASSUME(iter); \
DC_ASSUME( \
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 VALUE const * try_read(SELF const *self, INDEX index)
Definition template.h:180
#define NS(pre, post)
Definition namespace.h:4
#define SELF
Definition def.h:52

Definition at line 407 of file template.h.

407#define ITER_CONST_INVARIANT_CHECK(iter) \
408 DC_ASSUME(iter); \
409 DC_ASSUME( \
410 DC_WHEN((iter)->next_index != INDEX_NONE, \
411 NS(SELF, try_read)(iter->arena, (INDEX){.index = (iter)->next_index}) != NULL), \
412 "The next index is either valid, or the iterator is empty");

◆ ITER_INVARIANT_CHECK

#define ITER_INVARIANT_CHECK ( iter)
Value:
DC_ASSUME(iter); \
DC_ASSUME( \
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 329 of file template.h.

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

◆ IV_PAIR

#define IV_PAIR   NS(ITER, item)

Definition at line 321 of file template.h.

◆ IV_PAIR_CONST

#define IV_PAIR_CONST   NS(ITER_CONST, item)

Definition at line 399 of file template.h.

◆ SLOT

#define SLOT   NS(NAME, slot)

Definition at line 63 of file template.h.

◆ SLOT_INDEX_TYPE

#define SLOT_INDEX_TYPE   INDEX_TYPE

Definition at line 65 of file template.h.

◆ SLOT_VALUE

#define SLOT_VALUE   VALUE

Definition at line 66 of file template.h.

◆ SLOT_VALUE_CLONE [1/2]

#define SLOT_VALUE_CLONE   VALUE_CLONE

Definition at line 67 of file template.h.

◆ SLOT_VALUE_CLONE [2/2]

#define SLOT_VALUE_CLONE   VALUE_CLONE

Definition at line 67 of file template.h.

◆ SLOT_VALUE_DELETE

#define SLOT_VALUE_DELETE   VALUE_DELETE

Definition at line 69 of file template.h.

◆ VALUE

#define VALUE   value_t

Definition at line 31 of file template.h.

◆ VALUE_CLONE

#define VALUE_CLONE   value_clone

Definition at line 37 of file template.h.

◆ VALUE_DEBUG

#define VALUE_DEBUG   value_debug

Definition at line 39 of file template.h.

◆ VALUE_DELETE

#define VALUE_DELETE   value_delete

Definition at line 35 of file template.h.

Typedef Documentation

◆ alloc_t

typedef ALLOC alloc_t

Definition at line 61 of file template.h.

◆ PRIV

Definition at line 73 of file template.h.

◆ value_t

typedef VALUE value_t

Definition at line 60 of file template.h.

Function Documentation

◆ clone()

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, malloc)(
219 self->alloc, sizeof(PRIV(NS(SELF, block))*) * (self->block_current + 1));
220
221 for (INDEX_TYPE b = 0; b <= self->block_current; b++) {
222 blocks[b] =
223 (PRIV(NS(SELF, block))*)NS(ALLOC, malloc)(self->alloc, 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];
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 = self->alloc,
247 .derive_c_arena_basic = dc_gdb_marker_new(),
248 .iterator_invalidation_tracker = mutation_tracker_new(),
249 };
250}
static void * malloc(SELF *self, size_t size)
Definition template.h:23
#define ALLOC
Definition template.h:64
#define SLOT
Definition template.h:63
#define INVARIANT_CHECK(self)
Definition template.h:88
SLOT PRIV(block)[DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS)]
Definition template.h:73
#define INDEX_TYPE
Definition template.h:74
static dc_gdb_marker dc_gdb_marker_new()
Definition gdb_marker.h:7
static mutation_tracker mutation_tracker_new()
static void clone_from(SELF const *from_slot, SELF *to_slot)
Definition template.h:83

◆ DC_STATIC_ASSERT() [1/2]

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() [2/2]

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

◆ DC_TRAIT_ARENA()

DC_TRAIT_ARENA ( SELF )

◆ debug()

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

Definition at line 458 of file template.h.

458 {
459 fprintf(stream, EXPAND_STRING(SELF) "@%p {\n", self);
460 fmt = dc_debug_fmt_scope_begin(fmt);
461 dc_debug_fmt_print(fmt, stream, "count: %lu,\n", self->count);
462 dc_debug_fmt_print(fmt, stream, "free_list: %lu,\n", (size_t)self->free_list);
463
464 dc_debug_fmt_print(fmt, stream, "alloc: ");
465 NS(ALLOC, debug)(self->alloc, fmt, stream);
466 fprintf(stream, ",\n");
467
468 dc_debug_fmt_print(fmt, stream, "current_block: %lu\n", (size_t)self->block_current);
469 dc_debug_fmt_print(fmt, stream, "block_current_exclusive_end: %lu\n",
470 (size_t)self->block_current_exclusive_end);
471 dc_debug_fmt_print(fmt, stream, "blocks: [");
472 fmt = dc_debug_fmt_scope_begin(fmt);
473
474 for (INDEX_TYPE b = 0; b <= self->block_current; b++) {
475
476 dc_debug_fmt_print(fmt, stream, "block[%lu]: @%p [", (size_t)b, self->blocks[b]);
477 fmt = dc_debug_fmt_scope_begin(fmt);
478
479 INDEX_TYPE block_entry_exclusive_end = b == self->block_current
480 ? self->block_current_exclusive_end
482
483 for (INDEX_TYPE i = 0; i < block_entry_exclusive_end; i++) {
484 /* Previously used self->blocks[b][i] which computes wrong address.
485 Use the dereference-then-index form to get the SLOT. */
486 SLOT* entry = &(*self->blocks[b])[i];
487
488 if (entry->present) {
490 fmt, stream, "[index=%lu]{\n",
492 fmt = dc_debug_fmt_scope_begin(fmt);
493 VALUE_DEBUG(&entry->value, fmt, stream);
494 fprintf(stream, ",\n");
495 fmt = dc_debug_fmt_scope_end(fmt);
496 dc_debug_fmt_print(fmt, stream, "},\n");
497 } else {
499 fmt, stream, "[index=%lu]{ next_free=%lu }\n",
501 (size_t)entry->next_free);
502 }
503 }
504
505 fmt = dc_debug_fmt_scope_end(fmt);
506 dc_debug_fmt_print(fmt, stream, "],\n");
507 }
508
509 fmt = dc_debug_fmt_scope_end(fmt);
510 dc_debug_fmt_print(fmt, stream, "],\n");
511
512 fmt = dc_debug_fmt_scope_end(fmt);
513 dc_debug_fmt_print(fmt, stream, "}");
514}
static void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
Definition template.h:62
#define DC_ARENA_CHUNKED_BLOCK_OFFSET_TO_INDEX(BLOCK, OFFSET, BLOCK_INDEX_BITS)
Definition utils.h:9
#define VALUE_DEBUG
Definition template.h:39
dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
Definition fmt.h:39
dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
Definition fmt.h:33
static void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
Definition fmt.h:22
#define EXPAND_STRING(NAME)
Definition namespace.h:8
VALUE value
Definition template.h:78
static FILE * stream(SELF *self)
Opens a file for.
Definition template.h:107

◆ delete()

void delete ( SELF * self)
static

Definition at line 379 of file template.h.

379 {
380 INVARIANT_CHECK(self);
381 ITER iter = NS(SELF, get_iter)(self);
382
383 for (IV_PAIR entry = NS(ITER, next)(&iter); !NS(ITER, empty_item)(&entry);
384 entry = NS(ITER, next)(&iter)) {
385 VALUE_DELETE(entry.value);
386 }
387
388 for (INDEX_TYPE b = 0; b <= self->block_current; b++) {
389 NS(ALLOC, free)(self->alloc, self->blocks[b]);
390 }
391 NS(ALLOC, free)(self->alloc, (void*)self->blocks);
392}
static void free(SELF *self, void *ptr)
Definition template.h:56
static ITER get_iter(SELF *self)
Definition template.h:370
static IV_PAIR next(ITER *iter)
Definition template.h:352
#define IV_PAIR
Definition template.h:321
static bool empty_item(IV_PAIR const *item)
Definition template.h:344
#define ITER
Definition template.h:320
#define VALUE_DELETE
Definition template.h:35
INDEX_TYPE block_current
Definition template.h:80
SLOT * blocks[DC_ARENA_GEO_MAX_NUM_BLOCKS(INDEX_BITS, INITIAL_BLOCK_INDEX_BITS)]
Definition template.h:116
ALLOC * alloc
Definition template.h:71

◆ empty() [1/2]

bool empty ( ITER const * iter)
static

Definition at line 346 of file template.h.

346 {
348 mutation_version_check(&iter->version);
349 return iter->next_index == INDEX_NONE;
350}
#define ITER_INVARIANT_CHECK(iter)
Definition template.h:329
static void mutation_version_check(mutation_version const *self)

◆ empty() [2/2]

bool empty ( ITER_CONST const * iter)
static

Definition at line 425 of file template.h.

425 {
427 mutation_version_check(&iter->version);
428 return iter->next_index == INDEX_NONE;
429}
#define ITER_CONST_INVARIANT_CHECK(iter)
Definition template.h:407

◆ empty_item() [1/2]

bool empty_item ( IV_PAIR const * item)
static

Definition at line 344 of file template.h.

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

◆ empty_item() [2/2]

bool empty_item ( IV_PAIR_CONST const * item)
static

Definition at line 423 of file template.h.

423{ return item->value == NULL; }

◆ full()

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()

ITER get_iter ( SELF * self)
static

Definition at line 370 of file template.h.

370 {
371 INVARIANT_CHECK(self);
372 return (ITER){
373 .arena = self,
374 .next_index = PRIV(NS(SELF, next_index_value))(self, 0),
376 };
377}
static INDEX_TYPE PRIV next_index_value(SELF const *self, INDEX_TYPE from_index)
Definition template.h:301
static mutation_version mutation_tracker_get(mutation_tracker const *self)
mutation_tracker iterator_invalidation_tracker
Definition template.h:85

◆ get_iter_const()

ITER_CONST get_iter_const ( SELF const * self)
static

Definition at line 449 of file template.h.

449 {
450 INVARIANT_CHECK(self);
451 return (ITER_CONST){
452 .arena = self,
453 .next_index = PRIV(NS(SELF, next_index_value))(self, 0),
454 .version = mutation_tracker_get(&self->iterator_invalidation_tracker),
455 };
456}
#define ITER_CONST
Definition template.h:398

◆ insert()

INDEX insert ( SELF * self,
VALUE value )
static

Definition at line 127 of file template.h.

127 {
128 INVARIANT_CHECK(self);
130 DC_ASSERT(self->count < MAX_INDEX);
131
132 if (self->free_list != INDEX_NONE) {
133 INDEX_TYPE free_index = self->free_list;
136
137 SLOT* slot = &(*self->blocks[block])[offset];
138
139 DC_ASSUME(!slot->present);
140 self->free_list = slot->next_free;
141 slot->present = true;
143 slot->value = value;
144 self->count++;
145 return (INDEX){.index = free_index};
146 }
147
149 self->block_current++;
151
152 self->blocks = (PRIV(NS(SELF, block))**)NS(ALLOC, realloc)(
153 self->alloc, (void*)self->blocks,
154 (self->block_current + 1) * sizeof(PRIV(NS(SELF, block))*));
155 DC_ASSERT(self->blocks);
156
157 PRIV(NS(SELF, block))* new_block =
158 (PRIV(NS(SELF, block))*)NS(ALLOC, malloc)(self->alloc, sizeof(PRIV(NS(SELF, block))));
159
160 self->blocks[self->block_current] = new_block;
161
162 for (size_t offset = 0; offset < DC_ARENA_CHUNKED_BLOCK_SIZE(BLOCK_INDEX_BITS); offset++) {
163 NS(SLOT, memory_tracker_empty)(&(*new_block)[offset]);
164 }
165 }
166
167 SLOT* slot = &(*self->blocks[self->block_current])[self->block_current_exclusive_end];
168 slot->present = true;
170 slot->value = value;
171
174 self->count++;
176
177 return (INDEX){.index = index};
178}
static void * realloc(SELF *self, void *ptr, size_t size)
Definition template.h:45
#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
static void mutation_tracker_mutate(mutation_tracker *self)
#define PRIV(name)
Definition namespace.h:6
#define DC_ASSERT(expr,...)
Definition panic.h:36
INDEX_TYPE block_current_exclusive_end
Definition template.h:81
INDEX_TYPE free_list
Definition template.h:77
size_t count
Definition template.h:76
static void memory_tracker_present(SELF const *slot)
Definition template.h:68
static void memory_tracker_empty(SELF const *slot)
Definition template.h:53

◆ iv_const_empty()

IV_PAIR_CONST iv_const_empty ( )
static

Definition at line 419 of file template.h.

419 {
420 return (IV_PAIR_CONST){.index = (INDEX){.index = INDEX_NONE}, .value = NULL};
421}
#define IV_PAIR_CONST
Definition template.h:399

◆ iv_empty()

IV_PAIR iv_empty ( )
static

Definition at line 341 of file template.h.

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

◆ new()

SELF new ( ALLOC * alloc)
static

Definition at line 99 of file template.h.

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

◆ next() [1/2]

IV_PAIR next ( ITER * iter)
static

Definition at line 352 of file template.h.

352 {
355
356 if (iter->next_index == INDEX_NONE) {
357 return NS(SELF, iv_empty)();
358 }
359
360 INDEX index = {.index = iter->next_index};
361 IV_PAIR result = (IV_PAIR){
362 .index = index,
363 .value = NS(SELF, write)(iter->arena, index),
364 };
365
366 iter->next_index = PRIV(NS(SELF, next_index_value))(iter->arena, iter->next_index);
367 return result;
368}
static VALUE * write(SELF *self, INDEX index)
Definition template.h:209
static IV_PAIR iv_empty()
Definition template.h:341
INDEX_TYPE next_index
Definition template.h:325
mutation_version version
Definition template.h:326
SELF * arena
Definition template.h:324

◆ next() [2/2]

IV_PAIR_CONST next ( ITER_CONST * iter)
static

Definition at line 431 of file template.h.

431 {
434
435 if (iter->next_index == INDEX_NONE) {
436 return NS(SELF, iv_const_empty)();
437 }
438
439 INDEX index = {.index = iter->next_index};
440 IV_PAIR_CONST result = (IV_PAIR_CONST){
441 .index = index,
442 .value = NS(SELF, read)(iter->arena, index),
443 };
444
445 iter->next_index = PRIV(NS(SELF, next_index_value))(iter->arena, iter->next_index);
446 return result;
447}
static IV_PAIR_CONST iv_const_empty()
Definition template.h:419
static VALUE const * read(SELF const *self, INDEX index)
Definition template.h:199
INDEX_TYPE next_index
Definition template.h:403
mutation_version version
Definition template.h:404
SELF const * arena
Definition template.h:402

◆ next_index_value()

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

Definition at line 301 of file template.h.

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

◆ read()

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);
202 return value;
203}
#define VALUE
Definition template.h:31

◆ remove()

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 return value;
299}
static bool try_remove(SELF *self, INDEX index, VALUE *destination)
Definition template.h:264

◆ size()

INDEX_TYPE 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()

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

Definition at line 180 of file template.h.

180 {
181 INVARIANT_CHECK(self);
182
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()

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

Definition at line 264 of file template.h.

264 {
265 INVARIANT_CHECK(self);
267
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 entry->present = false;
284 entry->next_free = self->free_list;
285 self->free_list = index.index;
286 self->count--;
287 return true;
288 }
289 return false;
290}

◆ try_write()

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

◆ VALUE_DEBUG()

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

◆ VALUE_DELETE()

void VALUE_DELETE ( value_t * self)
static

◆ write()

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);
212 return value;
213}
static 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 262 of file template.h.