16#ifndef CCC_IMPL_ORDERED_MAP_H
17#define CCC_IMPL_ORDERED_MAP_H
24#include "impl_types.h"
57 size_t node_elem_offset;
96 struct ccc_otree_entry impl;
102void *ccc_impl_om_key_in_slot(
struct ccc_omap
const *t,
void const *slot);
104struct ccc_omap_elem *ccc_impl_omap_elem_in_slot(
struct ccc_omap
const *t,
107struct ccc_otree_entry ccc_impl_om_entry(struct ccc_omap *t,
void const *key);
109void *ccc_impl_om_insert(
struct ccc_omap *t,
struct ccc_omap_elem *n);
114#define ccc_impl_om_init(impl_tree_name, impl_struct_name, \
115 impl_node_elem_field, impl_key_elem_field, \
116 impl_key_cmp_fn, impl_alloc_fn, impl_aux_data) \
118 .root = &(impl_tree_name).end, \
119 .end = {.branch = {&(impl_tree_name).end, &(impl_tree_name).end}, \
120 .parent = &(impl_tree_name).end}, \
121 .alloc = (impl_alloc_fn), \
122 .cmp = (impl_key_cmp_fn), \
123 .aux = (impl_aux_data), \
125 .sizeof_type = sizeof(impl_struct_name), \
126 .node_elem_offset = offsetof(impl_struct_name, impl_node_elem_field), \
127 .key_offset = offsetof(impl_struct_name, impl_key_elem_field), \
131#define ccc_impl_om_new(ordered_map_entry) \
133 void *impl_om_ins_alloc_ret = NULL; \
134 if ((ordered_map_entry)->t->alloc) \
136 impl_om_ins_alloc_ret \
137 = (ordered_map_entry) \
138 ->t->alloc(NULL, (ordered_map_entry)->t->sizeof_type, \
139 (ordered_map_entry)->t->aux); \
141 impl_om_ins_alloc_ret; \
145#define ccc_impl_om_insert_key_val(ordered_map_entry, new_mem, \
150 *new_mem = lazy_key_value; \
151 new_mem = ccc_impl_om_insert( \
152 (ordered_map_entry)->t, \
153 ccc_impl_omap_elem_in_slot((ordered_map_entry)->t, new_mem)); \
158#define ccc_impl_om_insert_and_copy_key(om_insert_entry, om_insert_entry_ret, \
159 key, lazy_value...) \
161 typeof(lazy_value) *impl_om_new_ins_base \
162 = ccc_impl_om_new((&om_insert_entry)); \
163 om_insert_entry_ret = (struct ccc_ent){ \
164 .e = impl_om_new_ins_base, \
165 .stats = CCC_ENTRY_INSERT_ERROR, \
167 if (impl_om_new_ins_base) \
169 *((typeof(lazy_value) *)impl_om_new_ins_base) = lazy_value; \
170 *((typeof(key) *)ccc_impl_om_key_in_slot(om_insert_entry.t, \
171 impl_om_new_ins_base)) \
173 (void)ccc_impl_om_insert( \
175 ccc_impl_omap_elem_in_slot(om_insert_entry.t, \
176 impl_om_new_ins_base)); \
183#define ccc_impl_om_and_modify_w(ordered_map_entry_ptr, type_name, \
186 __auto_type impl_om_ent_ptr = (ordered_map_entry_ptr); \
187 struct ccc_otree_entry impl_om_mod_ent \
188 = {.entry = {.stats = CCC_ENTRY_ARG_ERROR}}; \
189 if (impl_om_ent_ptr) \
191 impl_om_mod_ent = impl_om_ent_ptr->impl; \
192 if (impl_om_mod_ent.entry.stats & CCC_ENTRY_OCCUPIED) \
194 type_name *const T = impl_om_mod_ent.entry.e; \
205#define ccc_impl_om_or_insert_w(ordered_map_entry_ptr, lazy_key_value...) \
207 __auto_type impl_or_ins_entry_ptr = (ordered_map_entry_ptr); \
208 typeof(lazy_key_value) *impl_or_ins_ret = NULL; \
209 if (impl_or_ins_entry_ptr) \
211 struct ccc_otree_entry *impl_om_or_ins_ent \
212 = &impl_or_ins_entry_ptr->impl; \
213 if (impl_om_or_ins_ent->entry.stats == CCC_ENTRY_OCCUPIED) \
215 impl_or_ins_ret = impl_om_or_ins_ent->entry.e; \
219 impl_or_ins_ret = ccc_impl_om_new(impl_om_or_ins_ent); \
220 ccc_impl_om_insert_key_val(impl_om_or_ins_ent, \
221 impl_or_ins_ret, lazy_key_value); \
228#define ccc_impl_om_insert_entry_w(ordered_map_entry_ptr, lazy_key_value...) \
230 __auto_type impl_ins_entry_ptr = (ordered_map_entry_ptr); \
231 typeof(lazy_key_value) *impl_om_ins_ent_ret = NULL; \
232 if (impl_ins_entry_ptr) \
234 struct ccc_otree_entry *impl_om_ins_ent \
235 = &impl_ins_entry_ptr->impl; \
236 if (!(impl_om_ins_ent->entry.stats & CCC_ENTRY_OCCUPIED)) \
238 impl_om_ins_ent_ret = ccc_impl_om_new(impl_om_ins_ent); \
239 ccc_impl_om_insert_key_val( \
240 impl_om_ins_ent, impl_om_ins_ent_ret, lazy_key_value); \
242 else if (impl_om_ins_ent->entry.stats == CCC_ENTRY_OCCUPIED) \
244 struct ccc_omap_elem impl_ins_ent_saved \
245 = *ccc_impl_omap_elem_in_slot(impl_om_ins_ent->t, \
246 impl_om_ins_ent->entry.e); \
247 *((typeof(lazy_key_value) *)impl_om_ins_ent->entry.e) \
249 *ccc_impl_omap_elem_in_slot(impl_om_ins_ent->t, \
250 impl_om_ins_ent->entry.e) \
251 = impl_ins_ent_saved; \
252 impl_om_ins_ent_ret = impl_om_ins_ent->entry.e; \
255 impl_om_ins_ent_ret; \
259#define ccc_impl_om_try_insert_w(ordered_map_ptr, key, lazy_value...) \
261 __auto_type impl_try_ins_map_ptr = (ordered_map_ptr); \
262 struct ccc_ent impl_om_try_ins_ent_ret \
263 = {.stats = CCC_ENTRY_ARG_ERROR}; \
264 if (impl_try_ins_map_ptr) \
266 __auto_type impl_om_key = (key); \
267 struct ccc_otree_entry impl_om_try_ins_ent = ccc_impl_om_entry( \
268 impl_try_ins_map_ptr, (void *)&impl_om_key); \
269 if (!(impl_om_try_ins_ent.entry.stats & CCC_ENTRY_OCCUPIED)) \
271 ccc_impl_om_insert_and_copy_key(impl_om_try_ins_ent, \
272 impl_om_try_ins_ent_ret, \
273 impl_om_key, lazy_value); \
275 else if (impl_om_try_ins_ent.entry.stats == CCC_ENTRY_OCCUPIED) \
277 impl_om_try_ins_ent_ret = impl_om_try_ins_ent.entry; \
280 impl_om_try_ins_ent_ret; \
284#define ccc_impl_om_insert_or_assign_w(ordered_map_ptr, key, lazy_value...) \
286 __auto_type impl_ins_or_assign_map_ptr = (ordered_map_ptr); \
287 struct ccc_ent impl_om_ins_or_assign_ent_ret \
288 = {.stats = CCC_ENTRY_ARG_ERROR}; \
289 if (impl_ins_or_assign_map_ptr) \
291 __auto_type impl_om_key = (key); \
292 struct ccc_otree_entry impl_om_ins_or_assign_ent \
293 = ccc_impl_om_entry(impl_ins_or_assign_map_ptr, \
294 (void *)&impl_om_key); \
295 if (!(impl_om_ins_or_assign_ent.entry.stats & CCC_ENTRY_OCCUPIED)) \
297 ccc_impl_om_insert_and_copy_key(impl_om_ins_or_assign_ent, \
298 impl_om_ins_or_assign_ent_ret, \
299 impl_om_key, lazy_value); \
301 else if (impl_om_ins_or_assign_ent.entry.stats \
302 == CCC_ENTRY_OCCUPIED) \
304 struct ccc_omap_elem impl_ins_ent_saved \
305 = *ccc_impl_omap_elem_in_slot( \
306 impl_om_ins_or_assign_ent.t, \
307 impl_om_ins_or_assign_ent.entry.e); \
308 *((typeof(lazy_value) *)impl_om_ins_or_assign_ent.entry.e) \
310 *ccc_impl_omap_elem_in_slot(impl_om_ins_or_assign_ent.t, \
311 impl_om_ins_or_assign_ent.entry.e) \
312 = impl_ins_ent_saved; \
313 impl_om_ins_or_assign_ent_ret \
314 = impl_om_ins_or_assign_ent.entry; \
315 *((typeof(impl_om_key) *)ccc_impl_om_key_in_slot( \
316 impl_ins_or_assign_map_ptr, \
317 impl_om_ins_or_assign_ent_ret.e)) \
321 impl_om_ins_or_assign_ent_ret; \
struct ccc_omap_elem ccc_omap_elem
The intrusive element for the user defined struct being stored in the map.
Definition: ordered_map.h:65
union ccc_omap_entry ccc_omap_entry
A container specific entry used to implement the Entry Interface.
Definition: ordered_map.h:71
void * ccc_any_alloc_fn(void *ptr, size_t size, void *aux)
An allocation function at the core of all containers.
Definition: types.h:312
ccc_threeway_cmp ccc_any_key_cmp_fn(ccc_any_key_cmp)
A callback function for three-way comparing two stored keys.
Definition: types.h:362