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#include "private_types.h" /* NOLINT */
27
28/* NOLINTBEGIN(readability-identifier-naming) */
29
36{
38 size_t branch[2];
39 union
40 {
42 size_t parent;
44 size_t next_free;
45 };
46};
47
132{
134 void *data;
138 unsigned *parity;
140 size_t root;
142 size_t free_list;
144 size_t capacity;
146 size_t count;
156 void *context;
157};
158
161{
165 size_t index;
169 CCC_Entry_status status;
170};
171
174{
177};
178
179/*======================== Private Interface ==============================*/
180
182void *CCC_private_array_tree_map_data_at(struct CCC_Array_tree_map const *,
183 size_t);
185void *CCC_private_array_tree_map_key_at(struct CCC_Array_tree_map const *,
186 size_t);
189CCC_private_array_tree_map_node_at(struct CCC_Array_tree_map const *, size_t);
192CCC_private_array_tree_map_handle(struct CCC_Array_tree_map const *,
193 void const *);
195void CCC_private_array_tree_map_insert(struct CCC_Array_tree_map *, size_t,
196 CCC_Order, size_t);
198size_t CCC_private_array_tree_map_allocate_slot(struct CCC_Array_tree_map *);
199
200/*========================= Initialization =========================*/
201
205#define CCC_private_array_tree_map_blocks(private_cap) \
206 (((private_cap) \
207 + ((sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT) - 1)) \
208 / (sizeof(*(struct CCC_Array_tree_map){}.parity) * CHAR_BIT))
209
213#define CCC_private_array_tree_map_declare_fixed_map( \
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"); \
217 typedef struct \
218 { \
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)
224
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))
230
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, \
239 private_capacity) \
240 { \
241 .data = (private_memory_pointer), \
242 .nodes = NULL, \
243 .parity = NULL, \
244 .capacity = (private_capacity), \
245 .count = 0, \
246 .root = 0, \
247 .free_list = 0, \
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), \
253 }
254
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...) \
260 (__extension__({ \
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 \
276 : private_cap), \
277 private_allocate) \
278 == CCC_RESULT_OK) \
279 { \
280 for (size_t i = 0; i < private_array_tree_n; ++i) \
281 { \
282 struct CCC_Array_tree_map_handle private_array_tree_entry \
283 = CCC_private_array_tree_map_handle( \
284 &private_array_tree_map, \
285 (void const \
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)) \
291 { \
292 private_index = CCC_private_array_tree_map_allocate_slot( \
293 &private_array_tree_map); \
294 } \
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)) \
300 { \
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); \
305 } \
306 } \
307 } \
308 private_array_tree_map; \
309 }))
310
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) \
314 (__extension__({ \
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, \
319 0); \
320 (void)CCC_array_tree_map_reserve(&private_array_tree_map, private_cap, \
321 private_allocate); \
322 private_array_tree_map; \
323 }))
324
326#define CCC_private_array_tree_map_as(array_tree_map_pointer, type_name, \
327 handle...) \
328 ((type_name *)CCC_private_array_tree_map_data_at((array_tree_map_pointer), \
329 (handle)))
330
331/*================== Core Macro Implementations =====================*/
332
334#define CCC_private_array_tree_map_and_modify_with( \
335 array_tree_map_array_pointer, type_name, closure_over_T...) \
336 (__extension__({ \
337 __auto_type private_array_tree_map_hndl_pointer \
338 = (array_tree_map_array_pointer); \
339 struct CCC_Array_tree_map_handle private_array_tree_map_mod_hndl \
340 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
341 if (private_array_tree_map_hndl_pointer) \
342 { \
343 private_array_tree_map_mod_hndl \
344 = private_array_tree_map_hndl_pointer->private; \
345 if (private_array_tree_map_mod_hndl.status & CCC_ENTRY_OCCUPIED) \
346 { \
347 type_name *const T = CCC_private_array_tree_map_data_at( \
348 private_array_tree_map_mod_hndl.map, \
349 private_array_tree_map_mod_hndl.index); \
350 if (T) \
351 { \
352 closure_over_T \
353 } \
354 } \
355 } \
356 private_array_tree_map_mod_hndl; \
357 }))
358
360#define CCC_private_array_tree_map_or_insert_with( \
361 array_tree_map_array_pointer, type_compound_literal...) \
362 (__extension__({ \
363 __auto_type private_or_ins_array_pointer \
364 = (array_tree_map_array_pointer); \
365 CCC_Handle_index private_array_tree_map_or_ins_ret = 0; \
366 if (private_or_ins_array_pointer) \
367 { \
368 if (private_or_ins_array_pointer->private.status \
369 == CCC_ENTRY_OCCUPIED) \
370 { \
371 private_array_tree_map_or_ins_ret \
372 = private_or_ins_array_pointer->private.index; \
373 } \
374 else \
375 { \
376 private_array_tree_map_or_ins_ret \
377 = CCC_private_array_tree_map_allocate_slot( \
378 private_or_ins_array_pointer->private.map); \
379 if (private_array_tree_map_or_ins_ret) \
380 { \
381 *((typeof(type_compound_literal) *) \
382 CCC_private_array_tree_map_data_at( \
383 private_or_ins_array_pointer->private.map, \
384 private_array_tree_map_or_ins_ret)) \
385 = type_compound_literal; \
386 CCC_private_array_tree_map_insert( \
387 private_or_ins_array_pointer->private.map, \
388 private_or_ins_array_pointer->private.index, \
389 private_or_ins_array_pointer->private.last_order, \
390 private_array_tree_map_or_ins_ret); \
391 } \
392 } \
393 } \
394 private_array_tree_map_or_ins_ret; \
395 }))
396
398#define CCC_private_array_tree_map_insert_array_with( \
399 array_tree_map_array_pointer, type_compound_literal...) \
400 (__extension__({ \
401 __auto_type private_ins_array_pointer \
402 = (array_tree_map_array_pointer); \
403 CCC_Handle_index private_array_tree_map_ins_hndl_ret = 0; \
404 if (private_ins_array_pointer) \
405 { \
406 if (!(private_ins_array_pointer->private.status \
407 & CCC_ENTRY_OCCUPIED)) \
408 { \
409 private_array_tree_map_ins_hndl_ret \
410 = CCC_private_array_tree_map_allocate_slot( \
411 private_ins_array_pointer->private.map); \
412 if (private_array_tree_map_ins_hndl_ret) \
413 { \
414 *((typeof(type_compound_literal) *) \
415 CCC_private_array_tree_map_data_at( \
416 private_ins_array_pointer->private.map, \
417 private_array_tree_map_ins_hndl_ret)) \
418 = type_compound_literal; \
419 CCC_private_array_tree_map_insert( \
420 private_ins_array_pointer->private.map, \
421 private_ins_array_pointer->private.index, \
422 private_ins_array_pointer->private.last_order, \
423 private_array_tree_map_ins_hndl_ret); \
424 } \
425 } \
426 else if (private_ins_array_pointer->private.status \
427 == CCC_ENTRY_OCCUPIED) \
428 { \
429 private_array_tree_map_ins_hndl_ret \
430 = private_ins_array_pointer->private.index; \
431 *((typeof(type_compound_literal) *) \
432 CCC_private_array_tree_map_data_at( \
433 private_ins_array_pointer->private.map, \
434 private_array_tree_map_ins_hndl_ret)) \
435 = type_compound_literal; \
436 } \
437 } \
438 private_array_tree_map_ins_hndl_ret; \
439 }))
440
442#define CCC_private_array_tree_map_try_insert_with( \
443 array_tree_map_pointer, key, type_compound_literal...) \
444 (__extension__({ \
445 __auto_type private_try_ins_map_pointer = (array_tree_map_pointer); \
446 struct CCC_Handle private_array_tree_map_try_ins_hndl_ret \
447 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
448 if (private_try_ins_map_pointer) \
449 { \
450 __auto_type private_array_tree_map_key = (key); \
451 struct CCC_Array_tree_map_handle \
452 private_array_tree_map_try_ins_hndl \
453 = CCC_private_array_tree_map_handle( \
454 private_try_ins_map_pointer, \
455 (void *)&private_array_tree_map_key); \
456 if (!(private_array_tree_map_try_ins_hndl.status \
457 & CCC_ENTRY_OCCUPIED)) \
458 { \
459 private_array_tree_map_try_ins_hndl_ret = (struct CCC_Handle){ \
460 .index = CCC_private_array_tree_map_allocate_slot( \
461 private_array_tree_map_try_ins_hndl.map), \
462 .status = CCC_ENTRY_INSERT_ERROR, \
463 }; \
464 if (private_array_tree_map_try_ins_hndl_ret.index) \
465 { \
466 *((typeof(type_compound_literal) *) \
467 CCC_private_array_tree_map_data_at( \
468 private_try_ins_map_pointer, \
469 private_array_tree_map_try_ins_hndl_ret.index)) \
470 = type_compound_literal; \
471 *((typeof(private_array_tree_map_key) *) \
472 CCC_private_array_tree_map_key_at( \
473 private_try_ins_map_pointer, \
474 private_array_tree_map_try_ins_hndl_ret.index)) \
475 = private_array_tree_map_key; \
476 CCC_private_array_tree_map_insert( \
477 private_array_tree_map_try_ins_hndl.map, \
478 private_array_tree_map_try_ins_hndl.index, \
479 private_array_tree_map_try_ins_hndl.last_order, \
480 private_array_tree_map_try_ins_hndl_ret.index); \
481 private_array_tree_map_try_ins_hndl_ret.status \
482 = CCC_ENTRY_VACANT; \
483 } \
484 } \
485 else if (private_array_tree_map_try_ins_hndl.status \
486 == CCC_ENTRY_OCCUPIED) \
487 { \
488 private_array_tree_map_try_ins_hndl_ret = (struct CCC_Handle){ \
489 .index = private_array_tree_map_try_ins_hndl.index, \
490 .status = private_array_tree_map_try_ins_hndl.status, \
491 }; \
492 } \
493 } \
494 private_array_tree_map_try_ins_hndl_ret; \
495 }))
496
498#define CCC_private_array_tree_map_insert_or_assign_with( \
499 array_tree_map_pointer, key, type_compound_literal...) \
500 (__extension__({ \
501 __auto_type private_ins_or_assign_map_pointer \
502 = (array_tree_map_pointer); \
503 struct CCC_Handle private_array_tree_map_ins_or_assign_hndl_ret \
504 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
505 if (private_ins_or_assign_map_pointer) \
506 { \
507 __auto_type private_array_tree_map_key = (key); \
508 struct CCC_Array_tree_map_handle \
509 private_array_tree_map_ins_or_assign_hndl \
510 = CCC_private_array_tree_map_handle( \
511 private_ins_or_assign_map_pointer, \
512 (void *)&private_array_tree_map_key); \
513 if (!(private_array_tree_map_ins_or_assign_hndl.status \
514 & CCC_ENTRY_OCCUPIED)) \
515 { \
516 private_array_tree_map_ins_or_assign_hndl_ret \
517 = (struct CCC_Handle){ \
518 .index = CCC_private_array_tree_map_allocate_slot( \
519 private_array_tree_map_ins_or_assign_hndl.map), \
520 .status = CCC_ENTRY_INSERT_ERROR, \
521 }; \
522 if (private_array_tree_map_ins_or_assign_hndl_ret.index) \
523 { \
524 *((typeof(type_compound_literal) *) \
525 CCC_private_array_tree_map_data_at( \
526 private_array_tree_map_ins_or_assign_hndl.map, \
527 private_array_tree_map_ins_or_assign_hndl_ret \
528 .index)) \
529 = type_compound_literal; \
530 *((typeof(private_array_tree_map_key) *) \
531 CCC_private_array_tree_map_key_at( \
532 private_array_tree_map_ins_or_assign_hndl.map, \
533 private_array_tree_map_ins_or_assign_hndl_ret \
534 .index)) \
535 = private_array_tree_map_key; \
536 CCC_private_array_tree_map_insert( \
537 private_array_tree_map_ins_or_assign_hndl.map, \
538 private_array_tree_map_ins_or_assign_hndl.index, \
539 private_array_tree_map_ins_or_assign_hndl.last_order, \
540 private_array_tree_map_ins_or_assign_hndl_ret.index); \
541 private_array_tree_map_ins_or_assign_hndl_ret.status \
542 = CCC_ENTRY_VACANT; \
543 } \
544 } \
545 else if (private_array_tree_map_ins_or_assign_hndl.status \
546 == CCC_ENTRY_OCCUPIED) \
547 { \
548 *((typeof(type_compound_literal) *) \
549 CCC_private_array_tree_map_data_at( \
550 private_array_tree_map_ins_or_assign_hndl.map, \
551 private_array_tree_map_ins_or_assign_hndl.index)) \
552 = type_compound_literal; \
553 private_array_tree_map_ins_or_assign_hndl_ret \
554 = (struct CCC_Handle){ \
555 .index \
556 = private_array_tree_map_ins_or_assign_hndl.index, \
557 .status \
558 = private_array_tree_map_ins_or_assign_hndl.status, \
559 }; \
560 *((typeof(private_array_tree_map_key) *) \
561 CCC_private_array_tree_map_key_at( \
562 private_array_tree_map_ins_or_assign_hndl.map, \
563 private_array_tree_map_ins_or_assign_hndl.index)) \
564 = private_array_tree_map_key; \
565 } \
566 } \
567 private_array_tree_map_ins_or_assign_hndl_ret; \
568 }))
569
570/* NOLINTEND(readability-identifier-naming) */
571
572#endif /* CCC_PRIVATE_ARRAY_TREE_MAP_H */
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