16#ifndef CCC_PRIVATE_ARRAY_ADAPTIVE_MAP_H
17#define CCC_PRIVATE_ARRAY_ADAPTIVE_MAP_H
24#include "private_types.h"
144#define CCC_private_array_adaptive_map_declare_fixed_map( \
145 private_fixed_map_type_name, private_key_val_type_name, private_capacity) \
146 static_assert((private_capacity) > 1, \
147 "fixed size map must have capacity greater than 1"); \
150 private_key_val_type_name data[(private_capacity)]; \
151 struct CCC_Array_adaptive_map_node nodes[(private_capacity)]; \
152 }(private_fixed_map_type_name)
156#define CCC_private_array_adaptive_map_fixed_capacity(fixed_map_type_name) \
157 (sizeof((fixed_map_type_name){}.nodes) \
158 / sizeof(struct CCC_Array_adaptive_map_node))
161#define CCC_private_array_adaptive_map_initialize( \
162 private_memory_pointer, private_type_name, private_key_node_field, \
163 private_key_order_fn, private_allocate, private_context_data, \
166 .data = (private_memory_pointer), \
168 .capacity = (private_capacity), \
172 .sizeof_type = sizeof(private_type_name), \
173 .key_offset = offsetof(private_type_name, private_key_node_field), \
174 .order = (private_key_order_fn), \
175 .allocate = (private_allocate), \
176 .context = (private_context_data), \
180#define CCC_private_array_adaptive_map_from( \
181 private_key_field, private_key_compare, private_allocate, \
182 private_context_data, private_optional_cap, \
183 private_array_compound_literal...) \
185 typeof(*private_array_compound_literal) \
186 *private_array_adaptive_map_initializer_list \
187 = private_array_compound_literal; \
188 struct CCC_Array_adaptive_map private_array_adaptive_map \
189 = CCC_private_array_adaptive_map_initialize( \
190 NULL, typeof(*private_array_adaptive_map_initializer_list), \
191 private_key_field, private_key_compare, private_allocate, \
192 private_context_data, 0); \
193 size_t const private_array_adaptive_n \
194 = sizeof(private_array_compound_literal) \
195 / sizeof(*private_array_adaptive_map_initializer_list); \
196 size_t const private_cap = private_optional_cap; \
197 if (CCC_array_adaptive_map_reserve( \
198 &private_array_adaptive_map, \
199 (private_array_adaptive_n > private_cap \
200 ? private_array_adaptive_n \
205 for (size_t i = 0; i < private_array_adaptive_n; ++i) \
207 struct CCC_Array_adaptive_map_handle \
208 private_array_adaptive_entry \
209 = CCC_private_array_adaptive_map_handle( \
210 &private_array_adaptive_map, \
212 *)&private_array_adaptive_map_initializer_list[i] \
213 .private_key_field); \
214 CCC_Handle_index private_index \
215 = private_array_adaptive_entry.index; \
216 if (!(private_array_adaptive_entry.status \
217 & CCC_ENTRY_OCCUPIED)) \
220 = CCC_private_array_adaptive_map_allocate_slot( \
221 &private_array_adaptive_map); \
223 *((typeof(*private_array_adaptive_map_initializer_list) *) \
224 CCC_private_array_adaptive_map_data_at( \
225 private_array_adaptive_entry.map, private_index)) \
226 = private_array_adaptive_map_initializer_list[i]; \
227 if (!(private_array_adaptive_entry.status \
228 & CCC_ENTRY_OCCUPIED)) \
230 CCC_private_array_adaptive_map_insert( \
231 private_array_adaptive_entry.map, private_index); \
235 private_array_adaptive_map; \
238#define CCC_private_array_adaptive_map_with_capacity( \
239 private_type_name, private_key_field, private_key_compare, \
240 private_allocate, private_context_data, private_cap) \
242 struct CCC_Array_adaptive_map private_array_adaptive_map \
243 = CCC_private_array_adaptive_map_initialize( \
244 NULL, private_type_name, private_key_field, \
245 private_key_compare, private_allocate, private_context_data, \
247 (void)CCC_array_adaptive_map_reserve(&private_array_adaptive_map, \
248 private_cap, private_allocate); \
249 private_array_adaptive_map; \
253#define CCC_private_array_adaptive_map_as(array_adaptive_map_pointer, \
254 type_name, handle...) \
255 ((type_name *)CCC_private_array_adaptive_map_data_at( \
256 (array_adaptive_map_pointer), (handle)))
261#define CCC_private_array_adaptive_map_and_modify_with( \
262 array_adaptive_map_array_pointer, type_name, closure_over_T...) \
264 __auto_type private_array_adaptive_map_mod_hndl_pointer \
265 = (array_adaptive_map_array_pointer); \
266 struct CCC_Array_adaptive_map_handle \
267 private_array_adaptive_map_mod_hndl \
268 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
269 if (private_array_adaptive_map_mod_hndl_pointer) \
271 private_array_adaptive_map_mod_hndl \
272 = private_array_adaptive_map_mod_hndl_pointer->private; \
273 if (private_array_adaptive_map_mod_hndl.status \
274 & CCC_ENTRY_OCCUPIED) \
276 type_name *const T = CCC_private_array_adaptive_map_data_at( \
277 private_array_adaptive_map_mod_hndl.map, \
278 private_array_adaptive_map_mod_hndl.index); \
285 private_array_adaptive_map_mod_hndl; \
289#define CCC_private_array_adaptive_map_or_insert_with( \
290 array_adaptive_map_array_pointer, type_compound_literal...) \
292 __auto_type private_array_adaptive_map_or_ins_hndl_pointer \
293 = (array_adaptive_map_array_pointer); \
294 CCC_Handle_index private_array_adaptive_map_or_ins_ret = 0; \
295 if (private_array_adaptive_map_or_ins_hndl_pointer) \
297 if (private_array_adaptive_map_or_ins_hndl_pointer->private.status \
298 == CCC_ENTRY_OCCUPIED) \
300 private_array_adaptive_map_or_ins_ret \
301 = private_array_adaptive_map_or_ins_hndl_pointer->private \
306 private_array_adaptive_map_or_ins_ret \
307 = CCC_private_array_adaptive_map_allocate_slot( \
308 private_array_adaptive_map_or_ins_hndl_pointer \
310 if (private_array_adaptive_map_or_ins_ret) \
312 *((typeof(type_compound_literal) *) \
313 CCC_private_array_adaptive_map_data_at( \
314 private_array_adaptive_map_or_ins_hndl_pointer \
316 private_array_adaptive_map_or_ins_ret)) \
317 = type_compound_literal; \
318 CCC_private_array_adaptive_map_insert( \
319 private_array_adaptive_map_or_ins_hndl_pointer \
321 private_array_adaptive_map_or_ins_ret); \
325 private_array_adaptive_map_or_ins_ret; \
329#define CCC_private_array_adaptive_map_insert_array_with( \
330 array_adaptive_map_array_pointer, type_compound_literal...) \
332 __auto_type private_array_adaptive_map_ins_hndl_pointer \
333 = (array_adaptive_map_array_pointer); \
334 CCC_Handle_index private_array_adaptive_map_ins_hndl_ret = 0; \
335 if (private_array_adaptive_map_ins_hndl_pointer) \
337 if (!(private_array_adaptive_map_ins_hndl_pointer->private.status \
338 & CCC_ENTRY_OCCUPIED)) \
340 private_array_adaptive_map_ins_hndl_ret \
341 = CCC_private_array_adaptive_map_allocate_slot( \
342 private_array_adaptive_map_ins_hndl_pointer->private \
344 if (private_array_adaptive_map_ins_hndl_ret) \
346 *((typeof(type_compound_literal) *) \
347 CCC_private_array_adaptive_map_data_at( \
348 private_array_adaptive_map_ins_hndl_pointer \
350 private_array_adaptive_map_ins_hndl_ret)) \
351 = type_compound_literal; \
352 CCC_private_array_adaptive_map_insert( \
353 private_array_adaptive_map_ins_hndl_pointer->private \
355 private_array_adaptive_map_ins_hndl_ret); \
358 else if (private_array_adaptive_map_ins_hndl_pointer->private \
360 == CCC_ENTRY_OCCUPIED) \
362 *((typeof(type_compound_literal) *) \
363 CCC_private_array_adaptive_map_data_at( \
364 private_array_adaptive_map_ins_hndl_pointer->private \
366 private_array_adaptive_map_ins_hndl_pointer->private \
368 = type_compound_literal; \
369 private_array_adaptive_map_ins_hndl_ret \
370 = private_array_adaptive_map_ins_hndl_pointer->private \
374 private_array_adaptive_map_ins_hndl_ret; \
378#define CCC_private_array_adaptive_map_try_insert_with( \
379 array_adaptive_map_pointer, key, type_compound_literal...) \
381 __auto_type private_array_adaptive_map_try_ins_map_pointer \
382 = (array_adaptive_map_pointer); \
383 struct CCC_Handle private_array_adaptive_map_try_ins_hndl_ret \
384 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
385 if (private_array_adaptive_map_try_ins_map_pointer) \
387 __auto_type private_array_adaptive_map_key = (key); \
388 struct CCC_Array_adaptive_map_handle \
389 private_array_adaptive_map_try_ins_hndl \
390 = CCC_private_array_adaptive_map_handle( \
391 private_array_adaptive_map_try_ins_map_pointer, \
392 (void *)&private_array_adaptive_map_key); \
393 if (!(private_array_adaptive_map_try_ins_hndl.status \
394 & CCC_ENTRY_OCCUPIED)) \
396 private_array_adaptive_map_try_ins_hndl_ret \
397 = (struct CCC_Handle){ \
398 .index = CCC_private_array_adaptive_map_allocate_slot( \
399 private_array_adaptive_map_try_ins_hndl.map), \
400 .status = CCC_ENTRY_INSERT_ERROR, \
402 if (private_array_adaptive_map_try_ins_hndl_ret.index) \
404 *((typeof(type_compound_literal) *) \
405 CCC_private_array_adaptive_map_data_at( \
406 private_array_adaptive_map_try_ins_map_pointer, \
407 private_array_adaptive_map_try_ins_hndl_ret \
409 = type_compound_literal; \
410 *((typeof(private_array_adaptive_map_key) *) \
411 CCC_private_array_adaptive_map_key_at( \
412 private_array_adaptive_map_try_ins_hndl.map, \
413 private_array_adaptive_map_try_ins_hndl_ret \
415 = private_array_adaptive_map_key; \
416 CCC_private_array_adaptive_map_insert( \
417 private_array_adaptive_map_try_ins_hndl.map, \
418 private_array_adaptive_map_try_ins_hndl_ret.index); \
419 private_array_adaptive_map_try_ins_hndl_ret.status \
420 = CCC_ENTRY_VACANT; \
423 else if (private_array_adaptive_map_try_ins_hndl.status \
424 == CCC_ENTRY_OCCUPIED) \
426 private_array_adaptive_map_try_ins_hndl_ret \
427 = (struct CCC_Handle){ \
429 = private_array_adaptive_map_try_ins_hndl.index, \
431 = private_array_adaptive_map_try_ins_hndl.status}; \
434 private_array_adaptive_map_try_ins_hndl_ret; \
438#define CCC_private_array_adaptive_map_insert_or_assign_with( \
439 array_adaptive_map_pointer, key, type_compound_literal...) \
441 __auto_type private_array_adaptive_map_ins_or_assign_map_pointer \
442 = (array_adaptive_map_pointer); \
443 struct CCC_Handle private_array_adaptive_map_ins_or_assign_hndl_ret \
444 = {.status = CCC_ENTRY_ARGUMENT_ERROR}; \
445 if (private_array_adaptive_map_ins_or_assign_map_pointer) \
447 __auto_type private_array_adaptive_map_key = (key); \
448 struct CCC_Array_adaptive_map_handle \
449 private_array_adaptive_map_ins_or_assign_hndl \
450 = CCC_private_array_adaptive_map_handle( \
451 private_array_adaptive_map_ins_or_assign_map_pointer, \
452 (void *)&private_array_adaptive_map_key); \
453 if (!(private_array_adaptive_map_ins_or_assign_hndl.status \
454 & CCC_ENTRY_OCCUPIED)) \
456 private_array_adaptive_map_ins_or_assign_hndl_ret \
457 = (struct CCC_Handle){ \
458 .index = CCC_private_array_adaptive_map_allocate_slot( \
459 private_array_adaptive_map_ins_or_assign_hndl \
461 .status = CCC_ENTRY_INSERT_ERROR, \
463 if (private_array_adaptive_map_ins_or_assign_hndl_ret.index) \
465 *((typeof(type_compound_literal) *) \
466 CCC_private_array_adaptive_map_data_at( \
467 private_array_adaptive_map_ins_or_assign_map_pointer, \
468 private_array_adaptive_map_ins_or_assign_hndl_ret \
470 = type_compound_literal; \
471 *((typeof(private_array_adaptive_map_key) *) \
472 CCC_private_array_adaptive_map_key_at( \
473 private_array_adaptive_map_ins_or_assign_hndl \
475 private_array_adaptive_map_ins_or_assign_hndl_ret \
477 = private_array_adaptive_map_key; \
478 CCC_private_array_adaptive_map_insert( \
479 private_array_adaptive_map_ins_or_assign_hndl.map, \
480 private_array_adaptive_map_ins_or_assign_hndl_ret \
482 private_array_adaptive_map_ins_or_assign_hndl_ret.status \
483 = CCC_ENTRY_VACANT; \
486 else if (private_array_adaptive_map_ins_or_assign_hndl.status \
487 == CCC_ENTRY_OCCUPIED) \
489 *((typeof(type_compound_literal) *) \
490 CCC_private_array_adaptive_map_data_at( \
491 private_array_adaptive_map_ins_or_assign_hndl.map, \
492 private_array_adaptive_map_ins_or_assign_hndl \
494 = type_compound_literal; \
495 private_array_adaptive_map_ins_or_assign_hndl_ret \
496 = (struct CCC_Handle){ \
498 = private_array_adaptive_map_ins_or_assign_hndl.index, \
500 = private_array_adaptive_map_ins_or_assign_hndl \
503 *((typeof(private_array_adaptive_map_key) *) \
504 CCC_private_array_adaptive_map_key_at( \
505 private_array_adaptive_map_ins_or_assign_hndl.map, \
506 private_array_adaptive_map_ins_or_assign_hndl \
508 = private_array_adaptive_map_key; \
511 private_array_adaptive_map_ins_or_assign_hndl_ret; \
Definition: private_array_adaptive_map.h:98
CCC_Order last_order
Definition: private_array_adaptive_map.h:104
CCC_Entry_status status
Definition: private_array_adaptive_map.h:106
size_t index
Definition: private_array_adaptive_map.h:102
struct CCC_Array_adaptive_map * map
Definition: private_array_adaptive_map.h:100
Definition: private_array_adaptive_map.h:34
size_t branch[2]
Definition: private_array_adaptive_map.h:36
size_t next_free
Definition: private_array_adaptive_map.h:42
size_t parent
Definition: private_array_adaptive_map.h:40
Definition: private_array_adaptive_map.h:70
size_t free_list
Definition: private_array_adaptive_map.h:82
size_t count
Definition: private_array_adaptive_map.h:78
void * data
Definition: private_array_adaptive_map.h:72
void * context
Definition: private_array_adaptive_map.h:92
size_t sizeof_type
Definition: private_array_adaptive_map.h:84
size_t root
Definition: private_array_adaptive_map.h:80
CCC_Key_comparator * order
Definition: private_array_adaptive_map.h:88
struct CCC_Array_adaptive_map_node * nodes
Definition: private_array_adaptive_map.h:74
CCC_Allocator * allocate
Definition: private_array_adaptive_map.h:90
size_t capacity
Definition: private_array_adaptive_map.h:76
size_t key_offset
Definition: private_array_adaptive_map.h:86
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_adaptive_map.h:114
struct CCC_Array_adaptive_map_handle private
Definition: private_array_adaptive_map.h:116