15 #if !defined __clang_analyzer__
16 #error "The contained type must be defined for a queue template"
24 #define ITEM_DELETE item_delete
26 #define ITEM_CLONE item_clone
29#if !defined ITEM_DELETE
30 #define ITEM_DELETE(value)
33#if !defined ITEM_CLONE
34 #define ITEM_CLONE(value) (*(value))
48 return (
SELF){.data = NULL,
57 if (capacity_for == 0) {
58 return NS(
SELF,
new)(alloc);
91 if (self->head <= self->tail) {
92 return (self->tail - self->head) + 1;
94 return (self->capacity - self->head) + self->tail + 1;
100 if (new_capacity_for > self->capacity) {
105 if (self->head > self->tail) {
110 size_t old_capacity = self->capacity;
111 size_t additional_capacity = new_capacity - old_capacity;
112 size_t front_tail_items = self->tail + 1;
113 size_t back_head_items = old_capacity - self->head;
115 if (front_tail_items > back_head_items) {
116 size_t new_head = self->head + additional_capacity;
117 memmove(&new_data[new_head], &new_data[self->head], back_head_items *
sizeof(
ITEM));
118 self->head = new_head;
126 memcpy(&new_data[old_capacity], &new_data[0], front_tail_items *
sizeof(
ITEM));
127 self->tail = old_capacity + front_tail_items - 1;
130 self->capacity = new_capacity;
131 self->data = new_data;
142 self->data[self->tail] = item;
151 if (self->head == 0) {
152 self->head = self->capacity - 1;
157 self->data[self->head] = item;
165 ITEM value = self->data[self->head];
166 if (self->head == self->tail) {
178 ITEM value = self->data[self->tail];
179 if (self->head == self->tail) {
182 if (self->tail == 0) {
183 self->tail = self->capacity - 1;
195 return &self->data[real_index];
211 return &self->data[real_index];
223#define ITER NS(SELF, iter)
229static bool NS(ITER,
empty)(ITER
const* iter) {
257 while ((item =
NS(ITER,
next)(&iter))) {
266#define ITER_CONST NS(SELF, iter_const)
268 SELF const* circular;
272static bool NS(ITER_CONST,
empty)(ITER_CONST
const* iter) {
297 ITEM* new_data = NULL;
299 size_t new_capacity = 0;
309 while ((item =
NS(ITER_CONST,
next)(&iter))) {
317 .capacity = new_capacity,
320 .empty = self->empty,
321 .alloc = self->alloc,
static void free(SELF *self, void *ptr)
static void * realloc(SELF *self, void *ptr, size_t size)
static void * malloc(SELF *self, size_t size)
static bool is_power_of_2(size_t x)
static size_t next_power_of_2(size_t x)
static size_t modulus_power_of_2_capacity(size_t index, size_t capacity)
#define DEBUG_ASSERT(expr)
gdb_marker derive_c_circular
A queue comprised of an extendable circular buffer.
static ITER_CONST get_iter_const(SELF const *self)
static bool empty(ITER const *iter)
static ITER get_iter(SELF *self)
static SELF new_with_capacity_for(INDEX_TYPE items, ALLOC *alloc)
static INDEX_TYPE size(SELF const *self)
static IV_PAIR const * next(ITER *iter)
static SELF clone(SELF const *self)
static ITEM const * read_from_front(SELF const *self, size_t index)
static ITEM pop_front(SELF *self)
static ITEM pop_back(SELF *self)
static void reserve(SELF *self, size_t new_capacity_for)
static ITEM * try_write_from_front(SELF *self, size_t index)
static ITEM * write_from_front(SELF *self, size_t index)
static void push_back(SELF *self, ITEM item)
static void item_delete(item_t *UNUSED(self))
static ITEM const * try_read_from_front(SELF const *self, size_t index)
static item_t item_clone(item_t const *self)
static void push_front(SELF *self, ITEM item)
static size_t position(ITER const *iter)
static ITEM * data(SELF *self)