Derive-C
Loading...
Searching...
No Matches
template.h File Reference

Go to the source code of this file.

Data Structures

struct  item_t
 A queue comprised of an extendable circular buffer. More...
struct  SELF
 An allocator that prints to stdout when it allocates or frees memory. More...
struct  ITER
struct  ITER_CONST

Macros

#define ITEM   item_t
#define ITEM_DELETE   item_delete
#define ITEM_CLONE   item_clone
#define ITEM_DEBUG   item_debug
#define ITEM_VECTORS   NS(NAME, item_vectors)
#define INTERNAL_NAME   ITEM_VECTORS
#define INVARIANT_CHECK(self)
#define ITER   NS(SELF, iter)
#define ITER_CONST   NS(SELF, iter_const)

Typedefs

typedef ITEMitem

Functions

static void ITEM_DELETE (item_t *)
static item_t ITEM_CLONE (item_t const *self)
static void ITEM_DEBUG (ITEM const *, dc_debug_fmt, FILE *)
static DC_PUBLIC SELF new (ref alloc_ref)
static DC_PUBLIC SELF new_with_capacity (size_t front_and_back_capacity, ref alloc_ref)
static DC_PUBLIC SELF clone (SELF const *other)
static DC_PUBLIC size_t size (SELF const *self)
static DC_PUBLIC bool empty (SELF const *self)
static DC_PUBLIC void rebalance (SELF *self)
static DC_PUBLIC ITEM const * try_read_from_front (SELF const *self, size_t index)
static DC_PUBLIC ITEM const * try_read_from_back (SELF const *self, size_t index)
static DC_PUBLIC ITEMtry_write_from_front (SELF *self, size_t index)
static DC_PUBLIC ITEMtry_write_from_back (SELF *self, size_t index)
static DC_PUBLIC void push_front (SELF *self, ITEM item)
static DC_PUBLIC void push_back (SELF *self, ITEM item)
static DC_PUBLIC ITEM pop_front (SELF *self)
static DC_PUBLIC ITEM pop_back (SELF *self)
static DC_PUBLIC bool empty_item (ITEM *const *item)
static DC_PUBLIC ITEMnext (ITER *iter)
static DC_PUBLIC bool empty (ITER const *iter)
static DC_PUBLIC ITER get_iter (SELF *self)
static DC_PUBLIC bool empty_item (ITEM const *const *item)
static DC_PUBLIC ITEM const * next (ITER_CONST *iter)
static DC_PUBLIC bool empty (ITER_CONST const *iter)
static DC_PUBLIC ITER_CONST get_iter_const (SELF const *self)
static DC_PUBLIC void delete (SELF *self)
static DC_PUBLIC void debug (SELF const *self, dc_debug_fmt fmt, FILE *stream)
 DC_TRAIT_QUEUE (SELF)

Macro Definition Documentation

◆ INTERNAL_NAME

#define INTERNAL_NAME   ITEM_VECTORS

Definition at line 52 of file template.h.

◆ INVARIANT_CHECK

#define INVARIANT_CHECK ( self)
Value:
DC_ASSUME(self);
#define DC_ASSUME(expr,...)
Definition panic.h:57

Definition at line 67 of file template.h.

◆ ITEM

#define ITEM   item_t

Definition at line 19 of file template.h.

◆ ITEM_CLONE

#define ITEM_CLONE   item_clone

Definition at line 23 of file template.h.

◆ ITEM_DEBUG

#define ITEM_DEBUG   item_debug

Definition at line 25 of file template.h.

◆ ITEM_DELETE

#define ITEM_DELETE   item_delete

Definition at line 21 of file template.h.

◆ ITEM_VECTORS

#define ITEM_VECTORS   NS(NAME, item_vectors)

Definition at line 44 of file template.h.

◆ ITER

#define ITER   NS(SELF, iter)

Definition at line 226 of file template.h.

◆ ITER_CONST

#define ITER_CONST   NS(SELF, iter_const)

Definition at line 273 of file template.h.

