C Container Collection (CCC)
Loading...
Searching...
No Matches
impl_priority_queue.h
1
16#ifndef CCC_IMPL_PRIORITY_QUEUE_H
17#define CCC_IMPL_PRIORITY_QUEUE_H
18
20#include <stddef.h>
23#include "../types.h"
24
25/* NOLINTBEGIN(readability-identifier-naming) */
26
33struct ccc_pq_elem
34{
36 struct ccc_pq_elem *child;
38 struct ccc_pq_elem *next;
40 struct ccc_pq_elem *prev;
42 struct ccc_pq_elem *parent;
43};
44
86struct ccc_pq
87{
89 struct ccc_pq_elem *root;
91 size_t count;
93 size_t pq_elem_offset;
95 size_t sizeof_type;
97 ccc_threeway_cmp order;
101 ccc_any_alloc_fn *alloc;
103 void *aux;
104};
105
106/*========================= Private Interface ==========================*/
107
109void ccc_impl_pq_push(struct ccc_pq *, struct ccc_pq_elem *);
111struct ccc_pq_elem *ccc_impl_pq_elem_in(struct ccc_pq const *, void const *);
113ccc_threeway_cmp ccc_impl_pq_cmp(struct ccc_pq const *,
114 struct ccc_pq_elem const *,
115 struct ccc_pq_elem const *);
117struct ccc_pq_elem *ccc_impl_pq_merge(struct ccc_pq *pq,
118 struct ccc_pq_elem *old,
119 struct ccc_pq_elem *new);
121void ccc_impl_pq_cut_child(struct ccc_pq_elem *);
123void ccc_impl_pq_init_node(struct ccc_pq_elem *);
125struct ccc_pq_elem *ccc_impl_pq_delete_node(struct ccc_pq *,
126 struct ccc_pq_elem *);
128void *ccc_impl_pq_struct_base(struct ccc_pq const *,
129 struct ccc_pq_elem const *);
130
131/*========================= Macro Implementations ======================*/
132
134#define ccc_impl_pq_init(impl_struct_name, impl_pq_elem_field, impl_pq_order, \
135 impl_cmp_fn, impl_alloc_fn, impl_aux_data) \
136 { \
137 .root = NULL, \
138 .count = 0, \
139 .pq_elem_offset = offsetof(impl_struct_name, impl_pq_elem_field), \
140 .sizeof_type = sizeof(impl_struct_name), \
141 .alloc = (impl_alloc_fn), \
142 .cmp = (impl_cmp_fn), \
143 .order = (impl_pq_order), \
144 .aux = (impl_aux_data), \
145 }
146
148#define ccc_impl_pq_emplace(pq_ptr, lazy_value...) \
149 (__extension__({ \
150 typeof(lazy_value) *impl_pq_res = NULL; \
151 struct ccc_pq *impl_pq = (pq_ptr); \
152 if (impl_pq) \
153 { \
154 if (!impl_pq->alloc) \
155 { \
156 impl_pq_res = NULL; \
157 } \
158 else \
159 { \
160 impl_pq_res = impl_pq->alloc(NULL, impl_pq->sizeof_type, \
161 impl_pq->aux); \
162 if (impl_pq_res) \
163 { \
164 *impl_pq_res = lazy_value; \
165 ccc_impl_pq_push( \
166 impl_pq, ccc_impl_pq_elem_in(impl_pq, impl_pq_res)); \
167 } \
168 } \
169 } \
170 impl_pq_res; \
171 }))
172
174#define ccc_impl_pq_update_w(pq_ptr, any_type_ptr, update_closure_over_T...) \
175 (__extension__({ \
176 struct ccc_pq *const impl_pq = (pq_ptr); \
177 typeof(*any_type_ptr) *T = (any_type_ptr); \
178 if (impl_pq && T) \
179 { \
180 struct ccc_pq_elem *const impl_pq_elem_ptr \
181 = ccc_impl_pq_elem_in(impl_pq, T); \
182 if (impl_pq_elem_ptr->parent \
183 && ccc_impl_pq_cmp(impl_pq, impl_pq_elem_ptr, \
184 impl_pq_elem_ptr->parent) \
185 == impl_pq->order) \
186 { \
187 ccc_impl_pq_cut_child(impl_pq_elem_ptr); \
188 {update_closure_over_T} impl_pq->root = ccc_impl_pq_merge( \
189 impl_pq, impl_pq->root, impl_pq_elem_ptr); \
190 } \
191 else \
192 { \
193 impl_pq->root \
194 = ccc_impl_pq_delete_node(impl_pq, impl_pq_elem_ptr); \
195 ccc_impl_pq_init_node(impl_pq_elem_ptr); \
196 {update_closure_over_T} impl_pq->root = ccc_impl_pq_merge( \
197 impl_pq, impl_pq->root, impl_pq_elem_ptr); \
198 } \
199 } \
200 T; \
201 }))
202
204#define ccc_impl_pq_increase_w(pq_ptr, any_type_ptr, \
205 increase_closure_over_T...) \
206 (__extension__({ \
207 struct ccc_pq *const impl_pq = (pq_ptr); \
208 typeof(*any_type_ptr) *T = (any_type_ptr); \
209 if (impl_pq && T) \
210 { \
211 struct ccc_pq_elem *const impl_pq_elem_ptr \
212 = ccc_impl_pq_elem_in(impl_pq, T); \
213 if (impl_pq->order == CCC_GRT) \
214 { \
215 ccc_impl_pq_cut_child(impl_pq_elem_ptr); \
216 } \
217 else \
218 { \
219 impl_pq->root \
220 = ccc_impl_pq_delete_node(impl_pq, impl_pq_elem_ptr); \
221 ccc_impl_pq_init_node(impl_pq_elem_ptr); \
222 } \
223 {increase_closure_over_T} impl_pq->root \
224 = ccc_impl_pq_merge(impl_pq, impl_pq->root, impl_pq_elem_ptr); \
225 } \
226 T; \
227 }))
228
230#define ccc_impl_pq_decrease_w(pq_ptr, any_type_ptr, \
231 decrease_closure_over_T...) \
232 (__extension__({ \
233 struct ccc_pq *const impl_pq = (pq_ptr); \
234 typeof(*any_type_ptr) *T = (any_type_ptr); \
235 if (impl_pq && T) \
236 { \
237 struct ccc_pq_elem *const impl_pq_elem_ptr \
238 = ccc_impl_pq_elem_in(impl_pq, T); \
239 if (impl_pq->order == CCC_LES) \
240 { \
241 ccc_impl_pq_cut_child(impl_pq_elem_ptr); \
242 } \
243 else \
244 { \
245 impl_pq->root \
246 = ccc_impl_pq_delete_node(impl_pq, impl_pq_elem_ptr); \
247 ccc_impl_pq_init_node(impl_pq_elem_ptr); \
248 } \
249 {decrease_closure_over_T} impl_pq->root \
250 = ccc_impl_pq_merge(impl_pq, impl_pq->root, impl_pq_elem_ptr); \
251 } \
252 T; \
253 }))
254
255/* NOLINTEND(readability-identifier-naming) */
256
257#endif /* CCC_IMPL_PRIORITY_QUEUE_H */
struct ccc_pq_elem ccc_pq_elem
The embedded struct type for operation of the priority queue.
Definition: priority_queue.h:63
ccc_threeway_cmp ccc_any_type_cmp_fn(ccc_any_type_cmp)
A callback function for comparing two elements in a container.
Definition: types.h:320
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
A three-way comparison for comparison functions.
Definition: types.h:153