23#ifndef CCC_PRIVATE_ARRAY_ADAPTIVE_MAP_H
24#define CCC_PRIVATE_ARRAY_ADAPTIVE_MAP_H
30#include "../../types.h"
144#define CCC_private_array_adaptive_map_compound_literal_array_capacity( \
145 private_type_compound_literal_array \
147 (sizeof(private_type_compound_literal_array) \
148 / sizeof(*(private_type_compound_literal_array)))
151#define CCC_private_array_adaptive_map_default( \
152 private_type_name, private_key_node_field, private_comparator... \
154 (struct CCC_Array_adaptive_map) { \
155 .sizeof_type = sizeof(private_type_name), \
156 .alignof_type = alignof(private_type_name), \
157 .key_offset = offsetof(private_type_name, private_key_node_field), \
158 .comparator = private_comparator, \
162#define CCC_private_array_adaptive_map_for( \
165 private_comparator, \
167 private_memory_pointer \
169 (struct CCC_Array_adaptive_map) { \
170 .data = (private_memory_pointer), .nodes = NULL, \
171 .capacity = (private_capacity), .count = 0, .root = 0, .free_list = 0, \
172 .sizeof_type = sizeof(private_type_name), \
173 .alignof_type = alignof(private_type_name), \
174 .key_offset = offsetof(private_type_name, private_key_field), \
175 .comparator = (private_comparator), \
179#define CCC_private_array_adaptive_map_from( \
181 private_comparator, \
183 private_optional_cap, \
184 private_array_compound_literal... \
186 (struct { struct CCC_Array_adaptive_map private; }){(__extension__({ \
187 typeof(*private_array_compound_literal) \
188 *private_array_adaptive_map_initializer_list \
189 = private_array_compound_literal; \
190 struct CCC_Array_adaptive_map private_array_adaptive_map \
191 = CCC_private_array_adaptive_map_default( \
192 typeof(*private_array_adaptive_map_initializer_list), \
196 size_t const private_array_adaptive_n \
197 = sizeof(private_array_compound_literal) \
198 / sizeof(*private_array_adaptive_map_initializer_list); \
199 size_t const private_cap = private_optional_cap; \
200 CCC_Allocator const *const private_array_adaptive_map_allocator \
201 = &(private_allocator); \
202 if (CCC_array_adaptive_map_reserve( \
203 &private_array_adaptive_map, \
204 (private_array_adaptive_n > private_cap \
205 ? private_array_adaptive_n \
207 private_array_adaptive_map_allocator \
209 == CCC_RESULT_OK) { \
210 for (size_t i = 0; i < private_array_adaptive_n; ++i) { \
211 struct CCC_Array_adaptive_map_handle \
212 private_array_adaptive_entry \
213 = CCC_private_array_adaptive_map_handle( \
214 &private_array_adaptive_map, \
217 )&private_array_adaptive_map_initializer_list[i] \
220 CCC_Handle_index private_index \
221 = private_array_adaptive_entry.index; \
222 if (!(private_array_adaptive_entry.status \
223 & CCC_ENTRY_OCCUPIED)) { \
225 = CCC_private_array_adaptive_map_allocate_slot( \
226 &private_array_adaptive_map, \
227 private_array_adaptive_map_allocator \
230 *((typeof(*private_array_adaptive_map_initializer_list) *) \
231 CCC_private_array_adaptive_map_data_at( \
232 private_array_adaptive_entry.map, private_index \
233 )) = private_array_adaptive_map_initializer_list[i]; \
234 if (!(private_array_adaptive_entry.status \
235 & CCC_ENTRY_OCCUPIED)) { \
236 CCC_private_array_adaptive_map_insert( \
237 private_array_adaptive_entry.map, private_index \
242 private_array_adaptive_map; \
246#define CCC_private_array_adaptive_map_with_capacity( \
249 private_comparator, \
253 (struct { struct CCC_Array_adaptive_map private; }){(__extension__({ \
254 struct CCC_Array_adaptive_map private_array_adaptive_map \
255 = CCC_private_array_adaptive_map_default( \
256 private_type_name, private_key_field, private_comparator \
258 (void)CCC_array_adaptive_map_reserve( \
259 &private_array_adaptive_map, private_cap, &(private_allocator) \
261 private_array_adaptive_map; \
267#define CCC_private_array_adaptive_map_storage_for( \
268 private_type_compound_literal_array, optional_storage_specifier... \
270 (optional_storage_specifier struct { \
272 CCC_private_array_adaptive_map_compound_literal_array_capacity( \
273 private_type_compound_literal_array \
275 "fixed size map must have capacity greater than 1" \
278 alignof(*(private_type_compound_literal_array)) \
279 > alignof(struct CCC_Array_adaptive_map_node) \
280 ? alignof(*(private_type_compound_literal_array)) \
281 : alignof(struct CCC_Array_adaptive_map_node) \
282 ) typeof(*(private_type_compound_literal_array)) data \
283 [CCC_private_array_adaptive_map_compound_literal_array_capacity( \
284 private_type_compound_literal_array \
286 struct CCC_Array_adaptive_map_node nodes \
287 [CCC_private_array_adaptive_map_compound_literal_array_capacity( \
288 private_type_compound_literal_array \
294#define CCC_private_array_adaptive_map_with_storage( \
295 private_key_node_field, \
296 private_comparator, \
297 private_compound_literal, \
298 private_optional_storage_specifier... \
300 (struct CCC_Array_adaptive_map) { \
301 .data = &CCC_private_array_adaptive_map_storage_for( \
302 private_compound_literal, private_optional_storage_specifier \
306 = CCC_private_array_adaptive_map_compound_literal_array_capacity( \
307 private_compound_literal \
309 .count = 0, .root = 0, .free_list = 0, \
310 .sizeof_type = sizeof(*(private_compound_literal)), \
311 .alignof_type = alignof(*(private_compound_literal)), \
312 .key_offset = offsetof( \
313 typeof(*(private_compound_literal)), private_key_node_field \
315 .comparator = (private_comparator), \
319#define CCC_private_array_adaptive_map_with_allocator_storage( \
321 private_comparator, \
323 private_compound_literal \
326 CCC_Allocator const *const private_allocator_pointer \
327 = &(private_allocator); \
328 void *private_data_base = NULL; \
329 if (private_allocator_pointer->allocate) { \
330 private_data_base = private_allocator_pointer->allocate(( \
331 CCC_Allocator_arguments \
334 .bytes = sizeof(CCC_private_array_adaptive_map_storage_for( \
335 private_compound_literal \
337 .alignment = alignof(struct CCC_Array_adaptive_map_node) \
338 > alignof(*(private_compound_literal)) \
339 ? alignof(struct CCC_Array_adaptive_map_node) \
340 : alignof(*(private_compound_literal)), \
341 .context = private_allocator_pointer->context, \
344 struct CCC_Array_adaptive_map private_array_adaptive_map = {}; \
345 if (private_data_base) { \
346 private_array_adaptive_map = CCC_private_array_adaptive_map_for( \
347 typeof(*(private_compound_literal)), \
349 private_comparator, \
350 CCC_private_array_adaptive_map_compound_literal_array_capacity( \
351 private_compound_literal \
356 private_array_adaptive_map = CCC_private_array_adaptive_map_for( \
357 typeof(*(private_compound_literal)), \
359 private_comparator, \
364 private_array_adaptive_map; \
368#define CCC_private_array_adaptive_map_as( \
369 array_adaptive_map_pointer, type_name, handle... \
371 ((type_name *)CCC_private_array_adaptive_map_data_at( \
372 (array_adaptive_map_pointer), (handle) \
378#define CCC_private_array_adaptive_map_and_modify_with( \
379 array_adaptive_map_handle_pointer, \
381 closure_over_closure_parameter... \
384 struct CCC_Array_adaptive_map_handle const *const \
385 private_array_adaptive_map_mod_hndl_pointer \
386 = (array_adaptive_map_handle_pointer); \
387 struct CCC_Array_adaptive_map_handle \
388 private_array_adaptive_map_mod_hndl \
389 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
390 if (private_array_adaptive_map_mod_hndl_pointer) { \
391 private_array_adaptive_map_mod_hndl \
392 = *private_array_adaptive_map_mod_hndl_pointer; \
393 if (private_array_adaptive_map_mod_hndl.status \
394 & CCC_ENTRY_OCCUPIED) { \
395 closure_parameter = CCC_private_array_adaptive_map_data_at( \
396 private_array_adaptive_map_mod_hndl.map, \
397 private_array_adaptive_map_mod_hndl.index \
399 closure_over_closure_parameter \
402 private_array_adaptive_map_mod_hndl; \
406#define CCC_private_array_adaptive_map_or_insert_with( \
407 array_adaptive_map_handle_pointer, \
408 private_allocator_pointer, \
409 type_compound_literal... \
412 struct CCC_Array_adaptive_map_handle const *const \
413 private_array_adaptive_map_or_ins_hndl_pointer \
414 = (array_adaptive_map_handle_pointer); \
415 CCC_Handle_index private_array_adaptive_map_or_ins_ret = 0; \
416 CCC_Allocator const *const private_array_adaptive_map_allocator \
417 = (private_allocator_pointer); \
418 if (private_array_adaptive_map_allocator \
419 && private_array_adaptive_map_or_ins_hndl_pointer) { \
420 if (private_array_adaptive_map_or_ins_hndl_pointer->status \
421 == CCC_ENTRY_OCCUPIED) { \
422 private_array_adaptive_map_or_ins_ret \
423 = private_array_adaptive_map_or_ins_hndl_pointer->index; \
425 private_array_adaptive_map_or_ins_ret \
426 = CCC_private_array_adaptive_map_allocate_slot( \
427 private_array_adaptive_map_or_ins_hndl_pointer->map, \
428 private_array_adaptive_map_allocator \
430 if (private_array_adaptive_map_or_ins_ret) { \
431 *((typeof(type_compound_literal) *) \
432 CCC_private_array_adaptive_map_data_at( \
433 private_array_adaptive_map_or_ins_hndl_pointer \
435 private_array_adaptive_map_or_ins_ret \
436 )) = type_compound_literal; \
437 CCC_private_array_adaptive_map_insert( \
438 private_array_adaptive_map_or_ins_hndl_pointer->map, \
439 private_array_adaptive_map_or_ins_ret \
444 private_array_adaptive_map_or_ins_ret; \
448#define CCC_private_array_adaptive_map_insert_handle_with( \
449 array_adaptive_map_handle_pointer, \
450 private_allocator_pointer, \
451 type_compound_literal... \
454 struct CCC_Array_adaptive_map_handle const *const \
455 private_array_adaptive_map_ins_hndl_pointer \
456 = (array_adaptive_map_handle_pointer); \
457 CCC_Handle_index private_array_adaptive_map_ins_hndl_ret = 0; \
458 CCC_Allocator const *const private_array_adaptive_map_allocator \
459 = (private_allocator_pointer); \
460 if (private_array_adaptive_map_allocator \
461 && private_array_adaptive_map_ins_hndl_pointer) { \
462 if (!(private_array_adaptive_map_ins_hndl_pointer->status \
463 & CCC_ENTRY_OCCUPIED)) { \
464 private_array_adaptive_map_ins_hndl_ret \
465 = CCC_private_array_adaptive_map_allocate_slot( \
466 private_array_adaptive_map_ins_hndl_pointer->map, \
467 private_array_adaptive_map_allocator \
469 if (private_array_adaptive_map_ins_hndl_ret) { \
470 *((typeof(type_compound_literal) *) \
471 CCC_private_array_adaptive_map_data_at( \
472 private_array_adaptive_map_ins_hndl_pointer \
474 private_array_adaptive_map_ins_hndl_ret \
475 )) = type_compound_literal; \
476 CCC_private_array_adaptive_map_insert( \
477 private_array_adaptive_map_ins_hndl_pointer->map, \
478 private_array_adaptive_map_ins_hndl_ret \
481 } else if (private_array_adaptive_map_ins_hndl_pointer->status \
482 == CCC_ENTRY_OCCUPIED) { \
483 *((typeof(type_compound_literal) *) \
484 CCC_private_array_adaptive_map_data_at( \
485 private_array_adaptive_map_ins_hndl_pointer->map, \
486 private_array_adaptive_map_ins_hndl_pointer->index \
487 )) = type_compound_literal; \
488 private_array_adaptive_map_ins_hndl_ret \
489 = private_array_adaptive_map_ins_hndl_pointer->index; \
492 private_array_adaptive_map_ins_hndl_ret; \
496#define CCC_private_array_adaptive_map_try_insert_with( \
497 array_adaptive_map_pointer, \
499 private_allocator_pointer, \
500 type_compound_literal... \
503 struct CCC_Array_adaptive_map *const \
504 private_array_adaptive_map_try_ins_map_pointer \
505 = (array_adaptive_map_pointer); \
506 CCC_Handle private_array_adaptive_map_try_ins_hndl_ret \
507 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
508 CCC_Allocator const *const private_array_adaptive_map_allocator \
509 = (private_allocator_pointer); \
510 if (private_array_adaptive_map_allocator \
511 && private_array_adaptive_map_try_ins_map_pointer) { \
512 __auto_type private_array_adaptive_map_key = (key); \
513 struct CCC_Array_adaptive_map_handle \
514 private_array_adaptive_map_try_ins_hndl \
515 = CCC_private_array_adaptive_map_handle( \
516 private_array_adaptive_map_try_ins_map_pointer, \
517 (void *)&private_array_adaptive_map_key \
519 if (!(private_array_adaptive_map_try_ins_hndl.status \
520 & CCC_ENTRY_OCCUPIED)) { \
521 private_array_adaptive_map_try_ins_hndl_ret = (CCC_Handle){ \
522 .index = CCC_private_array_adaptive_map_allocate_slot( \
523 private_array_adaptive_map_try_ins_hndl.map, \
524 private_array_adaptive_map_allocator \
526 .status = CCC_ENTRY_INSERT_ERROR, \
528 if (private_array_adaptive_map_try_ins_hndl_ret.index) { \
529 *((typeof(type_compound_literal) *) \
530 CCC_private_array_adaptive_map_data_at( \
531 private_array_adaptive_map_try_ins_map_pointer, \
532 private_array_adaptive_map_try_ins_hndl_ret \
534 )) = type_compound_literal; \
535 *((typeof(private_array_adaptive_map_key) *) \
536 CCC_private_array_adaptive_map_key_at( \
537 private_array_adaptive_map_try_ins_hndl.map, \
538 private_array_adaptive_map_try_ins_hndl_ret \
540 )) = private_array_adaptive_map_key; \
541 CCC_private_array_adaptive_map_insert( \
542 private_array_adaptive_map_try_ins_hndl.map, \
543 private_array_adaptive_map_try_ins_hndl_ret.index \
545 private_array_adaptive_map_try_ins_hndl_ret.status \
546 = CCC_ENTRY_VACANT; \
548 } else if (private_array_adaptive_map_try_ins_hndl.status \
549 == CCC_ENTRY_OCCUPIED) { \
550 private_array_adaptive_map_try_ins_hndl_ret = (CCC_Handle){ \
551 .index = private_array_adaptive_map_try_ins_hndl.index, \
552 .status = private_array_adaptive_map_try_ins_hndl.status}; \
555 private_array_adaptive_map_try_ins_hndl_ret; \
559#define CCC_private_array_adaptive_map_insert_or_assign_with( \
560 array_adaptive_map_pointer, \
562 private_allocator_pointer, \
563 type_compound_literal... \
566 struct CCC_Array_adaptive_map *const \
567 private_array_adaptive_map_ins_or_assign_map_pointer \
568 = (array_adaptive_map_pointer); \
569 CCC_Handle private_array_adaptive_map_ins_or_assign_hndl_ret \
570 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
571 CCC_Allocator const *const private_array_adaptive_map_allocator \
572 = (private_allocator_pointer); \
573 if (private_array_adaptive_map_allocator \
574 && private_array_adaptive_map_ins_or_assign_map_pointer) { \
575 __auto_type private_array_adaptive_map_key = (key); \
576 struct CCC_Array_adaptive_map_handle \
577 private_array_adaptive_map_ins_or_assign_hndl \
578 = CCC_private_array_adaptive_map_handle( \
579 private_array_adaptive_map_ins_or_assign_map_pointer, \
580 (void *)&private_array_adaptive_map_key \
582 if (!(private_array_adaptive_map_ins_or_assign_hndl.status \
583 & CCC_ENTRY_OCCUPIED)) { \
584 private_array_adaptive_map_ins_or_assign_hndl_ret \
586 .index = CCC_private_array_adaptive_map_allocate_slot( \
587 private_array_adaptive_map_ins_or_assign_hndl.map, \
588 private_array_adaptive_map_allocator \
590 .status = CCC_ENTRY_INSERT_ERROR, \
592 if (private_array_adaptive_map_ins_or_assign_hndl_ret.index) { \
593 *((typeof(type_compound_literal) *) \
594 CCC_private_array_adaptive_map_data_at( \
595 private_array_adaptive_map_ins_or_assign_map_pointer, \
596 private_array_adaptive_map_ins_or_assign_hndl_ret \
598 )) = type_compound_literal; \
599 *((typeof(private_array_adaptive_map_key) *) \
600 CCC_private_array_adaptive_map_key_at( \
601 private_array_adaptive_map_ins_or_assign_hndl \
603 private_array_adaptive_map_ins_or_assign_hndl_ret \
605 )) = private_array_adaptive_map_key; \
606 CCC_private_array_adaptive_map_insert( \
607 private_array_adaptive_map_ins_or_assign_hndl.map, \
608 private_array_adaptive_map_ins_or_assign_hndl_ret \
611 private_array_adaptive_map_ins_or_assign_hndl_ret.status \
612 = CCC_ENTRY_VACANT; \
614 } else if (private_array_adaptive_map_ins_or_assign_hndl.status \
615 == CCC_ENTRY_OCCUPIED) { \
616 *((typeof(type_compound_literal) *) \
617 CCC_private_array_adaptive_map_data_at( \
618 private_array_adaptive_map_ins_or_assign_hndl.map, \
619 private_array_adaptive_map_ins_or_assign_hndl.index \
620 )) = type_compound_literal; \
621 private_array_adaptive_map_ins_or_assign_hndl_ret \
624 = private_array_adaptive_map_ins_or_assign_hndl.index, \
626 = private_array_adaptive_map_ins_or_assign_hndl \
629 *((typeof(private_array_adaptive_map_key) *) \
630 CCC_private_array_adaptive_map_key_at( \
631 private_array_adaptive_map_ins_or_assign_hndl.map, \
632 private_array_adaptive_map_ins_or_assign_hndl.index \
633 )) = private_array_adaptive_map_key; \
636 private_array_adaptive_map_ins_or_assign_hndl_ret; \
struct CCC_Array_adaptive_map_handle CCC_private_array_adaptive_map_handle(struct CCC_Array_adaptive_map *, void const *key)
void * CCC_private_array_adaptive_map_key_at(struct CCC_Array_adaptive_map const *, size_t slot)
void * CCC_private_array_adaptive_map_data_at(struct CCC_Array_adaptive_map const *, size_t slot)
size_t CCC_private_array_adaptive_map_allocate_slot(struct CCC_Array_adaptive_map *, CCC_Allocator const *)
void CCC_private_array_adaptive_map_insert(struct CCC_Array_adaptive_map *, size_t)
The type passed by reference to any container function that may need to allocate memory....
Definition: types.h:384
Definition: private_array_adaptive_map.h:108
CCC_Order last_order
Definition: private_array_adaptive_map.h:114
CCC_Entry_status status
Definition: private_array_adaptive_map.h:116
size_t index
Definition: private_array_adaptive_map.h:112
struct CCC_Array_adaptive_map * map
Definition: private_array_adaptive_map.h:110
Definition: private_array_adaptive_map.h:39
size_t branch[2]
Definition: private_array_adaptive_map.h:41
size_t next_free
Definition: private_array_adaptive_map.h:46
size_t parent
Definition: private_array_adaptive_map.h:44
Definition: private_array_adaptive_map.h:83
size_t alignof_type
Definition: private_array_adaptive_map.h:99
size_t free_list
Definition: private_array_adaptive_map.h:95
size_t count
Definition: private_array_adaptive_map.h:91
void * data
Definition: private_array_adaptive_map.h:85
size_t sizeof_type
Definition: private_array_adaptive_map.h:97
size_t root
Definition: private_array_adaptive_map.h:93
CCC_Key_comparator comparator
Definition: private_array_adaptive_map.h:103
struct CCC_Array_adaptive_map_node * nodes
Definition: private_array_adaptive_map.h:87
size_t capacity
Definition: private_array_adaptive_map.h:89
size_t key_offset
Definition: private_array_adaptive_map.h:101
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