28#ifndef CCC_PRIVATE_TREE_MAP_H
29#define CCC_PRIVATE_TREE_MAP_H
117#define CCC_private_tree_map_for( \
118 private_struct_name, \
119 private_node_field, \
120 private_key_node_field, \
121 private_comparator... \
123 (struct CCC_Tree_map) { \
124 .root = NULL, .count = 0, \
125 .key_offset = offsetof(private_struct_name, private_key_node_field), \
126 .type_intruder_offset \
127 = offsetof(private_struct_name, private_node_field), \
128 .sizeof_type = sizeof(private_struct_name), \
129 .alignof_type = alignof(private_struct_name), \
130 .comparator = (private_comparator), \
134#define CCC_private_tree_map_default( \
135 private_struct_name, \
136 private_node_field, \
137 private_key_node_field, \
138 private_comparator... \
140 CCC_private_tree_map_for( \
141 private_struct_name, \
142 private_node_field, \
143 private_key_node_field, \
148#define CCC_private_tree_map_from( \
149 private_type_intruder_field_name, \
150 private_key_field_name, \
151 private_comparator, \
153 private_destructor, \
154 private_compound_literal_array... \
156 (struct { struct CCC_Tree_map private; }){(__extension__({ \
157 typeof(*private_compound_literal_array) *private_tree_map_type_array \
158 = private_compound_literal_array; \
159 struct CCC_Tree_map private_map = CCC_private_tree_map_default( \
160 typeof(*private_tree_map_type_array), \
161 private_type_intruder_field_name, \
162 private_key_field_name, \
165 CCC_Allocator const *const private_tree_map_allocator \
166 = &(private_allocator); \
167 if (private_tree_map_allocator->allocate) { \
168 size_t const private_count \
169 = sizeof(private_compound_literal_array) \
170 / sizeof(*private_tree_map_type_array); \
171 for (size_t private_i = 0; private_i < private_count; \
173 struct CCC_Tree_map_entry private_tree_map_entry \
174 = CCC_private_tree_map_entry( \
176 (void *)&private_tree_map_type_array[private_i] \
177 .private_key_field_name \
179 if (!(private_tree_map_entry.entry.status \
180 & CCC_ENTRY_OCCUPIED)) { \
181 typeof(*private_tree_map_type_array) *const \
183 = private_tree_map_allocator->allocate(( \
184 CCC_Allocator_arguments \
187 .bytes = private_map.sizeof_type, \
188 .alignment = private_map.alignof_type, \
189 .context = private_tree_map_allocator->context, \
191 if (!private_new_slot) { \
192 (void)CCC_tree_map_clear( \
194 &private_destructor, \
195 private_tree_map_allocator \
200 = private_tree_map_type_array[private_i]; \
201 CCC_private_tree_map_insert( \
203 CCC_private_tree_map_node_in_slot( \
204 &private_map, private_tree_map_entry.entry.type \
206 private_tree_map_entry.last_order, \
207 CCC_private_tree_map_node_in_slot( \
208 &private_map, private_new_slot \
212 struct CCC_Tree_map_node private_node_saved \
213 = *CCC_private_tree_map_node_in_slot( \
214 &private_map, private_tree_map_entry.entry.type \
216 *((typeof(*private_tree_map_type_array) *) \
217 private_tree_map_entry.entry.type) \
218 = private_tree_map_type_array[private_i]; \
219 *CCC_private_tree_map_node_in_slot( \
220 &private_map, private_tree_map_entry.entry.type \
221 ) = private_node_saved; \
231#define CCC_private_tree_map_new( \
232 private_tree_map_entry, private_allocator_pointer \
235 void *private_tree_map_ins_allocate_ret = NULL; \
236 if ((private_allocator_pointer)->allocate) { \
237 private_tree_map_ins_allocate_ret \
238 = (private_allocator_pointer) \
239 ->allocate((CCC_Allocator_arguments){ \
241 .bytes = (private_tree_map_entry)->map->sizeof_type, \
243 = (private_tree_map_entry)->map->alignof_type, \
244 .context = (private_allocator_pointer)->context, \
247 private_tree_map_ins_allocate_ret; \
251#define CCC_private_tree_map_insert_key_val( \
252 private_tree_map_entry, new_data, type_compound_literal... \
256 *new_data = type_compound_literal; \
257 new_data = CCC_private_tree_map_insert( \
258 (private_tree_map_entry)->map, \
259 CCC_private_tree_map_node_in_slot( \
260 (private_tree_map_entry)->map, \
261 (private_tree_map_entry)->entry.type \
263 (private_tree_map_entry)->last_order, \
264 CCC_private_tree_map_node_in_slot( \
265 (private_tree_map_entry)->map, new_data \
272#define CCC_private_tree_map_insert_and_copy_key( \
273 tree_map_insert_entry, \
274 tree_map_insert_entry_ret, \
276 private_allocator_pointer, \
277 type_compound_literal... \
280 typeof(type_compound_literal) *private_tree_map_new_ins_base \
281 = CCC_private_tree_map_new( \
282 (&tree_map_insert_entry), private_allocator_pointer \
284 tree_map_insert_entry_ret = (CCC_Entry){ \
285 .type = private_tree_map_new_ins_base, \
286 .status = CCC_ENTRY_INSERT_ERROR, \
288 if (private_tree_map_new_ins_base) { \
289 tree_map_insert_entry_ret.status = CCC_ENTRY_VACANT; \
290 *private_tree_map_new_ins_base = type_compound_literal; \
291 *((typeof(key) *)CCC_private_tree_map_key_in_slot( \
292 tree_map_insert_entry.map, private_tree_map_new_ins_base \
294 (void)CCC_private_tree_map_insert( \
295 tree_map_insert_entry.map, \
296 CCC_private_tree_map_node_in_slot( \
297 tree_map_insert_entry.map, \
298 tree_map_insert_entry.entry.type \
300 tree_map_insert_entry.last_order, \
301 CCC_private_tree_map_node_in_slot( \
302 tree_map_insert_entry.map, private_tree_map_new_ins_base \
311#define CCC_private_tree_map_and_modify_with( \
312 private_tree_map_entry_pointer, \
314 closure_over_closure_parameter... \
317 struct CCC_Tree_map_entry const *const private_tree_map_ent_pointer \
318 = (private_tree_map_entry_pointer); \
319 struct CCC_Tree_map_entry private_tree_map_mod_ent \
320 = {.entry = {.status = CCC_ENTRY_ARGUMENT_ERROR}}; \
321 if (private_tree_map_ent_pointer) { \
322 private_tree_map_mod_ent = *private_tree_map_ent_pointer; \
323 if (private_tree_map_mod_ent.entry.status & CCC_ENTRY_OCCUPIED) { \
324 closure_parameter = private_tree_map_mod_ent.entry.type; \
325 closure_over_closure_parameter \
328 private_tree_map_mod_ent; \
332#define CCC_private_tree_map_or_insert_with( \
333 private_tree_map_entry_pointer, \
334 private_allocator_pointer, \
335 type_compound_literal... \
338 struct CCC_Tree_map_entry const *const private_or_ins_entry_pointer \
339 = (private_tree_map_entry_pointer); \
340 typeof(type_compound_literal) *private_tree_map_or_ins_ret = NULL; \
341 CCC_Allocator const *const private_tree_map_allocator \
342 = (private_allocator_pointer); \
343 if (private_tree_map_allocator && private_or_ins_entry_pointer) { \
344 if (private_or_ins_entry_pointer->entry.status \
345 == CCC_ENTRY_OCCUPIED) { \
346 private_tree_map_or_ins_ret \
347 = private_or_ins_entry_pointer->entry.type; \
349 private_tree_map_or_ins_ret = CCC_private_tree_map_new( \
350 private_or_ins_entry_pointer, private_tree_map_allocator \
352 CCC_private_tree_map_insert_key_val( \
353 private_or_ins_entry_pointer, \
354 private_tree_map_or_ins_ret, \
355 type_compound_literal \
359 private_tree_map_or_ins_ret; \
363#define CCC_private_tree_map_insert_entry_with( \
364 private_tree_map_entry_pointer, \
365 private_allocator_pointer, \
366 type_compound_literal... \
369 struct CCC_Tree_map_entry const *const private_ins_entry_pointer \
370 = (private_tree_map_entry_pointer); \
371 typeof(type_compound_literal) *private_tree_map_ins_ent_ret = NULL; \
372 CCC_Allocator const *const private_tree_map_allocator \
373 = (private_allocator_pointer); \
374 if (private_tree_map_allocator && private_ins_entry_pointer) { \
375 if (!(private_ins_entry_pointer->entry.status \
376 & CCC_ENTRY_OCCUPIED)) { \
377 private_tree_map_ins_ent_ret = CCC_private_tree_map_new( \
378 private_ins_entry_pointer, private_allocator_pointer \
380 CCC_private_tree_map_insert_key_val( \
381 private_ins_entry_pointer, \
382 private_tree_map_ins_ent_ret, \
383 type_compound_literal \
385 } else if (private_ins_entry_pointer->entry.status \
386 == CCC_ENTRY_OCCUPIED) { \
387 struct CCC_Tree_map_node private_ins_ent_saved \
388 = *CCC_private_tree_map_node_in_slot( \
389 private_ins_entry_pointer->map, \
390 private_ins_entry_pointer->entry.type \
392 *((typeof(private_tree_map_ins_ent_ret)) \
393 private_ins_entry_pointer->entry.type) \
394 = type_compound_literal; \
395 *CCC_private_tree_map_node_in_slot( \
396 private_ins_entry_pointer->map, \
397 private_ins_entry_pointer->entry.type \
398 ) = private_ins_ent_saved; \
399 private_tree_map_ins_ent_ret \
400 = private_ins_entry_pointer->entry.type; \
403 private_tree_map_ins_ent_ret; \
407#define CCC_private_tree_map_try_insert_with( \
408 Tree_map_pointer, key, private_allocator_pointer, type_compound_literal... \
411 struct CCC_Tree_map *const private_try_ins_map_pointer \
412 = (Tree_map_pointer); \
413 CCC_Entry private_tree_map_try_ins_ent_ret \
414 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
415 CCC_Allocator const *const private_tree_map_allocator \
416 = (private_allocator_pointer); \
417 if (private_tree_map_allocator && private_try_ins_map_pointer) { \
418 __auto_type private_tree_map_key = (key); \
419 struct CCC_Tree_map_entry private_tree_map_try_ins_ent \
420 = CCC_private_tree_map_entry( \
421 private_try_ins_map_pointer, (void *)&private_tree_map_key \
423 if (!(private_tree_map_try_ins_ent.entry.status \
424 & CCC_ENTRY_OCCUPIED)) { \
425 CCC_private_tree_map_insert_and_copy_key( \
426 private_tree_map_try_ins_ent, \
427 private_tree_map_try_ins_ent_ret, \
428 private_tree_map_key, \
429 private_tree_map_allocator, \
430 type_compound_literal \
432 } else if (private_tree_map_try_ins_ent.entry.status \
433 == CCC_ENTRY_OCCUPIED) { \
434 private_tree_map_try_ins_ent_ret \
435 = private_tree_map_try_ins_ent.entry; \
438 private_tree_map_try_ins_ent_ret; \
442#define CCC_private_tree_map_insert_or_assign_with( \
443 Tree_map_pointer, key, private_allocator_pointer, type_compound_literal... \
446 struct CCC_Tree_map *const private_ins_or_assign_map_pointer \
447 = (Tree_map_pointer); \
448 CCC_Entry private_tree_map_ins_or_assign_ent_ret \
449 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
450 CCC_Allocator const *const private_tree_map_allocator \
451 = (private_allocator_pointer); \
452 if (private_tree_map_allocator && private_ins_or_assign_map_pointer) { \
453 __auto_type private_tree_map_key = (key); \
454 struct CCC_Tree_map_entry private_tree_map_ins_or_assign_ent \
455 = CCC_private_tree_map_entry( \
456 private_ins_or_assign_map_pointer, \
457 (void *)&private_tree_map_key \
459 if (!(private_tree_map_ins_or_assign_ent.entry.status \
460 & CCC_ENTRY_OCCUPIED)) { \
461 CCC_private_tree_map_insert_and_copy_key( \
462 private_tree_map_ins_or_assign_ent, \
463 private_tree_map_ins_or_assign_ent_ret, \
464 private_tree_map_key, \
465 private_tree_map_allocator, \
466 type_compound_literal \
468 } else if (private_tree_map_ins_or_assign_ent.entry.status \
469 == CCC_ENTRY_OCCUPIED) { \
470 struct CCC_Tree_map_node private_ins_ent_saved \
471 = *CCC_private_tree_map_node_in_slot( \
472 private_tree_map_ins_or_assign_ent.map, \
473 private_tree_map_ins_or_assign_ent.entry.type \
475 *((typeof(type_compound_literal) *) \
476 private_tree_map_ins_or_assign_ent.entry.type) \
477 = type_compound_literal; \
478 *CCC_private_tree_map_node_in_slot( \
479 private_tree_map_ins_or_assign_ent.map, \
480 private_tree_map_ins_or_assign_ent.entry.type \
481 ) = private_ins_ent_saved; \
482 private_tree_map_ins_or_assign_ent_ret \
483 = private_tree_map_ins_or_assign_ent.entry; \
484 *((typeof(private_tree_map_key) *) \
485 CCC_private_tree_map_key_in_slot( \
486 private_tree_map_ins_or_assign_ent.map, \
487 private_tree_map_ins_or_assign_ent_ret.type \
488 )) = private_tree_map_key; \
491 private_tree_map_ins_or_assign_ent_ret; \
struct CCC_Tree_map_entry CCC_private_tree_map_entry(struct CCC_Tree_map const *, void const *key)
void * CCC_private_tree_map_insert(struct CCC_Tree_map *, struct CCC_Tree_map_node *parent, CCC_Order last_order, struct CCC_Tree_map_node *type_output_intruder)
void * CCC_private_tree_map_key_in_slot(struct CCC_Tree_map const *, void const *slot)
struct CCC_Tree_map_node * CCC_private_tree_map_node_in_slot(struct CCC_Tree_map const *, void const *slot)
An Occupied or Vacant position in a searchable container.
Definition: types.h:135
The type passed by reference to any container function that may need to compare keys....
Definition: types.h:520
Definition: private_tree_map.h:83
CCC_Entry entry
Definition: private_tree_map.h:91
CCC_Order last_order
Definition: private_tree_map.h:89
struct CCC_Tree_map * map
Definition: private_tree_map.h:85
Definition: private_tree_map.h:42
uint8_t parity
Definition: private_tree_map.h:48
struct CCC_Tree_map_node * branch[2]
Definition: private_tree_map.h:44
struct CCC_Tree_map_node * parent
Definition: private_tree_map.h:46
Definition: private_tree_map.h:63
CCC_Key_comparator comparator
Definition: private_tree_map.h:77
size_t count
Definition: private_tree_map.h:67
size_t alignof_type
Definition: private_tree_map.h:75
struct CCC_Tree_map_node * root
Definition: private_tree_map.h:65
size_t sizeof_type
Definition: private_tree_map.h:73
size_t key_offset
Definition: private_tree_map.h:69
size_t type_intruder_offset
Definition: private_tree_map.h:71
CCC_Order
A three-way comparison for comparison functions.
Definition: types.h:213