C Container Collection (CCC)
Loading...
Searching...
No Matches
private_array_adaptive_map.h
Go to the documentation of this file.
1
23#ifndef CCC_PRIVATE_ARRAY_ADAPTIVE_MAP_H
24#define CCC_PRIVATE_ARRAY_ADAPTIVE_MAP_H
25
27#include <stddef.h>
30#include "../../types.h" /* IWYU pragma: keep */
31
32/* NOLINTBEGIN(readability-identifier-naming) */
33
41 size_t branch[2];
42 union {
44 size_t parent;
46 size_t next_free;
47 };
48};
49
85 void *data;
89 size_t capacity;
91 size_t count;
93 size_t root;
95 size_t free_list;
104};
105
112 size_t index;
117};
118
119/*=========================== Private Interface ===========================*/
120
122void
126 struct CCC_Array_adaptive_map *, void const *key
127);
130 struct CCC_Array_adaptive_map const *, size_t slot
131);
134 struct CCC_Array_adaptive_map const *, size_t slot
135);
138 struct CCC_Array_adaptive_map *, CCC_Allocator const *
139);
140
141/*======================== Initialization =========================*/
142
144#define CCC_private_array_adaptive_map_compound_literal_array_capacity( \
145 private_type_compound_literal_array \
146) \
147 (sizeof(private_type_compound_literal_array) \
148 / sizeof(*(private_type_compound_literal_array)))
149
151#define CCC_private_array_adaptive_map_default( \
152 private_type_name, private_key_node_field, private_comparator... \
153) \
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, \
159 }
160
162#define CCC_private_array_adaptive_map_for( \
163 private_type_name, \
164 private_key_field, \
165 private_comparator, \
166 private_capacity, \
167 private_memory_pointer \
168) \
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), \
176 }
177
179#define CCC_private_array_adaptive_map_from( \
180 private_key_field, \
181 private_comparator, \
182 private_allocator, \
183 private_optional_cap, \
184 private_array_compound_literal... \
185) \
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), \
193 private_key_field, \
194 private_comparator \
195 ); \
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 \
206 : private_cap), \
207 private_array_adaptive_map_allocator \
208 ) \
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, \
215 ( \
216 void const * \
217 )&private_array_adaptive_map_initializer_list[i] \
218 .private_key_field \
219 ); \
220 CCC_Handle_index private_index \
221 = private_array_adaptive_entry.index; \
222 if (!(private_array_adaptive_entry.status \
223 & CCC_ENTRY_OCCUPIED)) { \
224 private_index \
225 = CCC_private_array_adaptive_map_allocate_slot( \
226 &private_array_adaptive_map, \
227 private_array_adaptive_map_allocator \
228 ); \
229 } \
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 \
238 ); \
239 } \
240 } \
241 } \
242 private_array_adaptive_map; \
243 }))}.private
244
246#define CCC_private_array_adaptive_map_with_capacity( \
247 private_type_name, \
248 private_key_field, \
249 private_comparator, \
250 private_allocator, \
251 private_cap \
252) \
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 \
257 ); \
258 (void)CCC_array_adaptive_map_reserve( \
259 &private_array_adaptive_map, private_cap, &(private_allocator) \
260 ); \
261 private_array_adaptive_map; \
262 }))}.private
263
267#define CCC_private_array_adaptive_map_storage_for( \
268 private_type_compound_literal_array, optional_storage_specifier... \
269) \
270 (optional_storage_specifier struct { \
271 static_assert( \
272 CCC_private_array_adaptive_map_compound_literal_array_capacity( \
273 private_type_compound_literal_array \
274 ) > 1, \
275 "fixed size map must have capacity greater than 1" \
276 ); \
277 alignas( \
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 \
285 )]; \
286 struct CCC_Array_adaptive_map_node nodes \
287 [CCC_private_array_adaptive_map_compound_literal_array_capacity( \
288 private_type_compound_literal_array \
289 )]; \
290 }) { \
291 }
292
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... \
299) \
300 (struct CCC_Array_adaptive_map) { \
301 .data = &CCC_private_array_adaptive_map_storage_for( \
302 private_compound_literal, private_optional_storage_specifier \
303 ), \
304 .nodes = NULL, \
305 .capacity \
306 = CCC_private_array_adaptive_map_compound_literal_array_capacity( \
307 private_compound_literal \
308 ), \
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 \
314 ), \
315 .comparator = (private_comparator), \
316 }
317
319#define CCC_private_array_adaptive_map_with_allocator_storage( \
320 private_key_field, \
321 private_comparator, \
322 private_allocator, \
323 private_compound_literal \
324) \
325 (__extension__({ \
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 \
332 ){ \
333 .input = NULL, \
334 .bytes = sizeof(CCC_private_array_adaptive_map_storage_for( \
335 private_compound_literal \
336 )), \
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, \
342 }); \
343 } \
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)), \
348 private_key_field, \
349 private_comparator, \
350 CCC_private_array_adaptive_map_compound_literal_array_capacity( \
351 private_compound_literal \
352 ), \
353 private_data_base \
354 ); \
355 } else { \
356 private_array_adaptive_map = CCC_private_array_adaptive_map_for( \
357 typeof(*(private_compound_literal)), \
358 private_key_field, \
359 private_comparator, \
360 0, \
361 NULL \
362 ); \
363 } \
364 private_array_adaptive_map; \
365 }))
366
368#define CCC_private_array_adaptive_map_as( \
369 array_adaptive_map_pointer, type_name, handle... \
370) \
371 ((type_name *)CCC_private_array_adaptive_map_data_at( \
372 (array_adaptive_map_pointer), (handle) \
373 ))
374
375/*================== Core Macro Implementations =====================*/
376
378#define CCC_private_array_adaptive_map_and_modify_with( \
379 array_adaptive_map_handle_pointer, \
380 closure_parameter, \
381 closure_over_closure_parameter... \
382) \
383 (__extension__({ \
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 \
398 ); \
399 closure_over_closure_parameter \
400 } \
401 } \
402 private_array_adaptive_map_mod_hndl; \
403 }))
404
406#define CCC_private_array_adaptive_map_or_insert_with( \
407 array_adaptive_map_handle_pointer, \
408 private_allocator_pointer, \
409 type_compound_literal... \
410) \
411 (__extension__({ \
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; \
424 } else { \
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 \
429 ); \
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 \
434 ->map, \
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 \
440 ); \
441 } \
442 } \
443 } \
444 private_array_adaptive_map_or_ins_ret; \
445 }))
446
448#define CCC_private_array_adaptive_map_insert_handle_with( \
449 array_adaptive_map_handle_pointer, \
450 private_allocator_pointer, \
451 type_compound_literal... \
452) \
453 (__extension__({ \
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 \
468 ); \
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 \
473 ->map, \
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 \
479 ); \
480 } \
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; \
490 } \
491 } \
492 private_array_adaptive_map_ins_hndl_ret; \
493 }))
494
496#define CCC_private_array_adaptive_map_try_insert_with( \
497 array_adaptive_map_pointer, \
498 key, \
499 private_allocator_pointer, \
500 type_compound_literal... \
501) \
502 (__extension__({ \
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 \
518 ); \
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 \
525 ), \
526 .status = CCC_ENTRY_INSERT_ERROR, \
527 }; \
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 \
533 .index \
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 \
539 .index \
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 \
544 ); \
545 private_array_adaptive_map_try_ins_hndl_ret.status \
546 = CCC_ENTRY_VACANT; \
547 } \
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}; \
553 } \
554 } \
555 private_array_adaptive_map_try_ins_hndl_ret; \
556 }))
557
559#define CCC_private_array_adaptive_map_insert_or_assign_with( \
560 array_adaptive_map_pointer, \
561 key, \
562 private_allocator_pointer, \
563 type_compound_literal... \
564) \
565 (__extension__({ \
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 \
581 ); \
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 \
585 = (CCC_Handle){ \
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 \
589 ), \
590 .status = CCC_ENTRY_INSERT_ERROR, \
591 }; \
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 \
597 .index \
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 \
602 .map, \
603 private_array_adaptive_map_ins_or_assign_hndl_ret \
604 .index \
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 \
609 .index \
610 ); \
611 private_array_adaptive_map_ins_or_assign_hndl_ret.status \
612 = CCC_ENTRY_VACANT; \
613 } \
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 \
622 = (CCC_Handle){ \
623 .index \
624 = private_array_adaptive_map_ins_or_assign_hndl.index, \
625 .status \
626 = private_array_adaptive_map_ins_or_assign_hndl \
627 .status, \
628 }; \
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; \
634 } \
635 } \
636 private_array_adaptive_map_ins_or_assign_hndl_ret; \
637 }))
638
639/* NOLINTEND(readability-identifier-naming) */
640
641#endif /* CCC_PRIVATE_ARRAY_ADAPTIVE_MAP_H */
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