Typedef Documentation

◆ item

typedef ITEM const* item

Definition at line 227 of file template.h.

Function Documentation

◆ clone()

DC_PUBLIC SELF clone ( SELF const * other)
static

Definition at line 88 of file template.h.

88 {
89 INVARIANT_CHECK(other);
90 return (SELF){
91 .front = NS(ITEM_VECTORS, clone)(&other->front),
92 .back = NS(ITEM_VECTORS, clone)(&other->back),
93 .derive_c_deque = dc_gdb_marker_new(),
94 .iterator_invalidation_tracker = mutation_tracker_new(),
95 };
96}
#define INVARIANT_CHECK(self)
Definition template.h:90
static DC_PUBLIC SELF clone(SELF const *self)
Definition template.h:215
#define ITEM_VECTORS
Definition template.h:44
#define SELF
Definition def.h:52
static DC_PUBLIC dc_gdb_marker dc_gdb_marker_new()
Definition gdb_marker.h:8
static DC_PUBLIC mutation_tracker mutation_tracker_new()
#define NS(pre, post)
Definition namespace.h:14

◆ DC_TRAIT_QUEUE()

DC_TRAIT_QUEUE ( SELF )

◆ debug()

DC_PUBLIC void debug ( SELF const * self,
dc_debug_fmt fmt,
FILE * stream )
static

Definition at line 328 of file template.h.

328 {
329 fprintf(stream, DC_EXPAND_STRING(SELF) "@%p {\n", self);
330 fmt = dc_debug_fmt_scope_begin(fmt);
331 dc_debug_fmt_print(fmt, stream, "size: %lu,\n", NS(SELF, size)(self));
332
333 dc_debug_fmt_print(fmt, stream, "front: ");
334 NS(ITEM_VECTORS, debug)(&self->front, fmt, stream);
335 fprintf(stream, ",\n");
336
337 dc_debug_fmt_print(fmt, stream, "back: ");
338 NS(ITEM_VECTORS, debug)(&self->back, fmt, stream);
339 fprintf(stream, ",\n");
340
341 fmt = dc_debug_fmt_scope_end(fmt);
342 dc_debug_fmt_print(fmt, stream, "}");
343}
static DC_PUBLIC void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
Definition template.h:212
static DC_PUBLIC size_t size(SELF const *self)
Definition template.h:252
static DC_PUBLIC void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
Definition fmt.h:32
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
Definition fmt.h:57
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
Definition fmt.h:50
#define DC_EXPAND_STRING(NAME)
Definition namespace.h:6
static DC_PUBLIC FILE * stream(SELF *self)
Definition template.h:108

◆ delete()

DC_PUBLIC void delete ( SELF * self)
static

Definition at line 322 of file template.h.

322 {
323 INVARIANT_CHECK(self);
324 NS(ITEM_VECTORS, delete)(&self->front);
325 NS(ITEM_VECTORS, delete)(&self->back);
326}
ITEM_VECTORS back
Definition template.h:62
ITEM_VECTORS front
Definition template.h:61

◆ empty() [1/3]

DC_PUBLIC bool empty ( ITER const * iter)
static

Definition at line 257 of file template.h.

257 {
258 mutation_version_check(&iter->version);
259 DC_ASSUME(iter);
260 return iter->pos >=
261 NS(ITEM_VECTORS, size)(&iter->deque->front) + NS(ITEM_VECTORS, size)(&iter->deque->back);
262}
static DC_PUBLIC void mutation_version_check(mutation_version const *self)

◆ empty() [2/3]

DC_PUBLIC bool empty ( ITER_CONST const * iter)
static

Definition at line 304 of file template.h.

304 {
305 DC_ASSUME(iter);
306 mutation_version_check(&iter->version);
307 return iter->pos >=
308 NS(ITEM_VECTORS, size)(&iter->deque->front) + NS(ITEM_VECTORS, size)(&iter->deque->back);
309}

◆ empty() [3/3]

DC_PUBLIC bool empty ( SELF const * self)
static

