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_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 *self)
static value_t VALUE_CLONE (value_t const *self)
static void VALUE_DEBUG (VALUE const *self, dc_debug_fmt fmt, FILE *stream)
 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 void PRIV set_memory_tracking (SELF const *self)
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 INDEX_TYPE size (SELF const *self)
static SELF clone (SELF const *self)
static bool try_remove (SELF *self, INDEX index, VALUE *destination)
static VALUE remove (SELF *self, INDEX index)
static void delete (SELF *self)
static IV_PAIR_CONST iv_const_empty ()
static bool empty_item (IV_PAIR_CONST const *item)
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)
static IV_PAIR iv_empty ()
static bool empty_item (IV_PAIR const *item)
static IV_PAIR next (ITER *iter)
static 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 98 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:56

Definition at line 142 of file template.h.

142#define INVARIANT_CHECK(self) \
143 DC_ASSUME(self); \
144 DC_ASSUME(DC_ARENA_GEO_BLOCK_TO_SIZE((self)->block_current, INITIAL_BLOCK_INDEX_BITS) >= \
145 (self)->block_current_exclusive_end); \
146 DC_ASSUME((self)->count <= MAX_INDEX);

◆ ITER

#define ITER   NS(SELF, iter)

Definition at line 510 of file template.h.

◆ ITER_CONST

#define ITER_CONST   NS(SELF, iter_const)

Definition at line 377 of file template.h.

◆ IV_PAIR

#define IV_PAIR   NS(SELF, iv)

Definition at line 497 of file template.h.

◆ IV_PAIR_CONST

#define IV_PAIR_CONST   NS(SELF, iv_const)

Definition at line 364 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 [1/2]

#define SLOT_VALUE_CLONE   VALUE_CLONE

Definition at line 95 of file template.h.

◆ SLOT_VALUE_CLONE [2/2]

#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 97 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 378 of file template.h.

Function Documentation

◆ clone()

SELF clone ( SELF const * self)
static

Definition at line 264 of file template.h.

264 {
265 INVARIANT_CHECK(self);
266
267 SELF new_self = {
268 .free_list = self->free_list,
269 .count = self->count,
270 .alloc = self->alloc,
271 .derive_c_arena_blocks = dc_gdb_marker_new(),
272 .iterator_invalidation_tracker = mutation_tracker_new(),
273 .block_current_exclusive_end = self->block_current_exclusive_end,
274 .block_current = self->block_current,
275 .blocks = {},
276 };
277
278 for (size_t block_index = 0; block_index <= self->block_current; block_index++) {
279 size_t block_items = DC_ARENA_GEO_BLOCK_TO_SIZE(block_index, INITIAL_BLOCK_INDEX_BITS);
280 SLOT* block_slots = (SLOT*)NS(ALLOC, malloc)(self->alloc, block_items * sizeof(SLOT));
281 DC_ASSERT(block_slots);
282 new_self.blocks[block_index] = block_slots;
283
284 size_t const to_offset =
285 block_index == self->block_current ? self->block_current_exclusive_end : block_items;
286
287 for (size_t offset = 0; offset < to_offset; offset++) {
288 SLOT* src_slot = &self->blocks[block_index][offset];
289 SLOT* dst_slot = &new_self.blocks[block_index][offset];
290
291 if (src_slot->present) {
292 dst_slot->present = true;
293 dst_slot->value = VALUE_CLONE(&src_slot->value);
294 new_self.count++;
295 } else {
296 dst_slot->present = false;
297 }
298 }
299 }
300
301 PRIV(NS(SELF, set_memory_tracking))(&new_self);
302
303 return new_self;
304}
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 VALUE_CLONE
Definition template.h:37
static void PRIV set_memory_tracking(SELF const *self)
Definition template.h:119
static dc_gdb_marker dc_gdb_marker_new()
Definition gdb_marker.h:7
static mutation_tracker mutation_tracker_new()
#define NS(pre, post)
Definition namespace.h:4
#define DC_ASSERT(expr,...)
Definition panic.h:36
#define SELF
Definition def.h:52
size_t count
Definition template.h:76
SLOT * blocks[DC_ARENA_GEO_MAX_NUM_BLOCKS(INDEX_BITS, INITIAL_BLOCK_INDEX_BITS)]
Definition template.h:116
VALUE value
Definition template.h:78

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

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

