C Container Collection (CCC)
Loading...
Searching...
No Matches
impl_flat_priority_queue.h
1
16#ifndef CCC_IMPL_FLAT_PRIORITY_QUEUE_H
17#define CCC_IMPL_FLAT_PRIORITY_QUEUE_H
18
20#include <assert.h>
21#include <stddef.h>
24#include "../buffer.h"
25#include "../types.h"
26
27/* NOLINTBEGIN(readability-identifier-naming) */
28
35struct ccc_fpq
36{
38 ccc_buffer buf;
40 ccc_threeway_cmp order;
43};
44
45/*======================== Private Interface =========================*/
46
48size_t ccc_impl_fpq_bubble_up(struct ccc_fpq *, char[], size_t);
50void ccc_impl_fpq_in_place_heapify(struct ccc_fpq *, size_t n);
52void *ccc_impl_fpq_update_fixup(struct ccc_fpq *, void *);
53
54/*====================== Macro Implementations ========================*/
55
57#define ccc_impl_fpq_init(impl_mem_ptr, impl_cmp_order, impl_cmp_fn, \
58 impl_alloc_fn, impl_aux_data, impl_capacity) \
59 { \
60 .buf = ccc_buf_init(impl_mem_ptr, impl_alloc_fn, impl_aux_data, \
61 impl_capacity), \
62 .cmp = (impl_cmp_fn), \
63 .order = (impl_cmp_order), \
64 }
65
67#define ccc_impl_fpq_heapify_init(impl_mem_ptr, impl_cmp_order, impl_cmp_fn, \
68 impl_alloc_fn, impl_aux_data, impl_capacity, \
69 impl_size) \
70 (__extension__({ \
71 __auto_type impl_fpq_heapify_mem = (impl_mem_ptr); \
72 struct ccc_fpq impl_fpq_heapify_res = ccc_impl_fpq_init( \
73 impl_fpq_heapify_mem, impl_cmp_order, impl_cmp_fn, impl_alloc_fn, \
74 impl_aux_data, impl_capacity); \
75 ccc_impl_fpq_in_place_heapify(&impl_fpq_heapify_res, (impl_size)); \
76 impl_fpq_heapify_res; \
77 }))
78
82#define ccc_impl_fpq_emplace(fpq, type_initializer...) \
83 (__extension__({ \
84 typeof(type_initializer) *impl_fpq_res; \
85 struct ccc_fpq *impl_fpq = (fpq); \
86 assert(sizeof(*impl_fpq_res) \
87 == ccc_buf_sizeof_type(&impl_fpq->buf).count); \
88 impl_fpq_res = ccc_buf_alloc_back(&impl_fpq->buf); \
89 if (ccc_buf_size(&impl_fpq->buf).count \
90 == ccc_buf_capacity(&impl_fpq->buf).count) \
91 { \
92 impl_fpq_res = NULL; \
93 ccc_result const impl_extra_space = ccc_buf_alloc( \
94 &impl_fpq->buf, ccc_buf_capacity(&impl_fpq->buf).count * 2, \
95 impl_fpq->buf.alloc); \
96 if (impl_extra_space == CCC_RESULT_OK) \
97 { \
98 impl_fpq_res = ccc_buf_back(&impl_fpq->buf); \
99 } \
100 } \
101 if (impl_fpq_res) \
102 { \
103 *impl_fpq_res = type_initializer; \
104 if (ccc_buf_size(&impl_fpq->buf).count > 1) \
105 { \
106 void *impl_fpq_tmp = ccc_buf_at( \
107 &impl_fpq->buf, ccc_buf_size(&impl_fpq->buf).count); \
108 impl_fpq_res \
109 = ccc_buf_at(&impl_fpq->buf, \
110 ccc_impl_fpq_bubble_up( \
111 impl_fpq, impl_fpq_tmp, \
112 ccc_buf_size(&impl_fpq->buf).count - 1)); \
113 } \
114 else \
115 { \
116 impl_fpq_res = ccc_buf_at(&impl_fpq->buf, 0); \
117 } \
118 } \
119 impl_fpq_res; \
120 }))
121
124#define ccc_impl_fpq_update_w(fpq_ptr, T_ptr, update_closure_over_T...) \
125 (__extension__({ \
126 struct ccc_fpq *const impl_fpq = (fpq_ptr); \
127 typeof(*T_ptr) *T = (T_ptr); \
128 if (impl_fpq && !ccc_buf_is_empty(&impl_fpq->buf) && T) \
129 { \
130 {update_closure_over_T} T \
131 = ccc_impl_fpq_update_fixup(impl_fpq, T); \
132 } \
133 T; \
134 }))
135
137#define ccc_impl_fpq_increase_w(fpq_ptr, T_ptr, increase_closure_over_T...) \
138 ccc_impl_fpq_update_w(fpq_ptr, T_ptr, increase_closure_over_T)
139
141#define ccc_impl_fpq_decrease_w(fpq_ptr, T_ptr, decrease_closure_over_T...) \
142 ccc_impl_fpq_update_w(fpq_ptr, T_ptr, decrease_closure_over_T)
143
144/* NOLINTEND(readability-identifier-naming) */
145
146#endif /* CCC_IMPL_FLAT_PRIORITY_QUEUE_H */
struct ccc_buffer ccc_buffer
A contiguous block of storage for elements of the same type.
Definition: buffer.h:65
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
ccc_threeway_cmp
A three-way comparison for comparison functions.
Definition: types.h:153