C Container Collection (CCC)
Loading...
Searching...
No Matches
private_array_tree_map.h
Go to the documentation of this file.
1
24#ifndef CCC_PRIVATE_ARRAY_TREE_MAP_H
25#define CCC_PRIVATE_ARRAY_TREE_MAP_H
26
28#include <limits.h>
29#include <stddef.h>
30#include <stdint.h>
33#include "../types.h" /* IWYU pragma: keep */
34
35/* NOLINTBEGIN(readability-identifier-naming) */
36
44 size_t branch[2];
45 union {
47 size_t parent;
49 size_t next_free;
50 };
51};
52
150 void *data;
154 unsigned *parity;
156 size_t root;
158 size_t free_list;
160 size_t capacity;
162 size_t count;
171};
172
178 size_t index;
183};
184
185/*======================== Private Interface ==============================*/
186
188void *
191void *
195 struct CCC_Array_tree_map const *, void const *
196);
199 struct CCC_Array_tree_map *, size_t, CCC_Order, size_t
200);
203 struct CCC_Array_tree_map *, CCC_Allocator const *
204);
205
206/*========================= Initialization =========================*/
207
211#define CCC_private_array_tree_map_blocks(private_cap) \
212 (((private_cap) \
213 + ((sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT) - 1)) \
214 / (sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT))
215
217#define CCC_private_array_tree_map_compound_literal_array_capacity( \
218 private_type_compound_literal_array \
219) \
220 (sizeof(private_type_compound_literal_array) \
221 / sizeof(*(private_type_compound_literal_array)))
222
226#define CCC_private_array_tree_map_storage_for( \
227 private_type_compound_literal_array, optional_storage_specifier... \
228) \
229 (optional_storage_specifier struct { \
230 static_assert( \
231 CCC_private_array_tree_map_compound_literal_array_capacity( \
232 private_type_compound_literal_array \
233 ) > 1, \
234 "fixed size map must have capacity greater than 1" \
235 ); \
236 alignas( \
237 alignof(*(private_type_compound_literal_array)) \
238 > alignof(struct CCC_Array_tree_map_node) \
239 ? alignof(*(private_type_compound_literal_array)) \
240 : alignof(struct CCC_Array_tree_map_node) \
241 ) typeof(*(private_type_compound_literal_array)) \
242 data[CCC_private_array_tree_map_compound_literal_array_capacity( \
243 private_type_compound_literal_array \
244 )]; \
245 struct CCC_Array_tree_map_node \
246 nodes[CCC_private_array_tree_map_compound_literal_array_capacity( \
247 private_type_compound_literal_array \
248 )]; \
249 typeof(*(struct CCC_Array_tree_map){}.parity) \
250 parity[CCC_private_array_tree_map_blocks( \
251 CCC_private_array_tree_map_compound_literal_array_capacity( \
252 private_type_compound_literal_array \
253 ) \
254 )]; \
255 }) { \
256 }
257
259#define CCC_private_array_tree_map_default( \
260 private_type_name, private_key_field, private_comparator... \
261) \
262 (struct CCC_Array_tree_map) { \
263 .sizeof_type = sizeof(private_type_name), \
264 .alignof_type = alignof(private_type_name), \
265 .key_offset = offsetof(private_type_name, private_key_field), \
266 .comparator = (private_comparator), \
267 }
268
274#define CCC_private_array_tree_map_for( \
275 private_type_name, \
276 private_key_field, \
277 private_comparator, \
278 private_capacity, \
279 private_memory_pointer \
280) \
281 (struct CCC_Array_tree_map) { \
282 .data = (private_memory_pointer), .nodes = NULL, .parity = NULL, \
283 .capacity = (private_capacity), .count = 0, .root = 0, .free_list = 0, \
284 .sizeof_type = sizeof(private_type_name), \
285 .alignof_type = alignof(private_type_name), \
286 .key_offset = offsetof(private_type_name, private_key_field), \
287 .comparator = (private_comparator), \
288 }
289
291#define CCC_private_array_tree_map_from( \
292 private_key_field, \
293 private_comparator, \
294 private_allocator, \
295 private_optional_cap, \
296 private_array_compound_literal... \
297) \
298 (struct { struct CCC_Array_tree_map private; }){(__extension__({ \
299 typeof(*private_array_compound_literal) \
300 *private_array_tree_map_initializer_list \
301 = private_array_compound_literal; \
302 struct CCC_Array_tree_map private_array_tree_map \
303 = CCC_private_array_tree_map_default( \
304 typeof(*private_array_tree_map_initializer_list), \
305 private_key_field, \
306 private_comparator \
307 ); \
308 size_t const private_array_tree_n \
309 = sizeof(private_array_compound_literal) \
310 / sizeof(*private_array_tree_map_initializer_list); \
311 size_t const private_cap = private_optional_cap; \
312 CCC_Allocator const *const private_array_tree_map_allocator \
313 = &(private_allocator); \
314 if (CCC_array_tree_map_reserve( \
315 &private_array_tree_map, \
316 (private_array_tree_n > private_cap ? private_array_tree_n \
317 : private_cap), \
318 private_array_tree_map_allocator \
319 ) \
320 == CCC_RESULT_OK) { \
321 for (size_t i = 0; i < private_array_tree_n; ++i) { \
322 struct CCC_Array_tree_map_handle private_array_tree_entry \
323 = CCC_private_array_tree_map_handle( \
324 &private_array_tree_map, \
325 ( \
326 void const * \
327 )&private_array_tree_map_initializer_list[i] \
328 .private_key_field \
329 ); \
330 CCC_Handle_index private_index \
331 = private_array_tree_entry.index; \
332 if (!(private_array_tree_entry.status & CCC_ENTRY_OCCUPIED)) { \
333 private_index = CCC_private_array_tree_map_allocate_slot( \
334 &private_array_tree_map, \
335 private_array_tree_map_allocator \
336 ); \
337 } \
338 *((typeof(*private_array_tree_map_initializer_list) *) \
339 CCC_private_array_tree_map_data_at( \
340 private_array_tree_entry.map, private_index \
341 )) = private_array_tree_map_initializer_list[i]; \
342 if (!(private_array_tree_entry.status & CCC_ENTRY_OCCUPIED)) { \
343 CCC_private_array_tree_map_insert( \
344 private_array_tree_entry.map, \
345 private_array_tree_entry.index, \
346 private_array_tree_entry.last_order, \
347 private_index \
348 ); \
349 } \
350 } \
351 } \
352 private_array_tree_map; \
353 }))}.private
354
356#define CCC_private_array_tree_map_with_capacity( \
357 private_type_name, \
358 private_key_field, \
359 private_comparator, \
360 private_allocator, \
361 private_cap \
362) \
363 (struct { struct CCC_Array_tree_map private; }){(__extension__({ \
364 struct CCC_Array_tree_map private_array_tree_map \
365 = CCC_private_array_tree_map_default( \
366 private_type_name, private_key_field, private_comparator \
367 ); \
368 (void)CCC_array_tree_map_reserve( \
369 &private_array_tree_map, private_cap, &(private_allocator) \
370 ); \
371 private_array_tree_map; \
372 }))}.private
373
375#define CCC_private_array_tree_map_with_storage( \
376 private_key_node_field, \
377 private_comparator, \
378 private_compound_literal, \
379 private_optional_storage_specifier... \
380) \
381 (struct CCC_Array_tree_map) { \
382 .data = &CCC_private_array_tree_map_storage_for( \
383 private_compound_literal, private_optional_storage_specifier \
384 ), \
385 .nodes = NULL, .parity = NULL, \
386 .capacity \
387 = CCC_private_array_tree_map_compound_literal_array_capacity( \
388 private_compound_literal \
389 ), \
390 .count = 0, .root = 0, .free_list = 0, \
391 .sizeof_type = sizeof(*(private_compound_literal)), \
392 .alignof_type = alignof(*(private_compound_literal)), \
393 .key_offset = offsetof( \
394 typeof(*(private_compound_literal)), private_key_node_field \
395 ), \
396 .comparator = (private_comparator), \
397 }
398
400#define CCC_private_array_tree_map_as( \
401 array_tree_map_pointer, type_name, handle... \
402) \
403 ((type_name *)CCC_private_array_tree_map_data_at( \
404 (array_tree_map_pointer), (handle) \
405 ))
406
408#define CCC_private_array_tree_map_with_allocator_storage( \
409 private_key_field, \
410 private_comparator, \
411 private_allocator, \
412 private_compound_literal \
413) \
414 (__extension__({ \
415 CCC_Allocator const *const private_allocator_pointer \
416 = &(private_allocator); \
417 void *private_data_base = NULL; \
418 if (private_allocator_pointer->allocate) { \
419 private_data_base = private_allocator_pointer->allocate( \
420 (CCC_Allocator_arguments){ \
421 .input = NULL, \
422 .bytes = sizeof(CCC_private_array_tree_map_storage_for( \
423 private_compound_literal \
424 )), \
425 .alignment = alignof(struct CCC_Array_tree_map_node) \
426 > alignof(*(private_compound_literal)) \
427 ? alignof(struct CCC_Array_tree_map_node) \
428 : alignof(*(private_compound_literal)), \
429 .context = private_allocator_pointer->context, \
430 } \
431 ); \
432 } \
433 struct CCC_Array_tree_map private_array_tree_map = {}; \
434 if (private_data_base) { \
435 private_array_tree_map = CCC_private_array_tree_map_for( \
436 typeof(*(private_compound_literal)), \
437 private_key_field, \
438 private_comparator, \
439 CCC_private_array_tree_map_compound_literal_array_capacity( \
440 private_compound_literal \
441 ), \
442 private_data_base \
443 ); \
444 } else { \
445 private_array_tree_map = CCC_private_array_tree_map_for( \
446 typeof(*(private_compound_literal)), \
447 private_key_field, \
448 private_comparator, \
449 0, \
450 NULL \
451 ); \
452 } \
453 private_array_tree_map; \
454 }))
455
456/*================== Core Macro Implementations =====================*/
457
459#define CCC_private_array_tree_map_and_modify_with( \
460 array_tree_map_handle_pointer, \
461 closure_parameter, \
462 closure_over_closure_parameter... \
463) \
464 (__extension__({ \
465 struct CCC_Array_tree_map_handle const *const \
466 private_array_tree_map_hndl_pointer \
467 = (array_tree_map_handle_pointer); \
468 struct CCC_Array_tree_map_handle private_array_tree_map_mod_hndl \
469 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
470 if (private_array_tree_map_hndl_pointer) { \
471 private_array_tree_map_mod_hndl \
472 = *private_array_tree_map_hndl_pointer; \
473 if (private_array_tree_map_mod_hndl.status & CCC_ENTRY_OCCUPIED) { \
474 closure_parameter = CCC_private_array_tree_map_data_at( \
475 private_array_tree_map_mod_hndl.map, \
476 private_array_tree_map_mod_hndl.index \
477 ); \
478 closure_over_closure_parameter \
479 } \
480 } \
481 private_array_tree_map_mod_hndl; \
482 }))
483
485#define CCC_private_array_tree_map_or_insert_with( \
486 array_tree_map_handle_pointer, \
487 private_allocator_pointer, \
488 type_compound_literal... \
489) \
490 (__extension__({ \
491 struct CCC_Array_tree_map_handle const *const \
492 private_or_ins_handle_pointer = (array_tree_map_handle_pointer); \
493 CCC_Handle_index private_array_tree_map_or_ins_ret = 0; \
494 CCC_Allocator const *const private_array_tree_map_allocator \
495 = (private_allocator_pointer); \
496 if (private_array_tree_map_allocator \
497 && private_or_ins_handle_pointer) { \
498 if (private_or_ins_handle_pointer->status == CCC_ENTRY_OCCUPIED) { \
499 private_array_tree_map_or_ins_ret \
500 = private_or_ins_handle_pointer->index; \
501 } else { \
502 private_array_tree_map_or_ins_ret \
503 = CCC_private_array_tree_map_allocate_slot( \
504 private_or_ins_handle_pointer->map, \
505 private_array_tree_map_allocator \
506 ); \
507 if (private_array_tree_map_or_ins_ret) { \
508 *((typeof(type_compound_literal) *) \
509 CCC_private_array_tree_map_data_at( \
510 private_or_ins_handle_pointer->map, \
511 private_array_tree_map_or_ins_ret \
512 )) = type_compound_literal; \
513 CCC_private_array_tree_map_insert( \
514 private_or_ins_handle_pointer->map, \
515 private_or_ins_handle_pointer->index, \
516 private_or_ins_handle_pointer->last_order, \
517 private_array_tree_map_or_ins_ret \
518 ); \
519 } \
520 } \
521 } \
522 private_array_tree_map_or_ins_ret; \
523 }))
524
526#define CCC_private_array_tree_map_insert_handle_with( \
527 array_tree_map_handle_pointer, \
528 private_allocator_pointer, \
529 type_compound_literal... \
530) \
531 (__extension__({ \
532 struct CCC_Array_tree_map_handle const *const \
533 private_ins_handle_pointer = (array_tree_map_handle_pointer); \
534 CCC_Handle_index private_array_tree_map_ins_hndl_ret = 0; \
535 CCC_Allocator const *const private_array_tree_map_allocator \
536 = (private_allocator_pointer); \
537 if (private_array_tree_map_allocator && private_ins_handle_pointer) { \
538 if (!(private_ins_handle_pointer->status & CCC_ENTRY_OCCUPIED)) { \
539 private_array_tree_map_ins_hndl_ret \
540 = CCC_private_array_tree_map_allocate_slot( \
541 private_ins_handle_pointer->map, \
542 private_array_tree_map_allocator \
543 ); \
544 if (private_array_tree_map_ins_hndl_ret) { \
545 *((typeof(type_compound_literal) *) \
546 CCC_private_array_tree_map_data_at( \
547 private_ins_handle_pointer->map, \
548 private_array_tree_map_ins_hndl_ret \
549 )) = type_compound_literal; \
550 CCC_private_array_tree_map_insert( \
551 private_ins_handle_pointer->map, \
552 private_ins_handle_pointer->index, \
553 private_ins_handle_pointer->last_order, \
554 private_array_tree_map_ins_hndl_ret \
555 ); \
556 } \
557 } else if (private_ins_handle_pointer->status \
558 == CCC_ENTRY_OCCUPIED) { \
559 private_array_tree_map_ins_hndl_ret \
560 = private_ins_handle_pointer->index; \
561 *((typeof(type_compound_literal) *) \
562 CCC_private_array_tree_map_data_at( \
563 private_ins_handle_pointer->map, \
564 private_array_tree_map_ins_hndl_ret \
565 )) = type_compound_literal; \
566 } \
567 } \
568 private_array_tree_map_ins_hndl_ret; \
569 }))
570
572#define CCC_private_array_tree_map_try_insert_with( \
573 array_tree_map_pointer, \
574 key, \
575 private_allocator_pointer, \
576 type_compound_literal... \
577) \
578 (__extension__({ \
579 struct CCC_Array_tree_map *const private_try_ins_map_pointer \
580 = (array_tree_map_pointer); \
581 CCC_Handle private_array_tree_map_try_ins_hndl_ret \
582 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
583 CCC_Allocator const *const private_array_tree_map_allocator \
584 = (private_allocator_pointer); \
585 if (private_array_tree_map_allocator && private_try_ins_map_pointer) { \
586 __auto_type private_array_tree_map_key = (key); \
587 struct CCC_Array_tree_map_handle \
588 private_array_tree_map_try_ins_hndl \
589 = CCC_private_array_tree_map_handle( \
590 private_try_ins_map_pointer, \
591 (void *)&private_array_tree_map_key \
592 ); \
593 if (!(private_array_tree_map_try_ins_hndl.status \
594 & CCC_ENTRY_OCCUPIED)) { \
595 private_array_tree_map_try_ins_hndl_ret = (CCC_Handle){ \
596 .index = CCC_private_array_tree_map_allocate_slot( \
597 private_array_tree_map_try_ins_hndl.map, \
598 private_array_tree_map_allocator \
599 ), \
600 .status = CCC_ENTRY_INSERT_ERROR, \
601 }; \
602 if (private_array_tree_map_try_ins_hndl_ret.index) { \
603 *((typeof(type_compound_literal) *) \
604 CCC_private_array_tree_map_data_at( \
605 private_try_ins_map_pointer, \
606 private_array_tree_map_try_ins_hndl_ret.index \
607 )) = type_compound_literal; \
608 *((typeof(private_array_tree_map_key) *) \
609 CCC_private_array_tree_map_key_at( \
610 private_try_ins_map_pointer, \
611 private_array_tree_map_try_ins_hndl_ret.index \
612 )) = private_array_tree_map_key; \
613 CCC_private_array_tree_map_insert( \
614 private_array_tree_map_try_ins_hndl.map, \
615 private_array_tree_map_try_ins_hndl.index, \
616 private_array_tree_map_try_ins_hndl.last_order, \
617 private_array_tree_map_try_ins_hndl_ret.index \
618 ); \
619 private_array_tree_map_try_ins_hndl_ret.status \
620 = CCC_ENTRY_VACANT; \
621 } \
622 } else if (private_array_tree_map_try_ins_hndl.status \
623 == CCC_ENTRY_OCCUPIED) { \
624 private_array_tree_map_try_ins_hndl_ret = (CCC_Handle){ \
625 .index = private_array_tree_map_try_ins_hndl.index, \
626 .status = private_array_tree_map_try_ins_hndl.status, \
627 }; \
628 } \
629 } \
630 private_array_tree_map_try_ins_hndl_ret; \
631 }))
632
634#define CCC_private_array_tree_map_insert_or_assign_with( \
635 array_tree_map_pointer, \
636 key, \
637 private_allocator_pointer, \
638 type_compound_literal... \
639) \
640 (__extension__({ \
641 struct CCC_Array_tree_map *const private_ins_or_assign_map_pointer \
642 = (array_tree_map_pointer); \
643 CCC_Handle private_array_tree_map_ins_or_assign_hndl_ret \
644 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
645 CCC_Allocator const *const private_array_tree_map_allocator \
646 = (private_allocator_pointer); \
647 if (private_array_tree_map_allocator \
648 && private_ins_or_assign_map_pointer) { \
649 __auto_type private_array_tree_map_key = (key); \
650 struct CCC_Array_tree_map_handle \
651 private_array_tree_map_ins_or_assign_hndl \
652 = CCC_private_array_tree_map_handle( \
653 private_ins_or_assign_map_pointer, \
654 (void *)&private_array_tree_map_key \
655 ); \
656 if (!(private_array_tree_map_ins_or_assign_hndl.status \
657 & CCC_ENTRY_OCCUPIED)) { \
658 private_array_tree_map_ins_or_assign_hndl_ret = (CCC_Handle){ \
659 .index = CCC_private_array_tree_map_allocate_slot( \
660 private_array_tree_map_ins_or_assign_hndl.map, \
661 private_array_tree_map_allocator \
662 ), \
663 .status = CCC_ENTRY_INSERT_ERROR, \
664 }; \
665 if (private_array_tree_map_ins_or_assign_hndl_ret.index) { \
666 *((typeof(type_compound_literal) *) \
667 CCC_private_array_tree_map_data_at( \
668 private_array_tree_map_ins_or_assign_hndl.map, \
669 private_array_tree_map_ins_or_assign_hndl_ret \
670 .index \
671 )) = type_compound_literal; \
672 *((typeof(private_array_tree_map_key) *) \
673 CCC_private_array_tree_map_key_at( \
674 private_array_tree_map_ins_or_assign_hndl.map, \
675 private_array_tree_map_ins_or_assign_hndl_ret \
676 .index \
677 )) = private_array_tree_map_key; \
678 CCC_private_array_tree_map_insert( \
679 private_array_tree_map_ins_or_assign_hndl.map, \
680 private_array_tree_map_ins_or_assign_hndl.index, \
681 private_array_tree_map_ins_or_assign_hndl.last_order, \
682 private_array_tree_map_ins_or_assign_hndl_ret.index \
683 ); \
684 private_array_tree_map_ins_or_assign_hndl_ret.status \
685 = CCC_ENTRY_VACANT; \
686 } \
687 } else if (private_array_tree_map_ins_or_assign_hndl.status \
688 == CCC_ENTRY_OCCUPIED) { \
689 *((typeof(type_compound_literal) *) \
690 CCC_private_array_tree_map_data_at( \
691 private_array_tree_map_ins_or_assign_hndl.map, \
692 private_array_tree_map_ins_or_assign_hndl.index \
693 )) = type_compound_literal; \
694 private_array_tree_map_ins_or_assign_hndl_ret = (CCC_Handle){ \
695 .index = private_array_tree_map_ins_or_assign_hndl.index, \
696 .status \
697 = private_array_tree_map_ins_or_assign_hndl.status, \
698 }; \
699 *((typeof(private_array_tree_map_key) *) \
700 CCC_private_array_tree_map_key_at( \
701 private_array_tree_map_ins_or_assign_hndl.map, \
702 private_array_tree_map_ins_or_assign_hndl.index \
703 )) = private_array_tree_map_key; \
704 } \
705 } \
706 private_array_tree_map_ins_or_assign_hndl_ret; \
707 }))
708
709/* NOLINTEND(readability-identifier-naming) */
710
711#endif /* CCC_PRIVATE_ARRAY_TREE_MAP_H */
void * CCC_private_array_tree_map_data_at(struct CCC_Array_tree_map const *, size_t)
void CCC_private_array_tree_map_insert(struct CCC_Array_tree_map *, size_t, CCC_Order, size_t)
struct CCC_Array_tree_map_handle CCC_private_array_tree_map_handle(struct CCC_Array_tree_map const *, void const *)
void * CCC_private_array_tree_map_key_at(struct CCC_Array_tree_map const *, size_t)
size_t CCC_private_array_tree_map_allocate_slot(struct CCC_Array_tree_map *, CCC_Allocator const *)
The type passed by reference to any container function that may need to allocate memory....
Definition: types.h:384
Definition: private_array_tree_map.h:174
CCC_Order last_order
Definition: private_array_tree_map.h:180
size_t index
Definition: private_array_tree_map.h:178
struct CCC_Array_tree_map * map
Definition: private_array_tree_map.h:176
CCC_Entry_status status
Definition: private_array_tree_map.h:182
Definition: private_array_tree_map.h:42
size_t parent
Definition: private_array_tree_map.h:47
size_t branch[2]
Definition: private_array_tree_map.h:44
size_t next_free
Definition: private_array_tree_map.h:49
Definition: private_array_tree_map.h:148
void * data
Definition: private_array_tree_map.h:150
unsigned * parity
Definition: private_array_tree_map.h:154
size_t sizeof_type
Definition: private_array_tree_map.h:164
size_t count
Definition: private_array_tree_map.h:162
size_t capacity
Definition: private_array_tree_map.h:160
size_t root
Definition: private_array_tree_map.h:156
size_t free_list
Definition: private_array_tree_map.h:158
struct CCC_Array_tree_map_node * nodes
Definition: private_array_tree_map.h:152
CCC_Key_comparator comparator
Definition: private_array_tree_map.h:170
size_t alignof_type
Definition: private_array_tree_map.h:166
size_t key_offset
Definition: private_array_tree_map.h:168
The type passed by reference to any container function that may need to compare keys....
Definition: types.h:520
CCC_Order
A three-way comparison for comparison functions.
Definition: types.h:213
CCC_Entry_status
The status monitoring and entry state once it is obtained.
Definition: types.h:112