4#if !defined(SKIP_INCLUDES)
12 #if !defined DC_PLACEHOLDERS
19 #define ITEM_DELETE item_delete
21 #define ITEM_CLONE item_clone
23 #define ITEM_DEBUG item_debug
27#if !defined ITEM_DELETE
28 #define ITEM_DELETE DC_NO_DELETE
31#if !defined ITEM_CLONE
32 #define ITEM_CLONE DC_COPY_CLONE
35#if !defined ITEM_DEBUG
36 #define ITEM_DEBUG DC_DEFAULT_DEBUG
51#define INVARIANT_CHECK(self) \
53 DC_ASSUME((self)->size <= (self)->capacity); \
54 DC_ASSUME(DC_WHEN(!((self)->data), (self)->capacity == 0 && (self)->size == 0));
63 .alloc_ref = alloc_ref,
72 return NS(
SELF,
new)(alloc_ref);
77 capacity *
sizeof(
ITEM));
82 .alloc_ref = alloc_ref,
93 data[0] = default_item;
94 for (
size_t i = 1; i <
size; i++) {
102 .alloc_ref = alloc_ref,
110 if (new_capacity > self->capacity) {
111 if (self->data == NULL) {
116 self->data = new_data;
117 self->capacity = new_capacity;
119 self->data, self->capacity *
sizeof(
ITEM));
121 const size_t capacity_increase = new_capacity - self->capacity;
122 const size_t uninit_elements = self->capacity - self->size;
125 &self->data[self->size], uninit_elements *
sizeof(
ITEM));
127 size_t old_size = self->capacity *
sizeof(
ITEM);
128 size_t new_size = new_capacity *
sizeof(
ITEM);
132 self->data = new_data;
134 &self->data[self->size],
135 (uninit_elements + capacity_increase) *
sizeof(
ITEM));
136 self->capacity = new_capacity;
145 for (
size_t index = 0; index < self->size; index++) {
149 &
data[self->size], (self->capacity - self->size) *
sizeof(
ITEM));
152 .capacity = self->capacity,
154 .alloc_ref = self->alloc_ref,
163 return &self->data[index];
170 DC_ASSERT(
item,
"Cannot read, index out of bounds {index=%lu, size=%lu}", (
size_t)index,
178 return &self->data[index];
185 DC_ASSERT(
item,
"Cannot write, index out of bounds {index=%lu, size=%lu}", (
size_t)index,
194 DC_ASSERT(at <= self->
size,
"Cannot insert at, index out of bounds {at=%lu, size=%lu}",
195 (
size_t)at, (
size_t)self->size);
204 &self->data[self->size], count *
sizeof(
ITEM));
205 memmove(&self->data[at + count], &self->data[at], (self->size - at) *
sizeof(
ITEM));
206 memcpy(&self->data[at], items, count *
sizeof(
ITEM));
208 return &self->data[at];
214 "Cannot remove at, index out of bounds {at=%lu, count=%lu, size=%lu}", (
size_t)at,
215 (
size_t)count, (
size_t)self->size);
222 for (
size_t i = at; i < at + count; i++) {
226 memmove(&self->data[at], &self->data[at + count], (self->size - (at + count)) *
sizeof(
ITEM));
229 &self->data[self->size], count *
sizeof(
ITEM));
236 if (self->size == self->capacity) {
238 if (self->data == NULL) {
249 new_capacity = self->capacity * 2;
255 &self->data[self->size],
sizeof(
ITEM));
257 ITEM* entry = &self->data[self->size];
265 DC_ASSERT(entry != NULL,
"Cannot push, already at max capacity {capacity=%lu, item=%s}",
276 *destination = self->data[self->size];
278 &self->data[self->size],
sizeof(
ITEM));
299 DC_ASSERT(self->size > 0,
"Cannot pop front, already empty {size=%lu}", (
size_t)self->size);
300 ITEM entry = self->data[0];
301 memmove(&self->data[0], &self->data[1], (self->size - 1) *
sizeof(
ITEM));
304 &self->data[self->size],
sizeof(
ITEM));
316 for (
size_t i = 0; i < self->size; i++) {
321 &self->data[i],
sizeof(
ITEM));
326 size_t const size = self->capacity *
sizeof(
ITEM);
355 &target->data[target->size], to_move *
sizeof(
ITEM));
356 memmove(&target->data[to_move], target->data, target->size *
sizeof(
ITEM));
358 for (
size_t i = 0; i < to_move; i++) {
359 target->data[to_move - 1 - i] = source->data[i];
362 memmove(source->data, &source->data[to_move], (source->size - to_move) *
sizeof(
ITEM));
364 source->size -= to_move;
365 target->size += to_move;
367 &source->data[source->size], to_move *
sizeof(
ITEM));
370#define ITER NS(SELF, iter)
386 if (iter->pos < iter->size) {
387 ITEM*
item = &iter->data[iter->pos];
403 return iter->pos >= iter->size;
417#define ITER_CONST NS(SELF, iter_const)
421 return *
item == NULL;
434 if (iter->pos < iter->size) {
435 ITEM const*
item = &iter->data[iter->pos];
451 return iter->pos >= iter->size;
491#undef INVARIANT_CHECK
static DC_PUBLIC void deallocate(SELF *self, void *ptr, size_t size)
static DC_PUBLIC void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
static DC_PUBLIC void * allocate_uninit(SELF *self, size_t size)
static DC_PUBLIC void * reallocate(SELF *self, void *ptr, size_t old_size, size_t new_size)
#define DC_STATIC_CONSTANT
static DC_PUBLIC VALUE const * try_read(SELF const *self, INDEX index)
static DC_PUBLIC VALUE * try_write(SELF *self, INDEX index)
#define INVARIANT_CHECK(self)
static DC_PUBLIC IV_PAIR next(ITER *iter)
static DC_PUBLIC bool empty(ITER const *iter)
static DC_PUBLIC VALUE const * read(SELF const *self, INDEX index)
static DC_PUBLIC VALUE * write(SELF *self, INDEX index)
static DC_PUBLIC bool empty_item(IV_PAIR const *item)
static DC_PUBLIC ITER get_iter(SELF *self)
static DC_PUBLIC ITER_CONST get_iter_const(SELF const *self)
static DC_PUBLIC size_t size(SELF const *self)
static DC_PUBLIC SELF clone(SELF const *self)
static DC_PUBLIC void reserve(SELF *self, size_t new_capacity_for)
static DC_PUBLIC ITEM pop_front(SELF *self)
static DC_PUBLIC SELF new_with_capacity(size_t front_and_back_capacity, ref alloc_ref)
static DC_PUBLIC ITEM * data(SELF *self)
static DC_PUBLIC ITEM * try_push(SELF *self, ITEM item)
DC_STATIC_CONSTANT size_t max_size
static DC_PUBLIC bool try_pop(SELF *self, ITEM *destination)
static DC_PUBLIC ITEM * try_insert_at(SELF *self, size_t at, ITEM const *items, size_t count)
static DC_PUBLIC void remove_at(SELF *self, size_t at, size_t count)
static DC_PUBLIC ITEM * push(SELF *self, ITEM item)
static DC_PUBLIC DC_INLINE size_t position(ITER const *DC_RESTRICT iter)
static DC_PUBLIC ITEM pop(SELF *self)
static DC_PUBLIC void transfer_reverse(SELF *source, SELF *target, size_t to_move)
static DC_PUBLIC SELF new_with_defaults(size_t size, ITEM default_item, ref alloc_ref)
#define DC_TRAIT_VECTOR(SELF)
#define TEMPLATE_ERROR(...)
With the user provided name, even in nested templates.
#define DC_DEBUG(DEBUG_FN, DEBUG_PTR)
static DC_PUBLIC void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
static DC_PUBLIC void dc_debug_fmt_print_indents(dc_debug_fmt fmt, FILE *stream)
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
static DC_PUBLIC dc_gdb_marker dc_gdb_marker_new()
static DC_PUBLIC void dc_memory_tracker_set(dc_memory_tracker_level level, dc_memory_tracker_capability cap, const volatile void *addr, size_t size)
@ DC_MEMORY_TRACKER_LVL_CONTAINER
@ DC_MEMORY_TRACKER_CAP_WRITE
@ DC_MEMORY_TRACKER_CAP_NONE
static DC_PUBLIC void mutation_tracker_mutate(mutation_tracker *self)
static DC_PUBLIC void mutation_version_check(mutation_version const *self)
static DC_PUBLIC mutation_tracker mutation_tracker_new()
static DC_PUBLIC mutation_version mutation_tracker_get(mutation_tracker const *self)
#define DC_EXPAND_STRING(NAME)
#define DC_ASSERT(expr,...)
#define DC_ASSUME(expr,...)
mutation_version vec_version
mutation_tracker iterator_invalidation_tracker
dc_gdb_marker derive_c_vector_marker
Debug format helpers for debug printin data structures.
A queue comprised of an extendable circular buffer.
tracks a specific version of a value, so that this can be compared later to check modification For ex...
static DC_PUBLIC FILE * stream(SELF *self)