24#ifndef CCC_PRIVATE_ARRAY_TREE_MAP_H
25#define CCC_PRIVATE_ARRAY_TREE_MAP_H
211#define CCC_private_array_tree_map_blocks(private_cap) \
213 + ((sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT) - 1)) \
214 / (sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT))
217#define CCC_private_array_tree_map_compound_literal_array_capacity( \
218 private_type_compound_literal_array \
220 (sizeof(private_type_compound_literal_array) \
221 / sizeof(*(private_type_compound_literal_array)))
226#define CCC_private_array_tree_map_storage_for( \
227 private_type_compound_literal_array, optional_storage_specifier... \
229 (optional_storage_specifier struct { \
231 CCC_private_array_tree_map_compound_literal_array_capacity( \
232 private_type_compound_literal_array \
234 "fixed size map must have capacity greater than 1" \
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 \
245 struct CCC_Array_tree_map_node \
246 nodes[CCC_private_array_tree_map_compound_literal_array_capacity( \
247 private_type_compound_literal_array \
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 \
259#define CCC_private_array_tree_map_default( \
260 private_type_name, private_key_field, private_comparator... \
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), \
274#define CCC_private_array_tree_map_for( \
277 private_comparator, \
279 private_memory_pointer \
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), \
291#define CCC_private_array_tree_map_from( \
293 private_comparator, \
295 private_optional_cap, \
296 private_array_compound_literal... \
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), \
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 \
318 private_array_tree_map_allocator \
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, \
327 )&private_array_tree_map_initializer_list[i] \
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 \
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, \
352 private_array_tree_map; \
356#define CCC_private_array_tree_map_with_capacity( \
359 private_comparator, \
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 \
368 (void)CCC_array_tree_map_reserve( \
369 &private_array_tree_map, private_cap, &(private_allocator) \
371 private_array_tree_map; \
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... \
381 (struct CCC_Array_tree_map) { \
382 .data = &CCC_private_array_tree_map_storage_for( \
383 private_compound_literal, private_optional_storage_specifier \
385 .nodes = NULL, .parity = NULL, \
387 = CCC_private_array_tree_map_compound_literal_array_capacity( \
388 private_compound_literal \
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 \
396 .comparator = (private_comparator), \
400#define CCC_private_array_tree_map_as( \
401 array_tree_map_pointer, type_name, handle... \
403 ((type_name *)CCC_private_array_tree_map_data_at( \
404 (array_tree_map_pointer), (handle) \
408#define CCC_private_array_tree_map_with_allocator_storage( \
410 private_comparator, \
412 private_compound_literal \
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){ \
422 .bytes = sizeof(CCC_private_array_tree_map_storage_for( \
423 private_compound_literal \
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, \
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)), \
438 private_comparator, \
439 CCC_private_array_tree_map_compound_literal_array_capacity( \
440 private_compound_literal \
445 private_array_tree_map = CCC_private_array_tree_map_for( \
446 typeof(*(private_compound_literal)), \
448 private_comparator, \
453 private_array_tree_map; \
459#define CCC_private_array_tree_map_and_modify_with( \
460 array_tree_map_handle_pointer, \
462 closure_over_closure_parameter... \
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 \
478 closure_over_closure_parameter \
481 private_array_tree_map_mod_hndl; \
485#define CCC_private_array_tree_map_or_insert_with( \
486 array_tree_map_handle_pointer, \
487 private_allocator_pointer, \
488 type_compound_literal... \
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; \
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 \
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 \
522 private_array_tree_map_or_ins_ret; \
526#define CCC_private_array_tree_map_insert_handle_with( \
527 array_tree_map_handle_pointer, \
528 private_allocator_pointer, \
529 type_compound_literal... \
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 \
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 \
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; \
568 private_array_tree_map_ins_hndl_ret; \
572#define CCC_private_array_tree_map_try_insert_with( \
573 array_tree_map_pointer, \
575 private_allocator_pointer, \
576 type_compound_literal... \
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 \
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 \
600 .status = CCC_ENTRY_INSERT_ERROR, \
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 \
619 private_array_tree_map_try_ins_hndl_ret.status \
620 = CCC_ENTRY_VACANT; \
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, \
630 private_array_tree_map_try_ins_hndl_ret; \
634#define CCC_private_array_tree_map_insert_or_assign_with( \
635 array_tree_map_pointer, \
637 private_allocator_pointer, \
638 type_compound_literal... \
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 \
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 \
663 .status = CCC_ENTRY_INSERT_ERROR, \
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 \
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 \
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 \
684 private_array_tree_map_ins_or_assign_hndl_ret.status \
685 = CCC_ENTRY_VACANT; \
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, \
697 = private_array_tree_map_ins_or_assign_hndl.status, \
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; \
706 private_array_tree_map_ins_or_assign_hndl_ret; \
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