16#ifndef CCC_PRIVATE_ARRAY_TREE_MAP_H
17#define CCC_PRIVATE_ARRAY_TREE_MAP_H
26#include "private_types.h"
205#define CCC_private_array_tree_map_blocks(private_cap) \
207 + ((sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT) - 1)) \
208 / (sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT))
213#define CCC_private_array_tree_map_declare_fixed( \
214 private_fixed_map_type_name, private_key_val_type_name, private_capacity) \
215 static_assert((private_capacity) > 1, \
216 "fixed size map must have capacity greater than 1"); \
219 private_key_val_type_name data[(private_capacity)]; \
220 struct CCC_Array_tree_map_node nodes[(private_capacity)]; \
221 typeof(*(struct CCC_Array_tree_map){}.parity) \
222 parity[CCC_private_array_tree_map_blocks((private_capacity))]; \
223 }(private_fixed_map_type_name)
227#define CCC_private_array_tree_map_fixed_capacity(fixed_map_type_name) \
228 (sizeof((fixed_map_type_name){}.nodes) \
229 / sizeof(struct CCC_Array_tree_map_node))
236#define CCC_private_array_tree_map_initialize( \
237 private_memory_pointer, private_type_name, private_key_field, \
238 private_key_compare, private_allocate, private_context_data, \
241 .data = (private_memory_pointer), \
244 .capacity = (private_capacity), \
248 .sizeof_type = sizeof(private_type_name), \
249 .key_offset = offsetof(private_type_name, private_key_field), \
250 .compare = (private_key_compare), \
251 .allocate = (private_allocate), \
252 .context = (private_context_data), \
256#define CCC_private_array_tree_map_from( \
257 private_key_field, private_key_compare, private_allocate, \
258 private_context_data, private_optional_cap, \
259 private_array_compound_literal...) \
261 typeof(*private_array_compound_literal) \
262 *private_array_tree_map_initializer_list \
263 = private_array_compound_literal; \
264 struct CCC_Array_tree_map private_array_tree_map \
265 = CCC_private_array_tree_map_initialize( \
266 NULL, typeof(*private_array_tree_map_initializer_list), \
267 private_key_field, private_key_compare, private_allocate, \
268 private_context_data, 0); \
269 size_t const private_array_tree_n \
270 = sizeof(private_array_compound_literal) \
271 / sizeof(*private_array_tree_map_initializer_list); \
272 size_t const private_cap = private_optional_cap; \
273 if (CCC_array_tree_map_reserve(&private_array_tree_map, \
274 (private_array_tree_n > private_cap \
275 ? private_array_tree_n \
280 for (size_t i = 0; i < private_array_tree_n; ++i) \
282 struct CCC_Array_tree_map_handle private_array_tree_entry \
283 = CCC_private_array_tree_map_handle( \
284 &private_array_tree_map, \
286 *)&private_array_tree_map_initializer_list[i] \
287 .private_key_field); \
288 CCC_Handle_index private_index \
289 = private_array_tree_entry.index; \
290 if (!(private_array_tree_entry.status & CCC_ENTRY_OCCUPIED)) \
292 private_index = CCC_private_array_tree_map_allocate_slot( \
293 &private_array_tree_map); \
295 *((typeof(*private_array_tree_map_initializer_list) *) \
296 CCC_private_array_tree_map_data_at( \
297 private_array_tree_entry.map, private_index)) \
298 = private_array_tree_map_initializer_list[i]; \
299 if (!(private_array_tree_entry.status & CCC_ENTRY_OCCUPIED)) \
301 CCC_private_array_tree_map_insert( \
302 private_array_tree_entry.map, \
303 private_array_tree_entry.index, \
304 private_array_tree_entry.last_order, private_index); \
308 private_array_tree_map; \
311#define CCC_private_array_tree_map_with_capacity( \
312 private_type_name, private_key_field, private_key_compare, \
313 private_allocate, private_context_data, private_cap) \
315 struct CCC_Array_tree_map private_array_tree_map \
316 = CCC_private_array_tree_map_initialize( \
317 NULL, private_type_name, private_key_field, \
318 private_key_compare, private_allocate, private_context_data, \
320 (void)CCC_array_tree_map_reserve(&private_array_tree_map, private_cap, \
322 private_array_tree_map; \
326#define CCC_private_array_tree_map_with_compound_literal( \
327 private_key_node_field, private_key_order_fn, private_compound_literal) \
329 .data = &(private_compound_literal), \
332 .capacity = CCC_private_array_tree_map_fixed_capacity( \
333 typeof(private_compound_literal)), \
337 .sizeof_type = sizeof(*(private_compound_literal.data)) , \
339 = offsetof(typeof(*(private_compound_literal.data)) , \
340 private_key_node_field), \
341 .compare = (private_key_order_fn), \
347#define CCC_private_array_tree_map_with_context_compound_literal( \
348 private_key_node_field, private_key_order_fn, private_context, \
349 private_compound_literal) \
351 .data = &(private_compound_literal), \
354 .capacity = CCC_private_array_tree_map_fixed_capacity( \
355 typeof(private_compound_literal)), \
359 .sizeof_type = sizeof(*(private_compound_literal.data)) , \
361 = offsetof(typeof(*(private_compound_literal.data)) , \
362 private_key_node_field), \
363 .compare = (private_key_order_fn), \
365 .context = (private_context), \
369#define CCC_private_array_tree_map_as(array_tree_map_pointer, type_name, \
371 ((type_name *)CCC_private_array_tree_map_data_at((array_tree_map_pointer), \
377#define CCC_private_array_tree_map_and_modify_with( \
378 array_tree_map_array_pointer, type_name, closure_over_T...) \
380 __auto_type private_array_tree_map_hndl_pointer \
381 = (array_tree_map_array_pointer); \
382 struct CCC_Array_tree_map_handle private_array_tree_map_mod_hndl \
383 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
384 if (private_array_tree_map_hndl_pointer) \
386 private_array_tree_map_mod_hndl \
387 = private_array_tree_map_hndl_pointer->private; \
388 if (private_array_tree_map_mod_hndl.status & CCC_ENTRY_OCCUPIED) \
390 type_name *const T = CCC_private_array_tree_map_data_at( \
391 private_array_tree_map_mod_hndl.map, \
392 private_array_tree_map_mod_hndl.index); \
399 private_array_tree_map_mod_hndl; \
403#define CCC_private_array_tree_map_or_insert_with( \
404 array_tree_map_array_pointer, type_compound_literal...) \
406 __auto_type private_or_ins_array_pointer \
407 = (array_tree_map_array_pointer); \
408 CCC_Handle_index private_array_tree_map_or_ins_ret = 0; \
409 if (private_or_ins_array_pointer) \
411 if (private_or_ins_array_pointer->private.status \
412 == CCC_ENTRY_OCCUPIED) \
414 private_array_tree_map_or_ins_ret \
415 = private_or_ins_array_pointer->private.index; \
419 private_array_tree_map_or_ins_ret \
420 = CCC_private_array_tree_map_allocate_slot( \
421 private_or_ins_array_pointer->private.map); \
422 if (private_array_tree_map_or_ins_ret) \
424 *((typeof(type_compound_literal) *) \
425 CCC_private_array_tree_map_data_at( \
426 private_or_ins_array_pointer->private.map, \
427 private_array_tree_map_or_ins_ret)) \
428 = type_compound_literal; \
429 CCC_private_array_tree_map_insert( \
430 private_or_ins_array_pointer->private.map, \
431 private_or_ins_array_pointer->private.index, \
432 private_or_ins_array_pointer->private.last_order, \
433 private_array_tree_map_or_ins_ret); \
437 private_array_tree_map_or_ins_ret; \
441#define CCC_private_array_tree_map_insert_array_with( \
442 array_tree_map_array_pointer, type_compound_literal...) \
444 __auto_type private_ins_array_pointer \
445 = (array_tree_map_array_pointer); \
446 CCC_Handle_index private_array_tree_map_ins_hndl_ret = 0; \
447 if (private_ins_array_pointer) \
449 if (!(private_ins_array_pointer->private.status \
450 & CCC_ENTRY_OCCUPIED)) \
452 private_array_tree_map_ins_hndl_ret \
453 = CCC_private_array_tree_map_allocate_slot( \
454 private_ins_array_pointer->private.map); \
455 if (private_array_tree_map_ins_hndl_ret) \
457 *((typeof(type_compound_literal) *) \
458 CCC_private_array_tree_map_data_at( \
459 private_ins_array_pointer->private.map, \
460 private_array_tree_map_ins_hndl_ret)) \
461 = type_compound_literal; \
462 CCC_private_array_tree_map_insert( \
463 private_ins_array_pointer->private.map, \
464 private_ins_array_pointer->private.index, \
465 private_ins_array_pointer->private.last_order, \
466 private_array_tree_map_ins_hndl_ret); \
469 else if (private_ins_array_pointer->private.status \
470 == CCC_ENTRY_OCCUPIED) \
472 private_array_tree_map_ins_hndl_ret \
473 = private_ins_array_pointer->private.index; \
474 *((typeof(type_compound_literal) *) \
475 CCC_private_array_tree_map_data_at( \
476 private_ins_array_pointer->private.map, \
477 private_array_tree_map_ins_hndl_ret)) \
478 = type_compound_literal; \
481 private_array_tree_map_ins_hndl_ret; \
485#define CCC_private_array_tree_map_try_insert_with( \
486 array_tree_map_pointer, key, type_compound_literal...) \
488 __auto_type private_try_ins_map_pointer = (array_tree_map_pointer); \
489 struct CCC_Handle private_array_tree_map_try_ins_hndl_ret \
490 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
491 if (private_try_ins_map_pointer) \
493 __auto_type private_array_tree_map_key = (key); \
494 struct CCC_Array_tree_map_handle \
495 private_array_tree_map_try_ins_hndl \
496 = CCC_private_array_tree_map_handle( \
497 private_try_ins_map_pointer, \
498 (void *)&private_array_tree_map_key); \
499 if (!(private_array_tree_map_try_ins_hndl.status \
500 & CCC_ENTRY_OCCUPIED)) \
502 private_array_tree_map_try_ins_hndl_ret = (struct CCC_Handle){ \
503 .index = CCC_private_array_tree_map_allocate_slot( \
504 private_array_tree_map_try_ins_hndl.map), \
505 .status = CCC_ENTRY_INSERT_ERROR, \
507 if (private_array_tree_map_try_ins_hndl_ret.index) \
509 *((typeof(type_compound_literal) *) \
510 CCC_private_array_tree_map_data_at( \
511 private_try_ins_map_pointer, \
512 private_array_tree_map_try_ins_hndl_ret.index)) \
513 = type_compound_literal; \
514 *((typeof(private_array_tree_map_key) *) \
515 CCC_private_array_tree_map_key_at( \
516 private_try_ins_map_pointer, \
517 private_array_tree_map_try_ins_hndl_ret.index)) \
518 = private_array_tree_map_key; \
519 CCC_private_array_tree_map_insert( \
520 private_array_tree_map_try_ins_hndl.map, \
521 private_array_tree_map_try_ins_hndl.index, \
522 private_array_tree_map_try_ins_hndl.last_order, \
523 private_array_tree_map_try_ins_hndl_ret.index); \
524 private_array_tree_map_try_ins_hndl_ret.status \
525 = CCC_ENTRY_VACANT; \
528 else if (private_array_tree_map_try_ins_hndl.status \
529 == CCC_ENTRY_OCCUPIED) \
531 private_array_tree_map_try_ins_hndl_ret = (struct CCC_Handle){ \
532 .index = private_array_tree_map_try_ins_hndl.index, \
533 .status = private_array_tree_map_try_ins_hndl.status, \
537 private_array_tree_map_try_ins_hndl_ret; \
541#define CCC_private_array_tree_map_insert_or_assign_with( \
542 array_tree_map_pointer, key, type_compound_literal...) \
544 __auto_type private_ins_or_assign_map_pointer \
545 = (array_tree_map_pointer); \
546 struct CCC_Handle private_array_tree_map_ins_or_assign_hndl_ret \
547 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
548 if (private_ins_or_assign_map_pointer) \
550 __auto_type private_array_tree_map_key = (key); \
551 struct CCC_Array_tree_map_handle \
552 private_array_tree_map_ins_or_assign_hndl \
553 = CCC_private_array_tree_map_handle( \
554 private_ins_or_assign_map_pointer, \
555 (void *)&private_array_tree_map_key); \
556 if (!(private_array_tree_map_ins_or_assign_hndl.status \
557 & CCC_ENTRY_OCCUPIED)) \
559 private_array_tree_map_ins_or_assign_hndl_ret \
560 = (struct CCC_Handle){ \
561 .index = CCC_private_array_tree_map_allocate_slot( \
562 private_array_tree_map_ins_or_assign_hndl.map), \
563 .status = CCC_ENTRY_INSERT_ERROR, \
565 if (private_array_tree_map_ins_or_assign_hndl_ret.index) \
567 *((typeof(type_compound_literal) *) \
568 CCC_private_array_tree_map_data_at( \
569 private_array_tree_map_ins_or_assign_hndl.map, \
570 private_array_tree_map_ins_or_assign_hndl_ret \
572 = type_compound_literal; \
573 *((typeof(private_array_tree_map_key) *) \
574 CCC_private_array_tree_map_key_at( \
575 private_array_tree_map_ins_or_assign_hndl.map, \
576 private_array_tree_map_ins_or_assign_hndl_ret \
578 = private_array_tree_map_key; \
579 CCC_private_array_tree_map_insert( \
580 private_array_tree_map_ins_or_assign_hndl.map, \
581 private_array_tree_map_ins_or_assign_hndl.index, \
582 private_array_tree_map_ins_or_assign_hndl.last_order, \
583 private_array_tree_map_ins_or_assign_hndl_ret.index); \
584 private_array_tree_map_ins_or_assign_hndl_ret.status \
585 = CCC_ENTRY_VACANT; \
588 else if (private_array_tree_map_ins_or_assign_hndl.status \
589 == CCC_ENTRY_OCCUPIED) \
591 *((typeof(type_compound_literal) *) \
592 CCC_private_array_tree_map_data_at( \
593 private_array_tree_map_ins_or_assign_hndl.map, \
594 private_array_tree_map_ins_or_assign_hndl.index)) \
595 = type_compound_literal; \
596 private_array_tree_map_ins_or_assign_hndl_ret \
597 = (struct CCC_Handle){ \
599 = private_array_tree_map_ins_or_assign_hndl.index, \
601 = private_array_tree_map_ins_or_assign_hndl.status, \
603 *((typeof(private_array_tree_map_key) *) \
604 CCC_private_array_tree_map_key_at( \
605 private_array_tree_map_ins_or_assign_hndl.map, \
606 private_array_tree_map_ins_or_assign_hndl.index)) \
607 = private_array_tree_map_key; \
610 private_array_tree_map_ins_or_assign_hndl_ret; \
Definition: private_array_tree_map.h:161
CCC_Order last_order
Definition: private_array_tree_map.h:167
size_t index
Definition: private_array_tree_map.h:165
struct CCC_Array_tree_map * map
Definition: private_array_tree_map.h:163
CCC_Entry_status status
Definition: private_array_tree_map.h:169
Definition: private_array_tree_map.h:36
size_t parent
Definition: private_array_tree_map.h:42
size_t branch[2]
Definition: private_array_tree_map.h:38
size_t next_free
Definition: private_array_tree_map.h:44
Definition: private_array_tree_map.h:132
void * data
Definition: private_array_tree_map.h:134
unsigned * parity
Definition: private_array_tree_map.h:138
size_t sizeof_type
Definition: private_array_tree_map.h:148
size_t count
Definition: private_array_tree_map.h:146
size_t capacity
Definition: private_array_tree_map.h:144
size_t root
Definition: private_array_tree_map.h:140
size_t free_list
Definition: private_array_tree_map.h:142
void * context
Definition: private_array_tree_map.h:156
struct CCC_Array_tree_map_node * nodes
Definition: private_array_tree_map.h:136
CCC_Allocator * allocate
Definition: private_array_tree_map.h:154
size_t key_offset
Definition: private_array_tree_map.h:150
CCC_Key_comparator * compare
Definition: private_array_tree_map.h:152
CCC_Order
A three-way comparison for comparison functions.
Definition: types.h:171
CCC_Order CCC_Key_comparator(CCC_Key_comparator_context)
A callback function for three-way comparing two stored keys.
Definition: types.h:383
void * CCC_Allocator(CCC_Allocator_context)
An allocation function at the core of all containers.
Definition: types.h:340
Definition: private_array_tree_map.h:174
struct CCC_Array_tree_map_handle private
Definition: private_array_tree_map.h:176