Definition at line 103 of file template.h.

103 {
104 INVARIANT_CHECK(self);
105 return NS(ITEM_VECTORS, size)(&self->front) == 0 && NS(ITEM_VECTORS, size)(&self->back) == 0;
106}

◆ empty_item() [1/2]

DC_PUBLIC bool empty_item ( ITEM *const * item)
static

Definition at line 229 of file template.h.

229{ return *item == NULL; }
IV_PAIR item
Definition template.h:281

◆ empty_item() [2/2]

DC_PUBLIC bool empty_item ( ITEM const *const * item)
static

Definition at line 276 of file template.h.

276{ return *item == NULL; }

◆ get_iter()

DC_PUBLIC ITER get_iter ( SELF * self)
static

Definition at line 264 of file template.h.

264 {
265 DC_ASSUME(self);
266 return (ITER){.deque = self,
267 .pos = 0,
269}
#define ITER
Definition template.h:322
static DC_PUBLIC mutation_version mutation_tracker_get(mutation_tracker const *self)
mutation_tracker iterator_invalidation_tracker
Definition template.h:87

◆ get_iter_const()

DC_PUBLIC ITER_CONST get_iter_const ( SELF const * self)
static

Definition at line 311 of file template.h.

311 {
312 DC_ASSUME(self);
313 return (ITER_CONST){
314 .deque = self,
315 .pos = 0,
316 .version = mutation_tracker_get(&self->iterator_invalidation_tracker),
317 };
318}
#define ITER_CONST
Definition template.h:411

◆ ITEM_CLONE()

item_t ITEM_CLONE ( item_t const * self)
static

Definition at line 24 of file template.h.

24{ return *self; }

◆ ITEM_DEBUG()

void ITEM_DEBUG ( ITEM const * ,
dc_debug_fmt ,
FILE *  )
static

Definition at line 26 of file template.h.

26{}

◆ ITEM_DELETE()

void ITEM_DELETE ( item_t * )
static

Definition at line 22 of file template.h.

22{}

◆ new()

DC_PUBLIC SELF new ( ref alloc_ref)
static

Definition at line 69 of file template.h.

69 {
70 return (SELF){
71 .front = NS(ITEM_VECTORS, new)(alloc_ref),
72 .back = NS(ITEM_VECTORS, new)(alloc_ref),
73 .derive_c_deque = dc_gdb_marker_new(),
74 .iterator_invalidation_tracker = mutation_tracker_new(),
75 };
76}

◆ new_with_capacity()

DC_PUBLIC SELF new_with_capacity ( size_t front_and_back_capacity,
ref alloc_ref )
static

Definition at line 78 of file template.h.

79 {
80 return (SELF){
81 .front = NS(ITEM_VECTORS, new_with_capacity)(front_and_back_capacity, alloc_ref),
82 .back = NS(ITEM_VECTORS, new_with_capacity)(front_and_back_capacity, alloc_ref),
83 .derive_c_deque = dc_gdb_marker_new(),
84 .iterator_invalidation_tracker = mutation_tracker_new(),
85 };
86}
static DC_PUBLIC SELF new_with_capacity(size_t front_and_back_capacity, ref alloc_ref)
Definition template.h:78

◆ next() [1/2]

DC_PUBLIC ITEM * next ( ITER * iter)
static

Definition at line 237 of file template.h.

237 {
238 DC_ASSUME(iter);
240 size_t const front_size = NS(ITEM_VECTORS, size)(&iter->deque->front);
241 size_t const back_size = NS(ITEM_VECTORS, size)(&iter->deque->back);
242 size_t const total_size = front_size + back_size;
243
244 if (iter->pos < total_size) {
245 ITEM* item;
246 if (iter->pos < front_size) {
247 item = NS(ITEM_VECTORS, write)(&iter->deque->front, front_size - 1 - iter->pos);
248 } else {
249 item = NS(ITEM_VECTORS, write)(&iter->deque->back, iter->pos - front_size);
250 }
251 iter->pos++;
252 return item;
253 }
254 return NULL;
255}
#define ITEM
Definition template.h:36
static DC_PUBLIC VALUE * write(SELF *self, INDEX index)
Definition template.h:209
mutation_version version
Definition template.h:328
SELF * deque
Definition template.h:232
size_t pos
Definition template.h:233

◆ next() [2/2]

DC_PUBLIC ITEM const * next ( ITER_CONST * iter)
static

Definition at line 284 of file template.h.

284 {
285 DC_ASSUME(iter);
287 size_t const front_size = NS(ITEM_VECTORS, size)(&iter->deque->front);
288 size_t const back_size = NS(ITEM_VECTORS, size)(&iter->deque->back);
289 size_t const total_size = front_size + back_size;
290
291 if (iter->pos < total_size) {
292 ITEM const* item;
293 if (iter->pos < front_size) {
294 item = NS(ITEM_VECTORS, read)(&iter->deque->front, front_size - 1 - iter->pos);
295 } else {
296 item = NS(ITEM_VECTORS, read)(&iter->deque->back, iter->pos - front_size);
297 }
298 iter->pos++;
299 return item;
300 }
301 return NULL;
302}
static DC_PUBLIC VALUE const * read(SELF const *self, INDEX index)
Definition template.h:199
size_t pos
Definition template.h:280
SELF const * deque
Definition template.h:279
mutation_version version
Definition template.h:417

◆ pop_back()

DC_PUBLIC ITEM pop_back ( SELF * self)
static

Definition at line 205 of file template.h.

205 {
206 INVARIANT_CHECK(self);
208 if (NS(ITEM_VECTORS, size)(&self->back) > 0) {
209 ITEM result = NS(ITEM_VECTORS, pop)(&self->back);
210 NS(SELF, rebalance)(self);
211 return result;
212 }
213
214 // Back is empty, need to pop from front
215 // Rebalance first to move elements to back, then pop
216 // No need to rebalance again after pop since we just rebalanced
217 if (NS(ITEM_VECTORS, size)(&self->front) > 0) {
218 NS(SELF, rebalance)(self);
219 return NS(ITEM_VECTORS, pop)(&self->back);
220 }
221
222 // Both sides empty - should not happen if deque is non-empty
223 DC_UNREACHABLE("Cannot pop from empty deque");
224}
static DC_PUBLIC void rebalance(SELF *self)
Definition template.h:108
static DC_PUBLIC ITEM pop(SELF *self)
Definition template.h:289
static DC_PUBLIC void mutation_tracker_mutate(mutation_tracker *self)
#define DC_UNREACHABLE(...)
Definition panic.h:44

◆ pop_front()

DC_PUBLIC ITEM pop_front ( SELF * self)
static

Definition at line 184 of file template.h.

184 {
185 INVARIANT_CHECK(self);
187 if (NS(ITEM_VECTORS, size)(&self->front) > 0) {
188 ITEM result = NS(ITEM_VECTORS, pop)(&self->front);
189 NS(SELF, rebalance)(self);
190 return result;
191 }
192
193 // Front is empty, need to pop from back
194 // Rebalance first to move elements to front, then pop
195 // No need to rebalance again after pop since we just rebalanced
196 if (NS(ITEM_VECTORS, size)(&self->back) > 0) {
197 NS(SELF, rebalance)(self);
198 return NS(ITEM_VECTORS, pop)(&self->front);
199 }
200
201 // Both sides empty - should not happen if deque is non-empty
202 DC_UNREACHABLE("Cannot pop from empty deque");
203}

◆ push_back()

DC_PUBLIC void push_back ( SELF * self,
ITEM item )
static

Definition at line 177 of file template.h.

177 {
178 INVARIANT_CHECK(self);
180 NS(ITEM_VECTORS, push)(&self->back, item);
181 NS(SELF, rebalance)(self);
182}
static DC_PUBLIC ITEM * push(SELF *self, ITEM item)
Definition template.h:263

◆ push_front()

DC_PUBLIC void push_front ( SELF * self,
ITEM item )
static

Definition at line 170 of file template.h.

170 {
171 INVARIANT_CHECK(self);
173 NS(ITEM_VECTORS, push)(&self->front, item);
174 NS(SELF, rebalance)(self);
175}

◆ rebalance()

DC_PUBLIC void rebalance ( SELF * self)
static

Definition at line 108 of file template.h.

108 {
109 INVARIANT_CHECK(self);
111
112 size_t const front_size = NS(ITEM_VECTORS, size)(&self->front);
113 size_t const back_size = NS(ITEM_VECTORS, size)(&self->back);
114 size_t const total_size = front_size + back_size;
115
116 // Let the rebalance policy decide if we should rebalance
117 if (!_dc_deque_rebalance_policy(total_size, front_size, back_size)) {
118 return;
119 }
120
121 ITEM_VECTORS* source;
122 ITEM_VECTORS* target;
123 size_t source_size;
124 size_t target_size;
125
126 if (front_size > back_size) {
127 source = &self->front;
128 target = &self->back;
129 source_size = front_size;
130 target_size = back_size;
131 } else {
132 source = &self->back;
133 target = &self->front;
134 source_size = back_size;
135 target_size = front_size;
136 }
137
138 size_t to_move = (source_size - target_size) / 2;
139 // If target is empty, we must move at least 1 element (or all if only 1 exists)
140 if (target_size == 0 && source_size > 0) {
141 to_move = (source_size + 1) / 2; // Move at least half, or 1 if only 1 element
142 }
143 NS(ITEM_VECTORS, transfer_reverse)(source, target, to_move);
144}
static DC_PUBLIC void transfer_reverse(SELF *source, SELF *target, size_t to_move)
Definition template.h:348
static bool _dc_deque_rebalance_policy(size_t total_size, size_t front_size, size_t back_size)
Definition utils.h:6

◆ size()

DC_PUBLIC size_t size ( SELF const * self)
static

Definition at line 98 of file template.h.

98 {
99 INVARIANT_CHECK(self);
100 return NS(ITEM_VECTORS, size)(&self->front) + NS(ITEM_VECTORS, size)(&self->back);
101}

◆ try_read_from_back()

DC_PUBLIC ITEM const * try_read_from_back ( SELF const * self,
size_t index )
static

Definition at line 158 of file template.h.

158 {
159 return NS(SELF, try_read_from_front)(self, NS(SELF, size)(self) - 1 - index);
160}
static DC_PUBLIC ITEM const * try_read_from_front(SELF const *self, size_t index)
Definition template.h:262

◆ try_read_from_front()

DC_PUBLIC ITEM const * try_read_from_front ( SELF const * self,
size_t index )
static

Definition at line 146 of file template.h.

146 {
147 INVARIANT_CHECK(self);
148
149 if (index < NS(ITEM_VECTORS, size)(&self->front)) {
150 size_t front_index = NS(ITEM_VECTORS, size)(&self->front) - 1 - index;
151 return NS(ITEM_VECTORS, read)(&self->front, front_index);
152 }
153
154 size_t back_index = index - NS(ITEM_VECTORS, size)(&self->front);
155 return NS(ITEM_VECTORS, try_read)(&self->back, back_index);
156}
static DC_PUBLIC VALUE const * try_read(SELF const *self, INDEX index)
Definition template.h:180

◆ try_write_from_back()

DC_PUBLIC ITEM * try_write_from_back ( SELF * self,
size_t index )
static

Definition at line 166 of file template.h.

166 {
167 return (ITEM*)NS(SELF, try_read_from_back)(self, index);
168}
static DC_PUBLIC ITEM const * try_read_from_back(SELF const *self, size_t index)
Definition template.h:272

◆ try_write_from_front()

DC_PUBLIC ITEM * try_write_from_front ( SELF * self,
size_t index )
static

Definition at line 162 of file template.h.

162 {
163 return (ITEM*)NS(SELF, try_read_from_front)(self, index);
164}