1#ifndef CCC_IMPL_HANDLE_ORDERED_MAP_H
2#define CCC_IMPL_HANDLE_ORDERED_MAP_H
10#include "impl_types.h"
40 size_t node_elem_offset_;
45struct ccc_htree_handle_
47 struct ccc_homap_ *hom_;
49 struct ccc_handl_ handle_;
53union ccc_homap_handle_
55 struct ccc_htree_handle_ impl_;
61void ccc_impl_hom_insert(
struct ccc_homap_ *hom,
size_t elem_i);
63struct ccc_htree_handle_ ccc_impl_hom_handle(struct ccc_homap_ *hom,
66void *ccc_impl_hom_key_at(
struct ccc_homap_
const *hom,
size_t slot);
68struct ccc_homap_elem_ *ccc_impl_homap_elem_at(
struct ccc_homap_
const *hom,
71size_t ccc_impl_hom_alloc_slot(
struct ccc_homap_ *hom);
76#define ccc_impl_hom_init(mem_ptr, node_elem_field, key_elem_field, \
77 key_cmp_fn, alloc_fn, aux_data, capacity) \
79 .buf_ = ccc_buf_init(mem_ptr, alloc_fn, aux_data, capacity), \
82 .key_offset_ = offsetof(typeof(*(mem_ptr)), key_elem_field), \
83 .node_elem_offset_ = offsetof(typeof(*(mem_ptr)), node_elem_field), \
84 .cmp_ = (key_cmp_fn), \
88#define ccc_impl_hom_as(handle_ordered_map_ptr, type_name, handle...) \
89 ((type_name *)ccc_buf_at(&(handle_ordered_map_ptr)->buf_, (handle)))
94#define ccc_impl_hom_and_modify_w(handle_ordered_map_handle_ptr, type_name, \
97 __auto_type hom_mod_hndl_ptr_ = (handle_ordered_map_handle_ptr); \
98 struct ccc_htree_handle_ hom_mod_hndl_ \
99 = {.handle_ = {.stats_ = CCC_ENTRY_ARG_ERROR}}; \
100 if (hom_mod_hndl_ptr_) \
102 hom_mod_hndl_ = hom_mod_hndl_ptr_->impl_; \
103 if (hom_mod_hndl_.handle_.stats_ & CCC_ENTRY_OCCUPIED) \
105 type_name *const T = ccc_buf_at(&hom_mod_hndl_.hom_->buf_, \
106 hom_mod_hndl_.handle_.i_); \
117#define ccc_impl_hom_or_insert_w(handle_ordered_map_handle_ptr, \
120 __auto_type hom_or_ins_hndl_ptr_ = (handle_ordered_map_handle_ptr); \
121 ccc_handle_i hom_or_ins_ret_ = 0; \
122 if (hom_or_ins_hndl_ptr_) \
124 struct ccc_htree_handle_ *hom_or_ins_hndl_ \
125 = &hom_or_ins_hndl_ptr_->impl_; \
126 if (hom_or_ins_hndl_->handle_.stats_ == CCC_ENTRY_OCCUPIED) \
128 hom_or_ins_ret_ = hom_or_ins_hndl_->handle_.i_; \
133 = ccc_impl_hom_alloc_slot(hom_or_ins_hndl_->hom_); \
134 if (hom_or_ins_ret_) \
136 *((typeof(lazy_key_value) *)ccc_buf_at( \
137 &hom_or_ins_hndl_->hom_->buf_, hom_or_ins_ret_)) \
139 ccc_impl_hom_insert(hom_or_ins_hndl_->hom_, \
148#define ccc_impl_hom_insert_handle_w(handle_ordered_map_handle_ptr, \
151 __auto_type hom_ins_hndl_ptr_ = (handle_ordered_map_handle_ptr); \
152 ccc_handle_i hom_ins_hndl_ret_ = 0; \
153 if (hom_ins_hndl_ptr_) \
155 struct ccc_htree_handle_ *hom_ins_hndl_ \
156 = &hom_ins_hndl_ptr_->impl_; \
157 if (!(hom_ins_hndl_->handle_.stats_ & CCC_ENTRY_OCCUPIED)) \
160 = ccc_impl_hom_alloc_slot(hom_ins_hndl_->hom_); \
161 if (hom_ins_hndl_ret_) \
163 *((typeof(lazy_key_value) *)ccc_buf_at( \
164 &hom_ins_hndl_->hom_->buf_, hom_ins_hndl_ret_)) \
166 ccc_impl_hom_insert(hom_ins_hndl_->hom_, \
167 hom_ins_hndl_ret_); \
170 else if (hom_ins_hndl_->handle_.stats_ == CCC_ENTRY_OCCUPIED) \
172 hom_ins_hndl_ret_ = hom_ins_hndl_->handle_.i_; \
173 struct ccc_homap_elem_ ins_hndl_saved_ \
174 = *ccc_impl_homap_elem_at(hom_ins_hndl_->hom_, \
175 hom_ins_hndl_ret_); \
176 *((typeof(lazy_key_value) *)ccc_buf_at( \
177 &hom_ins_hndl_->hom_->buf_, hom_ins_hndl_ret_)) \
179 *ccc_impl_homap_elem_at(hom_ins_hndl_->hom_, \
188#define ccc_impl_hom_try_insert_w(handle_ordered_map_ptr, key, lazy_value...) \
190 __auto_type hom_try_ins_map_ptr_ = (handle_ordered_map_ptr); \
191 struct ccc_handl_ hom_try_ins_hndl_ret_ \
192 = {.stats_ = CCC_ENTRY_ARG_ERROR}; \
193 if (hom_try_ins_map_ptr_) \
195 __auto_type hom_key_ = (key); \
196 struct ccc_htree_handle_ hom_try_ins_hndl_ = ccc_impl_hom_handle( \
197 hom_try_ins_map_ptr_, (void *)&hom_key_); \
198 if (!(hom_try_ins_hndl_.handle_.stats_ & CCC_ENTRY_OCCUPIED)) \
200 hom_try_ins_hndl_ret_ = (struct ccc_handl_){ \
201 .i_ = ccc_impl_hom_alloc_slot(hom_try_ins_hndl_.hom_), \
202 .stats_ = CCC_ENTRY_INSERT_ERROR}; \
203 if (hom_try_ins_hndl_ret_.i_) \
205 *((typeof(lazy_value) *)ccc_buf_at( \
206 &hom_try_ins_map_ptr_->buf_, \
207 hom_try_ins_hndl_ret_.i_)) \
209 *((typeof(hom_key_) *)ccc_impl_hom_key_at( \
210 hom_try_ins_hndl_.hom_, hom_try_ins_hndl_ret_.i_)) \
212 ccc_impl_hom_insert(hom_try_ins_hndl_.hom_, \
213 hom_try_ins_hndl_ret_.i_); \
214 hom_try_ins_hndl_ret_.stats_ = CCC_ENTRY_VACANT; \
217 else if (hom_try_ins_hndl_.handle_.stats_ == CCC_ENTRY_OCCUPIED) \
219 hom_try_ins_hndl_ret_ = (struct ccc_handl_){ \
220 .i_ = hom_try_ins_hndl_.handle_.i_, \
221 .stats_ = hom_try_ins_hndl_.handle_.stats_}; \
224 hom_try_ins_hndl_ret_; \
228#define ccc_impl_hom_insert_or_assign_w(handle_ordered_map_ptr, key, \
231 __auto_type hom_ins_or_assign_map_ptr_ = (handle_ordered_map_ptr); \
232 struct ccc_handl_ hom_ins_or_assign_hndl_ret_ \
233 = {.stats_ = CCC_ENTRY_ARG_ERROR}; \
234 if (hom_ins_or_assign_map_ptr_) \
236 __auto_type hom_key_ = (key); \
237 struct ccc_htree_handle_ hom_ins_or_assign_hndl_ \
238 = ccc_impl_hom_handle((handle_ordered_map_ptr), \
239 (void *)&hom_key_); \
240 if (!(hom_ins_or_assign_hndl_.handle_.stats_ \
241 & CCC_ENTRY_OCCUPIED)) \
243 hom_ins_or_assign_hndl_ret_ \
244 = (struct ccc_handl_){.i_ = ccc_impl_hom_alloc_slot( \
245 hom_ins_or_assign_hndl_.hom_), \
246 .stats_ = CCC_ENTRY_INSERT_ERROR}; \
247 if (hom_ins_or_assign_hndl_ret_.i_) \
249 *((typeof(lazy_value) *)ccc_buf_at( \
250 &hom_ins_or_assign_map_ptr_->buf_, \
251 hom_ins_or_assign_hndl_ret_.i_)) \
253 *((typeof(hom_key_) *)ccc_impl_hom_key_at( \
254 hom_ins_or_assign_hndl_.hom_, \
255 hom_ins_or_assign_hndl_ret_.i_)) \
257 ccc_impl_hom_insert(hom_ins_or_assign_hndl_.hom_, \
258 hom_ins_or_assign_hndl_ret_.i_); \
259 hom_ins_or_assign_hndl_ret_.stats_ = CCC_ENTRY_VACANT; \
262 else if (hom_ins_or_assign_hndl_.handle_.stats_ \
263 == CCC_ENTRY_OCCUPIED) \
265 struct ccc_homap_elem_ ins_hndl_saved_ \
266 = *ccc_impl_homap_elem_at( \
267 hom_ins_or_assign_hndl_.hom_, \
268 hom_ins_or_assign_hndl_.handle_.i_); \
269 *((typeof(lazy_value) *)ccc_buf_at( \
270 &hom_ins_or_assign_hndl_.hom_->buf_, \
271 hom_ins_or_assign_hndl_.handle_.i_)) \
273 *ccc_impl_homap_elem_at(hom_ins_or_assign_hndl_.hom_, \
274 hom_ins_or_assign_hndl_.handle_.i_) \
276 hom_ins_or_assign_hndl_ret_ = (struct ccc_handl_){ \
277 .i_ = hom_ins_or_assign_hndl_.handle_.i_, \
278 .stats_ = hom_ins_or_assign_hndl_.handle_.stats_}; \
279 *((typeof(hom_key_) *)ccc_impl_hom_key_at( \
280 hom_ins_or_assign_hndl_.hom_, \
281 hom_ins_or_assign_hndl_.handle_.i_)) \
285 hom_ins_or_assign_hndl_ret_; \
struct ccc_buf_ ccc_buffer
A contiguous block of storage for elements of the same type.
Definition: buffer.h:50
ccc_threeway_cmp ccc_key_cmp_fn(ccc_key_cmp)
A callback function for three-way comparing two stored keys.
Definition: types.h:333
ccc_threeway_cmp
A three-way comparison for comparison functions.
Definition: types.h:138