C Container Collection (CCC)
Loading...
Searching...
No Matches
private_tree_map.h
Go to the documentation of this file.
1
28#ifndef CCC_PRIVATE_TREE_MAP_H
29#define CCC_PRIVATE_TREE_MAP_H
30
32#include <stddef.h>
33#include <stdint.h>
36#include "../types.h" /* IWYU pragma: keep */
37
38/* NOLINTBEGIN(readability-identifier-naming) */
39
48 uint8_t parity;
49};
50
67 size_t count;
69 size_t key_offset;
78};
79
92};
93
94/*========================= Private Interface ============================*/
95
97void *
98CCC_private_tree_map_key_in_slot(struct CCC_Tree_map const *, void const *slot);
101 struct CCC_Tree_map const *, void const *slot
102);
105CCC_private_tree_map_entry(struct CCC_Tree_map const *, void const *key);
108 struct CCC_Tree_map *,
109 struct CCC_Tree_map_node *parent,
111 struct CCC_Tree_map_node *type_output_intruder
112);
113
114/*========================== Initialization ===========================*/
115
117#define CCC_private_tree_map_for( \
118 private_struct_name, \
119 private_node_field, \
120 private_key_node_field, \
121 private_comparator... \
122) \
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), \
131 }
132
134#define CCC_private_tree_map_default( \
135 private_struct_name, \
136 private_node_field, \
137 private_key_node_field, \
138 private_comparator... \
139) \
140 CCC_private_tree_map_for( \
141 private_struct_name, \
142 private_node_field, \
143 private_key_node_field, \
144 private_comparator \
145 )
146
148#define CCC_private_tree_map_from( \
149 private_type_intruder_field_name, \
150 private_key_field_name, \
151 private_comparator, \
152 private_allocator, \
153 private_destructor, \
154 private_compound_literal_array... \
155) \
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, \
163 private_comparator \
164 ); \
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; \
172 ++private_i) { \
173 struct CCC_Tree_map_entry private_tree_map_entry \
174 = CCC_private_tree_map_entry( \
175 &private_map, \
176 (void *)&private_tree_map_type_array[private_i] \
177 .private_key_field_name \
178 ); \
179 if (!(private_tree_map_entry.entry.status \
180 & CCC_ENTRY_OCCUPIED)) { \
181 typeof(*private_tree_map_type_array) *const \
182 private_new_slot \
183 = private_tree_map_allocator->allocate(( \
184 CCC_Allocator_arguments \
185 ){ \
186 .input = NULL, \
187 .bytes = private_map.sizeof_type, \
188 .alignment = private_map.alignof_type, \
189 .context = private_tree_map_allocator->context, \
190 }); \
191 if (!private_new_slot) { \
192 (void)CCC_tree_map_clear( \
193 &private_map, \
194 &private_destructor, \
195 private_tree_map_allocator \
196 ); \
197 break; \
198 } \
199 *private_new_slot \
200 = private_tree_map_type_array[private_i]; \
201 CCC_private_tree_map_insert( \
202 &private_map, \
203 CCC_private_tree_map_node_in_slot( \
204 &private_map, private_tree_map_entry.entry.type \
205 ), \
206 private_tree_map_entry.last_order, \
207 CCC_private_tree_map_node_in_slot( \
208 &private_map, private_new_slot \
209 ) \
210 ); \
211 } else { \
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 \
215 ); \
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; \
222 } \
223 } \
224 } \
225 private_map; \
226 }))}.private
227
228/*================== Helper Macros for Repeated Logic =================*/
229
231#define CCC_private_tree_map_new( \
232 private_tree_map_entry, private_allocator_pointer \
233) \
234 (__extension__({ \
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){ \
240 .input = NULL, \
241 .bytes = (private_tree_map_entry)->map->sizeof_type, \
242 .alignment \
243 = (private_tree_map_entry)->map->alignof_type, \
244 .context = (private_allocator_pointer)->context, \
245 }); \
246 } \
247 private_tree_map_ins_allocate_ret; \
248 }))
249
251#define CCC_private_tree_map_insert_key_val( \
252 private_tree_map_entry, new_data, type_compound_literal... \
253) \
254 (__extension__({ \
255 if (new_data) { \
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 \
262 ), \
263 (private_tree_map_entry)->last_order, \
264 CCC_private_tree_map_node_in_slot( \
265 (private_tree_map_entry)->map, new_data \
266 ) \
267 ); \
268 } \
269 }))
270
272#define CCC_private_tree_map_insert_and_copy_key( \
273 tree_map_insert_entry, \
274 tree_map_insert_entry_ret, \
275 key, \
276 private_allocator_pointer, \
277 type_compound_literal... \
278) \
279 (__extension__({ \
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 \
283 ); \
284 tree_map_insert_entry_ret = (CCC_Entry){ \
285 .type = private_tree_map_new_ins_base, \
286 .status = CCC_ENTRY_INSERT_ERROR, \
287 }; \
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 \
293 )) = key; \
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 \
299 ), \
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 \
303 ) \
304 ); \
305 } \
306 }))
307
308/*================== Core Macro Implementations =====================*/
309
311#define CCC_private_tree_map_and_modify_with( \
312 private_tree_map_entry_pointer, \
313 closure_parameter, \
314 closure_over_closure_parameter... \
315) \
316 (__extension__({ \
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 \
326 } \
327 } \
328 private_tree_map_mod_ent; \
329 }))
330
332#define CCC_private_tree_map_or_insert_with( \
333 private_tree_map_entry_pointer, \
334 private_allocator_pointer, \
335 type_compound_literal... \
336) \
337 (__extension__({ \
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; \
348 } else { \
349 private_tree_map_or_ins_ret = CCC_private_tree_map_new( \
350 private_or_ins_entry_pointer, private_tree_map_allocator \
351 ); \
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 \
356 ); \
357 } \
358 } \
359 private_tree_map_or_ins_ret; \
360 }))
361
363#define CCC_private_tree_map_insert_entry_with( \
364 private_tree_map_entry_pointer, \
365 private_allocator_pointer, \
366 type_compound_literal... \
367) \
368 (__extension__({ \
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 \
379 ); \
380 CCC_private_tree_map_insert_key_val( \
381 private_ins_entry_pointer, \
382 private_tree_map_ins_ent_ret, \
383 type_compound_literal \
384 ); \
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 \
391 ); \
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; \
401 } \
402 } \
403 private_tree_map_ins_ent_ret; \
404 }))
405
407#define CCC_private_tree_map_try_insert_with( \
408 Tree_map_pointer, key, private_allocator_pointer, type_compound_literal... \
409) \
410 (__extension__({ \
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 \
422 ); \
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 \
431 ); \
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; \
436 } \
437 } \
438 private_tree_map_try_ins_ent_ret; \
439 }))
440
442#define CCC_private_tree_map_insert_or_assign_with( \
443 Tree_map_pointer, key, private_allocator_pointer, type_compound_literal... \
444) \
445 (__extension__({ \
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 \
458 ); \
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 \
467 ); \
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 \
474 ); \
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; \
489 } \
490 } \
491 private_tree_map_ins_or_assign_ent_ret; \
492 }))
493
494/* NOLINTEND(readability-identifier-naming) */
495
496#endif /* CCC_PRIVATE_REALTIME__ADAPTIVE_MAP_H */
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