20#define restrict __restrict__
40#define PASTE(a, b) a##b
48#define XPASTE(a, b) PASTE(a, b)
56#define JOIN(a, b) XPASTE(a, XPASTE(_, b))
65#ifndef FPQUEUE_LEFT_CHILD
66#define FPQUEUE_LEFT_CHILD(index) (2 * (index) + 1)
75#ifndef FPQUEUE_RIGHT_CHILD
76#define FPQUEUE_RIGHT_CHILD(index) (2 * (index) + 2)
86#define FPQUEUE_PARENT(index) (((index) - 1) / 2)
100#ifndef FPQUEUE_FOR_EACH
101#define FPQUEUE_FOR_EACH(self, index, value_) \
102 for ((index) = 0; (index) < (self)->count && ((value_) = (self)->elements[(index)].value, true); (index)++)
115#ifndef FPQUEUE_CALC_SIZEOF
116#define FPQUEUE_CALC_SIZEOF(fpqueue_name, capacity) \
117 (uint32_t)(offsetof(struct fpqueue_name, elements) + capacity * sizeof(((struct fpqueue_name *)0)->elements[0]))
130#ifndef FPQUEUE_CALC_SIZEOF_OVERFLOWS
131#define FPQUEUE_CALC_SIZEOF_OVERFLOWS(fpqueue_name, capacity) \
133 > (UINT32_MAX - offsetof(struct fpqueue_name, elements)) / sizeof(((struct fpqueue_name *)0)->elements[0]))
144#error "Must define NAME."
146#define FPQUEUE_NAME NAME
157#define VALUE_TYPE int
158#define FUNCTION_DEFINITIONS
159#define TYPE_DEFINITIONS
160#error "Must declare VALUE_TYPE."
167#ifndef FUNCTION_LINKAGE
168#define FUNCTION_LINKAGE
172#define FPQUEUE_TYPE struct FPQUEUE_NAME
173#define FPQUEUE_ELEMENT_TYPE struct JOIN(FPQUEUE_NAME, element)
174#define FPQUEUE_INIT JOIN(FPQUEUE_NAME, init)
175#define FPQUEUE_IS_EMPTY JOIN(FPQUEUE_NAME, is_empty)
176#define FPQUEUE_IS_FULL JOIN(FPQUEUE_NAME, is_full)
177#define FPQUEUE_UPHEAP JOIN(internal, JOIN(FPQUEUE_NAME, upheap))
178#define FPQUEUE_DOWNHEAP JOIN(internal, JOIN(FPQUEUE_NAME, downheap))
189#ifdef TYPE_DEFINITIONS
194struct JOIN(FPQUEUE_NAME, element) {
220FUNCTION_LINKAGE FPQUEUE_TYPE *
JOIN(FPQUEUE_NAME, init)(FPQUEUE_TYPE *self,
const uint32_t capacity);
323FUNCTION_LINKAGE void JOIN(FPQUEUE_NAME, copy)(FPQUEUE_TYPE *restrict dest_ptr,
const FPQUEUE_TYPE *restrict src_ptr);
333#ifdef FUNCTION_DEFINITIONS
338static inline void JOIN(internal,
JOIN(FPQUEUE_NAME, downheap))(FPQUEUE_TYPE *self,
const uint32_t index);
341static inline void JOIN(internal,
JOIN(FPQUEUE_NAME, upheap))(FPQUEUE_TYPE *self, uint32_t index);
350 self->capacity = capacity;
363 FPQUEUE_TYPE *self = (FPQUEUE_TYPE *)calloc(1, size);
369 FPQUEUE_INIT(self, capacity);
376 assert(self != NULL);
383 assert(self != NULL);
385 return self->count == 0;
390 assert(self != NULL);
392 return self->count == self->capacity;
397 assert(self != NULL);
398 assert(FPQUEUE_IS_EMPTY(self) ==
false);
400 return self->elements[0].value;
405 return JOIN(FPQUEUE_NAME, get_max)(self);
410 assert(self != NULL);
411 assert(FPQUEUE_IS_EMPTY(self) ==
false);
413 VALUE_TYPE max_priority_value = self->elements[0].value;
415 self->elements[0] = self->elements[self->count - 1];
419 JOIN(internal,
JOIN(FPQUEUE_NAME, downheap))(self, 0);
421 return max_priority_value;
426 assert(self != NULL);
427 assert(FPQUEUE_IS_FULL(self) ==
false);
429 const uint32_t index = self->count;
431 self->elements[index] = (FPQUEUE_ELEMENT_TYPE){.priority = priority, .value = value};
435 JOIN(internal,
JOIN(FPQUEUE_NAME, upheap))(self, index);
440 assert(self != NULL);
445FUNCTION_LINKAGE void JOIN(FPQUEUE_NAME, copy)(FPQUEUE_TYPE *restrict dest_ptr,
const FPQUEUE_TYPE *restrict src_ptr)
447 assert(src_ptr != NULL);
448 assert(dest_ptr != NULL);
449 assert(src_ptr->count <= dest_ptr->capacity);
450 assert(FPQUEUE_IS_EMPTY(dest_ptr));
452 for (uint32_t i = 0; i < src_ptr->count; i++) {
453 dest_ptr->elements[i] = src_ptr->elements[i];
455 dest_ptr->count = src_ptr->count;
460static inline void JOIN(internal,
JOIN(FPQUEUE_NAME, upheap))(FPQUEUE_TYPE *self, uint32_t index)
462 assert(self != NULL);
463 assert(index < self->count);
469 const bool sorted = self->elements[parent].priority >= self->elements[index].priority;
475 const FPQUEUE_ELEMENT_TYPE temp = self->elements[index];
476 self->elements[index] = self->elements[parent];
477 self->elements[parent] = temp;
483static inline void JOIN(internal,
JOIN(FPQUEUE_NAME, downheap))(FPQUEUE_TYPE *self,
const uint32_t index)
485 assert(self != NULL);
486 assert(self->count == 0 || index < self->count);
491 uint32_t largest = index;
492 if (l < self->count && self->elements[l].priority > self->elements[index].priority) {
495 if (r < self->count && self->elements[r].priority > self->elements[largest].priority) {
499 if (largest == index) {
503 const FPQUEUE_ELEMENT_TYPE temp = self->elements[index];
504 self->elements[index] = self->elements[largest];
505 self->elements[largest] = temp;
507 JOIN(internal,
JOIN(FPQUEUE_NAME, downheap))(self, largest);
519#undef FUNCTION_LINKAGE
520#undef FUNCTION_DEFINITIONS
521#undef TYPE_DEFINITIONS
525#undef FPQUEUE_ELEMENT_TYPE
527#undef FPQUEUE_IS_EMPTY
528#undef FPQUEUE_IS_FULL
529#undef FPQUEUE_CALC_SIZEOF
530#undef FHASHTABLE_UPHEAP
531#undef FHASHTABLE_DOWNHEAP
#define JOIN(a, b)
First expand tokens, then paste them together with a _ in between.
Definition fpqueue_template.h:56
#define FPQUEUE_RIGHT_CHILD(index)
Given an element index, get the index of the right child.
Definition fpqueue_template.h:76
#define FPQUEUE_CALC_SIZEOF(fpqueue_name, capacity)
Calculate the size of the pqueue struct. No overflow checks.
Definition fpqueue_template.h:116
#define FPQUEUE_LEFT_CHILD(index)
Given an element index, get the index of the left child.
Definition fpqueue_template.h:66
#define FPQUEUE_PARENT(index)
Given an element index, get the index of the parent.
Definition fpqueue_template.h:86
#define VALUE_TYPE
Priority queue value type. This must be manually defined before including this header file.
Definition fpqueue_template.h:157
#define FPQUEUE_CALC_SIZEOF_OVERFLOWS(fpqueue_name, capacity)
Check for a given capacity, if the equivalent size of the pqueue struct overflows.
Definition fpqueue_template.h:131
#define FUNCTION_LINKAGE
Specify function linkage e.g. static inline.
Definition fstack_template.h:146
#define VALUE_TYPE
Stack value type. This must be manually defined before including this header file.
Definition fstack_template.h:135
uint32_t priority
Element priority (highest is next to-be-popped).
Definition fpqueue_template.h:195
VALUE_TYPE value
Element value member.
Definition fpqueue_template.h:196
uint32_t capacity
Number of elements allocated for.
Definition fpqueue_template.h:204
fpqueue_element_type elements[]
Array of elements.
Definition fpqueue_template.h:205
uint32_t count
Number of non-empty elements.
Definition fpqueue_template.h:203