C Container Collection (CCC)
Loading...
Searching...
No Matches
private_array_tree_map.h
1
16#ifndef CCC_PRIVATE_ARRAY_TREE_MAP_H
17#define CCC_PRIVATE_ARRAY_TREE_MAP_H
18
20#include <limits.h>
21#include <stddef.h>
22#include <stdint.h>
25#include "../types.h"
26
27/* NOLINTBEGIN(readability-identifier-naming) */
28
36 size_t branch[2];
37 union {
39 size_t parent;
41 size_t next_free;
42 };
43};
44
135 void *data;
139 unsigned *parity;
141 size_t root;
143 size_t free_list;
145 size_t capacity;
147 size_t count;
154};
155
161 size_t index;
166};
167
168/*======================== Private Interface ==============================*/
169
171void *
172CCC_private_array_tree_map_data_at(struct CCC_Array_tree_map const *, size_t);
174void *
175CCC_private_array_tree_map_key_at(struct CCC_Array_tree_map const *, size_t);
177struct CCC_Array_tree_map_handle CCC_private_array_tree_map_handle(
178 struct CCC_Array_tree_map const *, void const *
179);
181void CCC_private_array_tree_map_insert(
182 struct CCC_Array_tree_map *, size_t, CCC_Order, size_t
183);
185size_t CCC_private_array_tree_map_allocate_slot(
186 struct CCC_Array_tree_map *, CCC_Allocator const *
187);
188
189/*========================= Initialization =========================*/
190
194#define CCC_private_array_tree_map_blocks(private_cap) \
195 (((private_cap) \
196 + ((sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT) - 1)) \
197 / (sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT))
198
200#define CCC_private_array_tree_map_compound_literal_array_capacity( \
201 private_type_compound_literal_array \
202) \
203 (sizeof(private_type_compound_literal_array) \
204 / sizeof(*(private_type_compound_literal_array)))
205
209#define CCC_private_array_tree_map_storage_for( \
210 private_type_compound_literal_array, optional_storage_specifier... \
211) \
212 (optional_storage_specifier struct { \
213 static_assert( \
214 CCC_private_array_tree_map_compound_literal_array_capacity( \
215 private_type_compound_literal_array \
216 ) > 1, \
217 "fixed size map must have capacity greater than 1" \
218 ); \
219 typeof(*(private_type_compound_literal_array)) \
220 data[CCC_private_array_tree_map_compound_literal_array_capacity( \
221 private_type_compound_literal_array \
222 )]; \
223 struct CCC_Array_tree_map_node \
224 nodes[CCC_private_array_tree_map_compound_literal_array_capacity( \
225 private_type_compound_literal_array \
226 )]; \
227 typeof(*(struct CCC_Array_tree_map){}.parity) \
228 parity[CCC_private_array_tree_map_blocks( \
229 CCC_private_array_tree_map_compound_literal_array_capacity( \
230 private_type_compound_literal_array \
231 ) \
232 )]; \
233 }) { \
234 }
235
237#define CCC_private_array_tree_map_default( \
238 private_type_name, private_key_field, private_comparator... \
239) \
240 (struct CCC_Array_tree_map) { \
241 .sizeof_type = sizeof(private_type_name), \
242 .key_offset = offsetof(private_type_name, private_key_field), \
243 .comparator = (private_comparator), \
244 }
245
251#define CCC_private_array_tree_map_for( \
252 private_type_name, \
253 private_key_field, \
254 private_comparator, \
255 private_capacity, \
256 private_memory_pointer \
257) \
258 (struct CCC_Array_tree_map) { \
259 .data = (private_memory_pointer), .nodes = NULL, .parity = NULL, \
260 .capacity = (private_capacity), .count = 0, .root = 0, .free_list = 0, \
261 .sizeof_type = sizeof(private_type_name), \
262 .key_offset = offsetof(private_type_name, private_key_field), \
263 .comparator = (private_comparator), \
264 }
265
267#define CCC_private_array_tree_map_from( \
268 private_key_field, \
269 private_comparator, \
270 private_allocator, \
271 private_optional_cap, \
272 private_array_compound_literal... \
273) \
274 (struct { struct CCC_Array_tree_map private; }){(__extension__({ \
275 typeof(*private_array_compound_literal) \
276 *private_array_tree_map_initializer_list \
277 = private_array_compound_literal; \
278 struct CCC_Array_tree_map private_array_tree_map \
279 = CCC_private_array_tree_map_default( \
280 typeof(*private_array_tree_map_initializer_list), \
281 private_key_field, \
282 private_comparator \
283 ); \
284 size_t const private_array_tree_n \
285 = sizeof(private_array_compound_literal) \
286 / sizeof(*private_array_tree_map_initializer_list); \
287 size_t const private_cap = private_optional_cap; \
288 CCC_Allocator const *const private_array_tree_map_allocator \
289 = &(private_allocator); \
290 if (CCC_array_tree_map_reserve( \
291 &private_array_tree_map, \
292 (private_array_tree_n > private_cap ? private_array_tree_n \
293 : private_cap), \
294 private_array_tree_map_allocator \
295 ) \
296 == CCC_RESULT_OK) { \
297 for (size_t i = 0; i < private_array_tree_n; ++i) { \
298 struct CCC_Array_tree_map_handle private_array_tree_entry \
299 = CCC_private_array_tree_map_handle( \
300 &private_array_tree_map, \
301 ( \
302 void const * \
303 )&private_array_tree_map_initializer_list[i] \
304 .private_key_field \
305 ); \
306 CCC_Handle_index private_index \
307 = private_array_tree_entry.index; \
308 if (!(private_array_tree_entry.status & CCC_ENTRY_OCCUPIED)) { \
309 private_index = CCC_private_array_tree_map_allocate_slot( \
310 &private_array_tree_map, \
311 private_array_tree_map_allocator \
312 ); \
313 } \
314 *((typeof(*private_array_tree_map_initializer_list) *) \
315 CCC_private_array_tree_map_data_at( \
316 private_array_tree_entry.map, private_index \
317 )) = private_array_tree_map_initializer_list[i]; \
318 if (!(private_array_tree_entry.status & CCC_ENTRY_OCCUPIED)) { \
319 CCC_private_array_tree_map_insert( \
320 private_array_tree_entry.map, \
321 private_array_tree_entry.index, \
322 private_array_tree_entry.last_order, \
323 private_index \
324 ); \
325 } \
326 } \
327 } \
328 private_array_tree_map; \
329 }))}.private
330
332#define CCC_private_array_tree_map_with_capacity( \
333 private_type_name, \
334 private_key_field, \
335 private_comparator, \
336 private_allocator, \
337 private_cap \
338) \
339 (struct { struct CCC_Array_tree_map private; }){(__extension__({ \
340 struct CCC_Array_tree_map private_array_tree_map \
341 = CCC_private_array_tree_map_default( \
342 private_type_name, private_key_field, private_comparator \
343 ); \
344 (void)CCC_array_tree_map_reserve( \
345 &private_array_tree_map, private_cap, &(private_allocator) \
346 ); \
347 private_array_tree_map; \
348 }))}.private
349
351#define CCC_private_array_tree_map_with_storage( \
352 private_key_node_field, \
353 private_comparator, \
354 private_compound_literal, \
355 private_optional_storage_specifier... \
356) \
357 (struct CCC_Array_tree_map) { \
358 .data = &CCC_private_array_tree_map_storage_for( \
359 private_compound_literal, private_optional_storage_specifier \
360 ), \
361 .nodes = NULL, .parity = NULL, \
362 .capacity \
363 = CCC_private_array_tree_map_compound_literal_array_capacity( \
364 private_compound_literal \
365 ), \
366 .count = 0, .root = 0, .free_list = 0, \
367 .sizeof_type = sizeof(*(private_compound_literal)), \
368 .key_offset = offsetof( \
369 typeof(*(private_compound_literal)), private_key_node_field \
370 ), \
371 .comparator = (private_comparator), \
372 }
373
375#define CCC_private_array_tree_map_as( \
376 array_tree_map_pointer, type_name, handle... \
377) \
378 ((type_name *)CCC_private_array_tree_map_data_at( \
379 (array_tree_map_pointer), (handle) \
380 ))
381
382/*================== Core Macro Implementations =====================*/
383
385#define CCC_private_array_tree_map_and_modify_with( \
386 array_tree_map_handle_pointer, \
387 closure_parameter, \
388 closure_over_closure_parameter... \
389) \
390 (__extension__({ \
391 struct CCC_Array_tree_map_handle const *const \
392 private_array_tree_map_hndl_pointer \
393 = (array_tree_map_handle_pointer); \
394 struct CCC_Array_tree_map_handle private_array_tree_map_mod_hndl \
395 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
396 if (private_array_tree_map_hndl_pointer) { \
397 private_array_tree_map_mod_hndl \
398 = *private_array_tree_map_hndl_pointer; \
399 if (private_array_tree_map_mod_hndl.status & CCC_ENTRY_OCCUPIED) { \
400 closure_parameter = CCC_private_array_tree_map_data_at( \
401 private_array_tree_map_mod_hndl.map, \
402 private_array_tree_map_mod_hndl.index \
403 ); \
404 closure_over_closure_parameter \
405 } \
406 } \
407 private_array_tree_map_mod_hndl; \
408 }))
409
411#define CCC_private_array_tree_map_or_insert_with( \
412 array_tree_map_handle_pointer, \
413 private_allocator_pointer, \
414 type_compound_literal... \
415) \
416 (__extension__({ \
417 struct CCC_Array_tree_map_handle const *const \
418 private_or_ins_handle_pointer = (array_tree_map_handle_pointer); \
419 CCC_Handle_index private_array_tree_map_or_ins_ret = 0; \
420 CCC_Allocator const *const private_array_tree_map_allocator \
421 = (private_allocator_pointer); \
422 if (private_array_tree_map_allocator \
423 && private_or_ins_handle_pointer) { \
424 if (private_or_ins_handle_pointer->status == CCC_ENTRY_OCCUPIED) { \
425 private_array_tree_map_or_ins_ret \
426 = private_or_ins_handle_pointer->index; \
427 } else { \
428 private_array_tree_map_or_ins_ret \
429 = CCC_private_array_tree_map_allocate_slot( \
430 private_or_ins_handle_pointer->map, \
431 private_array_tree_map_allocator \
432 ); \
433 if (private_array_tree_map_or_ins_ret) { \
434 *((typeof(type_compound_literal) *) \
435 CCC_private_array_tree_map_data_at( \
436 private_or_ins_handle_pointer->map, \
437 private_array_tree_map_or_ins_ret \
438 )) = type_compound_literal; \
439 CCC_private_array_tree_map_insert( \
440 private_or_ins_handle_pointer->map, \
441 private_or_ins_handle_pointer->index, \
442 private_or_ins_handle_pointer->last_order, \
443 private_array_tree_map_or_ins_ret \
444 ); \
445 } \
446 } \
447 } \
448 private_array_tree_map_or_ins_ret; \
449 }))
450
452#define CCC_private_array_tree_map_insert_handle_with( \
453 array_tree_map_handle_pointer, \
454 private_allocator_pointer, \
455 type_compound_literal... \
456) \
457 (__extension__({ \
458 struct CCC_Array_tree_map_handle const *const \
459 private_ins_handle_pointer = (array_tree_map_handle_pointer); \
460 CCC_Handle_index private_array_tree_map_ins_hndl_ret = 0; \
461 CCC_Allocator const *const private_array_tree_map_allocator \
462 = (private_allocator_pointer); \
463 if (private_array_tree_map_allocator && private_ins_handle_pointer) { \
464 if (!(private_ins_handle_pointer->status & CCC_ENTRY_OCCUPIED)) { \
465 private_array_tree_map_ins_hndl_ret \
466 = CCC_private_array_tree_map_allocate_slot( \
467 private_ins_handle_pointer->map, \
468 private_array_tree_map_allocator \
469 ); \
470 if (private_array_tree_map_ins_hndl_ret) { \
471 *((typeof(type_compound_literal) *) \
472 CCC_private_array_tree_map_data_at( \
473 private_ins_handle_pointer->map, \
474 private_array_tree_map_ins_hndl_ret \
475 )) = type_compound_literal; \
476 CCC_private_array_tree_map_insert( \
477 private_ins_handle_pointer->map, \
478 private_ins_handle_pointer->index, \
479 private_ins_handle_pointer->last_order, \
480 private_array_tree_map_ins_hndl_ret \
481 ); \
482 } \
483 } else if (private_ins_handle_pointer->status \
484 == CCC_ENTRY_OCCUPIED) { \
485 private_array_tree_map_ins_hndl_ret \
486 = private_ins_handle_pointer->index; \
487 *((typeof(type_compound_literal) *) \
488 CCC_private_array_tree_map_data_at( \
489 private_ins_handle_pointer->map, \
490 private_array_tree_map_ins_hndl_ret \
491 )) = type_compound_literal; \
492 } \
493 } \
494 private_array_tree_map_ins_hndl_ret; \
495 }))
496
498#define CCC_private_array_tree_map_try_insert_with( \
499 array_tree_map_pointer, \
500 key, \
501 private_allocator_pointer, \
502 type_compound_literal... \
503) \
504 (__extension__({ \
505 struct CCC_Array_tree_map *const private_try_ins_map_pointer \
506 = (array_tree_map_pointer); \
507 CCC_Handle private_array_tree_map_try_ins_hndl_ret \
508 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
509 CCC_Allocator const *const private_array_tree_map_allocator \
510 = (private_allocator_pointer); \
511 if (private_array_tree_map_allocator && private_try_ins_map_pointer) { \
512 __auto_type private_array_tree_map_key = (key); \
513 struct CCC_Array_tree_map_handle \
514 private_array_tree_map_try_ins_hndl \
515 = CCC_private_array_tree_map_handle( \
516 private_try_ins_map_pointer, \
517 (void *)&private_array_tree_map_key \
518 ); \
519 if (!(private_array_tree_map_try_ins_hndl.status \
520 & CCC_ENTRY_OCCUPIED)) { \
521 private_array_tree_map_try_ins_hndl_ret = (CCC_Handle){ \
522 .index = CCC_private_array_tree_map_allocate_slot( \
523 private_array_tree_map_try_ins_hndl.map, \
524 private_array_tree_map_allocator \
525 ), \
526 .status = CCC_ENTRY_INSERT_ERROR, \
527 }; \
528 if (private_array_tree_map_try_ins_hndl_ret.index) { \
529 *((typeof(type_compound_literal) *) \
530 CCC_private_array_tree_map_data_at( \
531 private_try_ins_map_pointer, \
532 private_array_tree_map_try_ins_hndl_ret.index \
533 )) = type_compound_literal; \
534 *((typeof(private_array_tree_map_key) *) \
535 CCC_private_array_tree_map_key_at( \
536 private_try_ins_map_pointer, \
537 private_array_tree_map_try_ins_hndl_ret.index \
538 )) = private_array_tree_map_key; \
539 CCC_private_array_tree_map_insert( \
540 private_array_tree_map_try_ins_hndl.map, \
541 private_array_tree_map_try_ins_hndl.index, \
542 private_array_tree_map_try_ins_hndl.last_order, \
543 private_array_tree_map_try_ins_hndl_ret.index \
544 ); \
545 private_array_tree_map_try_ins_hndl_ret.status \
546 = CCC_ENTRY_VACANT; \
547 } \
548 } else if (private_array_tree_map_try_ins_hndl.status \
549 == CCC_ENTRY_OCCUPIED) { \
550 private_array_tree_map_try_ins_hndl_ret = (CCC_Handle){ \
551 .index = private_array_tree_map_try_ins_hndl.index, \
552 .status = private_array_tree_map_try_ins_hndl.status, \
553 }; \
554 } \
555 } \
556 private_array_tree_map_try_ins_hndl_ret; \
557 }))
558
560#define CCC_private_array_tree_map_insert_or_assign_with( \
561 array_tree_map_pointer, \
562 key, \
563 private_allocator_pointer, \
564 type_compound_literal... \
565) \
566 (__extension__({ \
567 struct CCC_Array_tree_map *const private_ins_or_assign_map_pointer \
568 = (array_tree_map_pointer); \
569 CCC_Handle private_array_tree_map_ins_or_assign_hndl_ret \
570 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
571 CCC_Allocator const *const private_array_tree_map_allocator \
572 = (private_allocator_pointer); \
573 if (private_array_tree_map_allocator \
574 && private_ins_or_assign_map_pointer) { \
575 __auto_type private_array_tree_map_key = (key); \
576 struct CCC_Array_tree_map_handle \
577 private_array_tree_map_ins_or_assign_hndl \
578 = CCC_private_array_tree_map_handle( \
579 private_ins_or_assign_map_pointer, \
580 (void *)&private_array_tree_map_key \
581 ); \
582 if (!(private_array_tree_map_ins_or_assign_hndl.status \
583 & CCC_ENTRY_OCCUPIED)) { \
584 private_array_tree_map_ins_or_assign_hndl_ret = (CCC_Handle){ \
585 .index = CCC_private_array_tree_map_allocate_slot( \
586 private_array_tree_map_ins_or_assign_hndl.map, \
587 private_array_tree_map_allocator \
588 ), \
589 .status = CCC_ENTRY_INSERT_ERROR, \
590 }; \
591 if (private_array_tree_map_ins_or_assign_hndl_ret.index) { \
592 *((typeof(type_compound_literal) *) \
593 CCC_private_array_tree_map_data_at( \
594 private_array_tree_map_ins_or_assign_hndl.map, \
595 private_array_tree_map_ins_or_assign_hndl_ret \
596 .index \
597 )) = type_compound_literal; \
598 *((typeof(private_array_tree_map_key) *) \
599 CCC_private_array_tree_map_key_at( \
600 private_array_tree_map_ins_or_assign_hndl.map, \
601 private_array_tree_map_ins_or_assign_hndl_ret \
602 .index \
603 )) = private_array_tree_map_key; \
604 CCC_private_array_tree_map_insert( \
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_ins_or_assign_hndl.last_order, \
608 private_array_tree_map_ins_or_assign_hndl_ret.index \
609 ); \
610 private_array_tree_map_ins_or_assign_hndl_ret.status \
611 = CCC_ENTRY_VACANT; \
612 } \
613 } else if (private_array_tree_map_ins_or_assign_hndl.status \
614 == CCC_ENTRY_OCCUPIED) { \
615 *((typeof(type_compound_literal) *) \
616 CCC_private_array_tree_map_data_at( \
617 private_array_tree_map_ins_or_assign_hndl.map, \
618 private_array_tree_map_ins_or_assign_hndl.index \
619 )) = type_compound_literal; \
620 private_array_tree_map_ins_or_assign_hndl_ret = (CCC_Handle){ \
621 .index = private_array_tree_map_ins_or_assign_hndl.index, \
622 .status \
623 = private_array_tree_map_ins_or_assign_hndl.status, \
624 }; \
625 *((typeof(private_array_tree_map_key) *) \
626 CCC_private_array_tree_map_key_at( \
627 private_array_tree_map_ins_or_assign_hndl.map, \
628 private_array_tree_map_ins_or_assign_hndl.index \
629 )) = private_array_tree_map_key; \
630 } \
631 } \
632 private_array_tree_map_ins_or_assign_hndl_ret; \
633 }))
634
635/* NOLINTEND(readability-identifier-naming) */
636
637#endif /* CCC_PRIVATE_ARRAY_TREE_MAP_H */
The type passed by reference to any container function that may need to allocate memory....
Definition: types.h:369
Definition: private_array_tree_map.h:157
CCC_Order last_order
Definition: private_array_tree_map.h:163
size_t index
Definition: private_array_tree_map.h:161
struct CCC_Array_tree_map * map
Definition: private_array_tree_map.h:159
CCC_Entry_status status
Definition: private_array_tree_map.h:165
Definition: private_array_tree_map.h:34
size_t parent
Definition: private_array_tree_map.h:39
size_t branch[2]
Definition: private_array_tree_map.h:36
size_t next_free
Definition: private_array_tree_map.h:41
Definition: private_array_tree_map.h:133
void * data
Definition: private_array_tree_map.h:135
unsigned * parity
Definition: private_array_tree_map.h:139
size_t sizeof_type
Definition: private_array_tree_map.h:149
size_t count
Definition: private_array_tree_map.h:147
size_t capacity
Definition: private_array_tree_map.h:145
size_t root
Definition: private_array_tree_map.h:141
size_t free_list
Definition: private_array_tree_map.h:143
struct CCC_Array_tree_map_node * nodes
Definition: private_array_tree_map.h:137
CCC_Key_comparator comparator
Definition: private_array_tree_map.h:153
size_t key_offset
Definition: private_array_tree_map.h:151
The type passed by reference to any container function that may need to compare keys....
Definition: types.h:505
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