Definition at line 429 of file template.h.

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

◆ delete()

void delete ( SELF * self)
static

Definition at line 342 of file template.h.

342 {
343 INVARIANT_CHECK(self);
344
345 for (uint8_t block = 0; block <= self->block_current; block++) {
346 size_t const to_offset = block == self->block_current
349
350 for (size_t offset = 0; offset < to_offset; offset++) {
351 SLOT* slot = &self->blocks[block][offset];
352 if (slot->present) {
353 VALUE_DELETE(&slot->value);
354 }
355 }
356
358 self->blocks[block],
360 NS(ALLOC, free)(self->alloc, self->blocks[block]);
361 }
362}
static void free(SELF *self, void *ptr)
Definition template.h:56
#define VALUE_DELETE
Definition template.h:35
static 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:80
INDEX_TYPE block_current_exclusive_end
Definition template.h:81
ALLOC * alloc
Definition template.h:71

◆ empty_item() [1/2]

bool empty_item ( IV_PAIR const * item)
static

Definition at line 513 of file template.h.

513{ 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 380 of file template.h.

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

◆ get_iter()

ITER get_iter ( SELF * self)
static

Definition at line 552 of file template.h.

552 {
553 INVARIANT_CHECK(self);
554
555 return (ITER){
556 .arena = self,
557 .next_index = 0,
559 };
560}
#define ITER
Definition template.h:320
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 419 of file template.h.

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

◆ insert()

INDEX insert ( SELF * self,
VALUE value )
static

Definition at line 173 of file template.h.

173 {
174 INVARIANT_CHECK(self);
175 DC_ASSERT(self->count < MAX_INDEX);
176
178
179 if (self->free_list != INDEX_NONE) {
180 INDEX_TYPE free_index = self->free_list;
181
182 uint8_t block = DC_ARENA_GEO_INDEX_TO_BLOCK(free_index, INITIAL_BLOCK_INDEX_BITS);
183 size_t offset = DC_ARENA_GEO_INDEX_TO_OFFSET(free_index, block, INITIAL_BLOCK_INDEX_BITS);
184 SLOT* free_slot = &self->blocks[block][offset];
185
186 DC_ASSUME(!free_slot->present, "The free list should only contain free slots");
187 self->free_list = free_slot->next_free;
188
189 free_slot->present = true;
190 NS(SLOT, fill)(free_slot, value);
191 self->count++;
192
193 return (INDEX){.index = free_index};
194 }
195
196 if (self->block_current_exclusive_end ==
198 DC_ASSUME(self->block_current < sizeof(self->blocks) / sizeof(SLOT*));
199
200 self->block_current++;
201 size_t block_items =
203 SLOT* block_slots = (SLOT*)NS(ALLOC, malloc)(self->alloc, block_items * sizeof(SLOT));
204 DC_ASSERT(block_slots);
205
206 self->blocks[self->block_current] = block_slots;
208 }
209
210 size_t offset = self->block_current_exclusive_end;
211 NS(SLOT, fill)(&self->blocks[self->block_current][offset], value);
214
216 self->count++;
217
219
220 return (INDEX){.index = new_index};
221}
#define DC_ARENA_GEO_INDEX_TO_OFFSET(IDX, BLOCK, INITIAL_BLOCK_INDEX_BITS)
Definition utils.h:9
#define DC_ARENA_GEO_BLOCK_OFFSET_TO_INDEX(BLOCK, OFFSET, INITIAL_BLOCK_INDEX_BITS)
Definition utils.h:16
#define DC_ARENA_GEO_INDEX_TO_BLOCK(IDX, INITIAL_BLOCK_INDEX_BITS)
Definition utils.h:4
#define INDEX_TYPE
Definition template.h:74
static void mutation_tracker_mutate(mutation_tracker *self)
INDEX_TYPE free_list
Definition template.h:77
static void fill(SELF *slot, SLOT_VALUE value)
Definition template.h:77

◆ iv_const_empty()

IV_PAIR_CONST iv_const_empty ( )
static

Definition at line 370 of file template.h.

370 {
371 return (IV_PAIR_CONST){
372 .index = {.index = INDEX_NONE},
373 .value = NULL,
374 };
375}
#define IV_PAIR_CONST
Definition template.h:399

◆ iv_empty()

IV_PAIR iv_empty ( )
static

Definition at line 503 of file template.h.

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

◆ new()

SELF new ( ALLOC * alloc)
static

Definition at line 148 of file template.h.

148 {
149 uint8_t initial_block = 0;
150 size_t initial_block_items =
152 SLOT* initial_block_slots = (SLOT*)NS(ALLOC, malloc)(alloc, initial_block_items * sizeof(SLOT));
153 DC_ASSERT(initial_block_slots);
154
155 SELF self = {
156 .free_list = INDEX_NONE,
157 .count = 0,
158 .alloc = alloc,
159 .derive_c_arena_blocks = dc_gdb_marker_new(),
160 .iterator_invalidation_tracker = mutation_tracker_new(),
161 .block_current_exclusive_end = 0,
162 .block_current = initial_block,
163 .blocks =
164 {
165 initial_block_slots,
166 },
167 };
168
170 return self;
171}

◆ next() [1/2]

IV_PAIR next ( ITER * iter)
static

Definition at line 521 of file template.h.

521 {
522 DC_ASSUME(iter);
524
525 while (iter->next_index < MAX_INDEX) {
527 size_t offset =
529
530 if ((block == iter->arena->block_current &&
531 offset >= iter->arena->block_current_exclusive_end) ||
532 (block > iter->arena->block_current)) {
533 break;
534 }
535
536 SLOT* slot = &iter->arena->blocks[block][offset];
537 if (slot->present) {
538 IV_PAIR result = {
539 .index = (INDEX){.index = iter->next_index},
540 .value = &slot->value,
541 };
542 iter->next_index++;
543 return result;
544 }
545
546 iter->next_index++;
547 }
548
549 return NS(SELF, iv_empty)();
550}
static IV_PAIR iv_empty()
Definition template.h:341
static void mutation_version_check(mutation_version const *self)
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 388 of file template.h.

388 {
389 DC_ASSUME(iter);
391
392 while (iter->next_index < MAX_INDEX) {
394 size_t offset =
396
397 if ((block == iter->arena->block_current &&
398 offset >= iter->arena->block_current_exclusive_end) ||
399 (block > iter->arena->block_current)) {
400 break;
401 }
402
403 SLOT* slot = &iter->arena->blocks[block][offset];
404 if (slot->present) {
405 IV_PAIR_CONST const result = {
406 .index = (INDEX){.index = iter->next_index},
407 .value = &slot->value,
408 };
409 iter->next_index++;
410 return result;
411 }
412
413 iter->next_index++;
414 }
415
416 return NS(SELF, iv_const_empty)();
417}
static IV_PAIR_CONST iv_const_empty()
Definition template.h:419
INDEX_TYPE next_index
Definition template.h:403
mutation_version version
Definition template.h:404
SELF const * arena
Definition template.h:402

◆ read()

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

Definition at line 245 of file template.h.

245 {
246 VALUE const* value = NS(SELF, try_read)(self, index);
247 DC_ASSERT(value);
248 return value;
249}
#define VALUE
Definition template.h:31
static VALUE const * try_read(SELF const *self, INDEX index)
Definition template.h:180

◆ remove()

VALUE remove ( SELF * self,
INDEX index )
static

Definition at line 333 of file template.h.

333 {
334 INVARIANT_CHECK(self);
336
337 VALUE value;
338 DC_ASSERT(NS(SELF, try_remove)(self, index, &value));
339 return value;
340}
static bool try_remove(SELF *self, INDEX index, VALUE *destination)
Definition template.h:264

◆ set_memory_tracking()

void PRIV set_memory_tracking ( SELF const * self)
static

Definition at line 119 of file template.h.

119 {
120 for (uint8_t block_index = 0; block_index <= self->block_current; block_index++) {
121 size_t block_items =
122 block_index == self->block_current
123 ? self->block_current_exclusive_end
125 for (size_t offset = 0; offset < block_items; offset++) {
126 SLOT* slot = &self->blocks[block_index][offset];
127 if (slot->present) {
129 } else {
131 }
132 }
133 }
134
135 size_t tail_slots = DC_ARENA_GEO_BLOCK_TO_SIZE(self->block_current, INITIAL_BLOCK_INDEX_BITS) -
136 (self->block_current_exclusive_end - 1);
138 &self->blocks[self->block_current][self->block_current_exclusive_end],
139 tail_slots * sizeof(SLOT));
140}
@ DC_MEMORY_TRACKER_CAP_NONE
static void memory_tracker_present(SELF const *slot)
Definition template.h:68
static void memory_tracker_empty(SELF const *slot)
Definition template.h:53

◆ size()

INDEX_TYPE size ( SELF const * self)
static

Definition at line 259 of file template.h.

259 {
260 INVARIANT_CHECK(self);
261 return self->count;
262}

◆ try_read()

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

Definition at line 223 of file template.h.

223 {
224 INVARIANT_CHECK(self);
225
226 uint8_t block = DC_ARENA_GEO_INDEX_TO_BLOCK(index.index, INITIAL_BLOCK_INDEX_BITS);
227 if (block > self->block_current) {
228 return NULL;
229 }
230
231 size_t offset = DC_ARENA_GEO_INDEX_TO_OFFSET(index.index, block, INITIAL_BLOCK_INDEX_BITS);
232
233 if (block == self->block_current && offset >= self->block_current_exclusive_end) {
234 return NULL;
235 }
236
237 SLOT* slot = &self->blocks[block][offset];
238 if (!slot->present) {
239 return NULL;
240 }
241
242 return &slot->value;
243}

◆ try_remove()

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

Definition at line 306 of file template.h.

306 {
307 INVARIANT_CHECK(self);
309
310 uint8_t block = DC_ARENA_GEO_INDEX_TO_BLOCK(index.index, INITIAL_BLOCK_INDEX_BITS);
311 if (block > self->block_current) {
312 return false;
313 }
314
315 size_t offset = DC_ARENA_GEO_INDEX_TO_OFFSET(index.index, block, INITIAL_BLOCK_INDEX_BITS);
316
317 if (block == self->block_current && offset >= self->block_current_exclusive_end) {
318 return false;
319 }
320
321 SLOT* slot = &self->blocks[block][offset];
322 if (slot->present) {
323 *destination = slot->value;
324 slot->present = false;
325 NS(SLOT, set_empty)(slot, self->free_list);
326 self->free_list = index.index;
327 self->count--;
328 return true;
329 }
330 return false;
331}
static void set_empty(SELF *slot, SLOT_INDEX_TYPE next_free)
Definition template.h:62

◆ try_write()

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

Definition at line 251 of file template.h.

251 {
252 return (VALUE*)NS(SELF, try_read)(self, index);
253}

◆ VALUE_CLONE()

value_t VALUE_CLONE ( value_t const * self)
static

◆ VALUE_DEBUG()

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

◆ VALUE_DELETE()

void VALUE_DELETE ( value_t * self)
static

◆ write()

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

Definition at line 255 of file template.h.

255 {
256 return (VALUE*)NS(SELF, read)(self, index);
257}
static VALUE const * read(SELF const *self, INDEX index)
Definition template.h:199

Variable Documentation

◆ max_entries

const size_t max_entries = MAX_INDEX
static

Definition at line 86 of file template.h.