Derive-C
Loading...
Searching...
No Matches
template.h File Reference
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <derive-c/core/helpers.h>
#include <derive-c/core/panic.h>
#include <derive-c/core/alloc/def.h>
#include <derive-c/core/self/def.h>
#include <derive-c/core/alloc/undef.h>
#include <derive-c/core/self/undef.h>
Include dependency graph for template.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

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...

Macros

#define ITEM   item_t
#define ITEM_DELETE   item_delete
#define ITEM_CLONE   item_clone

Functions

static void item_delete (item_t *UNUSED(t))
static item_t item_clone (item_t const *i)
static SELF new (ALLOC *alloc)
static SELF new_with_capacity (size_t capacity, ALLOC *alloc)
static SELF new_with_defaults (size_t size, ITEM default_item, ALLOC *alloc)
static void reserve (SELF *self, size_t new_capacity)
static SELF clone (SELF const *self)
static ITEM const * try_read (SELF const *self, size_t index)
static ITEM const * read (SELF const *self, size_t index)
static ITEMtry_write (SELF *self, size_t index)
static ITEMwrite (SELF *self, size_t index)
static void insert_at (SELF *self, size_t at, ITEM const *items, size_t count)
static void remove_at (SELF *self, size_t at, size_t count)
static ITEMpush (SELF *self, ITEM item)
static bool try_pop (SELF *self, ITEM *destination)
static ITEMdata (SELF *self)
static ITEM pop (SELF *self)
static ITEM pop_front (SELF *self)
static size_t size (SELF const *self)
static void delete (SELF *self)
static ITEMnext (ITER *iter)
static size_t position (ITER const *iter)
static bool empty (ITER const *iter)
static ITER get_iter (SELF *self)
static ITEM const * next (ITER_CONST *iter)
static size_t position (ITER_CONST const *iter)
static bool empty (ITER_CONST const *iter)
static ITER_CONST get_iter_const (SELF const *self)

Macro Definition Documentation

◆ ITEM

#define ITEM   item_t

Definition at line 22 of file template.h.

◆ ITEM_CLONE

#define ITEM_CLONE   item_clone

Definition at line 26 of file template.h.

◆ ITEM_DELETE

#define ITEM_DELETE   item_delete

Definition at line 24 of file template.h.

Function Documentation

◆ clone()

SELF clone ( SELF const * self)
static

Definition at line 99 of file template.h.

99 {
100 DEBUG_ASSERT(self);
101 ITEM* data = (ITEM*)NS(ALLOC, malloc)(self->alloc, self->capacity * sizeof(ITEM));
102 ASSERT(data);
103 for (size_t index = 0; index < self->size; index++) {
104 data[index] = ITEM_CLONE(&self->data[index]);
105 }
106 return (SELF){
107 .size = self->size,
108 .capacity = self->capacity,
109 .data = data,
110 .alloc = self->alloc,
111 };
112}
static void * malloc(SELF *self, size_t size)
Definition template.h:23
#define ALLOC
Definition template.h:56
#define ITEM
Definition template.h:55
#define NS(pre, post)
Definition helpers.h:6
#define ASSERT(expr,...)
Definition panic.h:15
#define DEBUG_ASSERT(expr)
Definition panic.h:34
#define SELF
Definition def.h:51
#define ITEM_CLONE
Definition template.h:26
static ITEM * data(SELF *self)
Definition template.h:215
Here is the call graph for this function:

◆ data()

ITEM * data ( SELF * self)
static
Examples
complex/employees.c.

Definition at line 215 of file template.h.

215 {
216 DEBUG_ASSERT(self);
217 return self->data;
218}
ITEM * data
Definition template.h:38
Here is the call graph for this function:
Here is the caller graph for this function:

◆ delete()

void delete ( SELF * self)
static

Definition at line 240 of file template.h.

240 {
241 DEBUG_ASSERT(self);
242 if (self->data) {
243 for (size_t i = 0; i < self->size; i++) {
244 ITEM_DELETE(&self->data[i]);
245 }
246 NS(ALLOC, free)(self->alloc, self->data);
247 }
248}
static void free(SELF *self, void *ptr)
Definition template.h:56
INPLACE_TYPE size
Definition template.h:52
ALLOC * alloc
Definition template.h:63
#define ITEM_DELETE
Definition template.h:24
Here is the call graph for this function:

◆ empty() [1/2]

bool empty ( ITER const * iter)
static

Definition at line 272 of file template.h.

272 {
273 DEBUG_ASSERT(iter);
274 return iter->pos >= iter->vec->size;
275}
Here is the call graph for this function:

◆ empty() [2/2]

bool empty ( ITER_CONST const * iter)
static

Definition at line 308 of file template.h.

308 {
309 DEBUG_ASSERT(iter);
310 return iter->pos >= iter->vec->size;
311}
Here is the call graph for this function:

◆ get_iter()

ITER get_iter ( SELF * self)
static

Definition at line 277 of file template.h.

277 {
278 DEBUG_ASSERT(self);
279 return (ITER){
280 .vec = self,
281 .pos = 0,
282 };
283}
Here is the call graph for this function:

◆ get_iter_const()

ITER_CONST get_iter_const ( SELF const * self)
static

Definition at line 313 of file template.h.

313 {
314 DEBUG_ASSERT(self);
315 return (ITER_CONST){
316 .vec = self,
317 .pos = 0,
318 };
319}
Here is the call graph for this function:

◆ insert_at()

void insert_at ( SELF * self,
size_t at,
ITEM const * items,
size_t count )
static

Definition at line 142 of file template.h.

142 {
143 DEBUG_ASSERT(self);
144 DEBUG_ASSERT(items);
145 ASSERT(at <= self->size);
146
147 if (count == 0) {
148 return;
149 }
150
151 NS(SELF, reserve)(self, self->size + count);
152
153 memmove(&self->data[at + count], &self->data[at], (self->size - at) * sizeof(ITEM));
154 memcpy(&self->data[at], items, count * sizeof(ITEM));
155 self->size += count;
156}
static INDEX_TYPE size(SELF const *self)
Definition template.h:220
static void reserve(SELF *self, size_t new_capacity_for)
Definition template.h:97
Here is the call graph for this function:
Here is the caller graph for this function:

◆ item_clone()

item_t item_clone ( item_t const * i)
static

Definition at line 25 of file template.h.

25{ return *i; }

◆ item_delete()

void item_delete ( item_t * UNUSEDt)
static

Definition at line 23 of file template.h.

23{}

◆ new()

SELF new ( ALLOC * alloc)
static

Definition at line 45 of file template.h.

45 {
46 SELF temp = (SELF){
47 .size = 0,
48 .capacity = 0,
49 .data = NULL,
50 .alloc = alloc,
51 };
52 return temp;
53}

◆ new_with_capacity()

SELF new_with_capacity ( size_t capacity,
ALLOC * alloc )
static

Definition at line 55 of file template.h.

55 {
56 if (capacity == 0) {
57 return NS(SELF, new)(alloc);
58 }
59
60 ITEM* data = (ITEM*)NS(ALLOC, malloc)(alloc, capacity * sizeof(ITEM));
62 return (SELF){
63 .size = 0,
64 .capacity = capacity,
65 .data = data,
66 .alloc = alloc,
67 };
68}
#define LIKELY(x)
Definition helpers.h:18
Here is the call graph for this function:

◆ new_with_defaults()

SELF new_with_defaults ( size_t size,
ITEM default_item,
ALLOC * alloc )
static

Definition at line 70 of file template.h.

70 {
71 ITEM* data = (ITEM*)NS(ALLOC, malloc)(alloc, size * sizeof(ITEM));
72 if (size > 0) {
73 // JUSTIFY: We only need to copy size-1 entries - can move the first as default.
74 data[0] = default_item;
75 for (size_t i = 1; i < size; i++) {
76 data[i] = ITEM_CLONE(&default_item);
77 }
78 }
80 return (SELF){
81 .size = size,
82 .capacity = size,
83 .data = data,
84 .alloc = alloc,
85 };
86}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ next() [1/2]

ITEM * next ( ITER * iter)
static

Definition at line 257 of file template.h.

257 {
258 DEBUG_ASSERT(iter);
259 if (iter->pos < iter->vec->size) {
260 ITEM* item = &iter->vec->data[iter->pos];
261 iter->pos++;
262 return item;
263 }
264 return NULL;
265}
Here is the call graph for this function:

◆ next() [2/2]

ITEM const * next ( ITER_CONST * iter)
static

Definition at line 293 of file template.h.

293 {
294 DEBUG_ASSERT(iter);
295 if (iter->pos < iter->vec->size) {
296 ITEM const* item = &iter->vec->data[iter->pos];
297 iter->pos++;
298 return item;
299 }
300 return NULL;
301}
Here is the call graph for this function:

◆ pop()

ITEM pop ( SELF * self)
static

Definition at line 220 of file template.h.

220 {
221 ITEM entry;
222 ASSERT(NS(SELF, try_pop)(self, &entry));
223 return entry;
224}
static bool try_pop(SELF *self, ITEM *destination)
Definition template.h:146
Here is the call graph for this function:

◆ pop_front()

ITEM pop_front ( SELF * self)
static

Definition at line 226 of file template.h.

226 {
227 DEBUG_ASSERT(self);
228 ASSERT(self->size > 0);
229 ITEM entry = self->data[0];
230 memmove(&self->data[0], &self->data[1], (self->size - 1) * sizeof(ITEM));
231 self->size--;
232 return entry;
233}
Here is the call graph for this function:

◆ position() [1/2]

size_t position ( ITER const * iter)
static

Definition at line 267 of file template.h.

267 {
268 DEBUG_ASSERT(iter);
269 return iter->pos;
270}
Here is the call graph for this function:

◆ position() [2/2]

size_t position ( ITER_CONST const * iter)
static

Definition at line 303 of file template.h.

303 {
304 DEBUG_ASSERT(iter);
305 return iter->pos;
306}
Here is the call graph for this function:

◆ push()

ITEM * push ( SELF * self,
ITEM item )
static

Definition at line 174 of file template.h.

174 {
175 DEBUG_ASSERT(self);
176 if (self->size == self->capacity) {
177 ITEM* new_data;
178 size_t new_capacity;
179 if (self->data == NULL) {
180 DEBUG_ASSERT(self->capacity == 0);
181 // JUSTIFY: Allocating capacity of 4
182 // - Avoid repeat reallocations on growing a vector from
183 // size sero (from new)
184 // Otherwise an arbitrary choice (given we do not know the size of T)
185 new_capacity = 8;
186 new_data = (ITEM*)NS(ALLOC, malloc)(self->alloc, new_capacity * sizeof(ITEM));
187 } else {
188 // JUSTIFY: Growth factor of 2
189 // - Simple arithmetic (for debugging)
190 // - Same as used by GCC's std::vector implementation
191 new_capacity = self->capacity * 2;
192 new_data =
193 (ITEM*)NS(ALLOC, realloc)(self->alloc, self->data, new_capacity * sizeof(ITEM));
194 }
195 ASSERT(new_data);
196 self->capacity = new_capacity;
197 self->data = new_data;
198 }
199 ITEM* entry = &self->data[self->size];
200 *entry = item;
201 self->size++;
202 return entry;
203}
static void * realloc(SELF *self, void *ptr, size_t size)
Definition template.h:45
size_t capacity
Definition template.h:97
Here is the call graph for this function:

◆ read()

ITEM const * read ( SELF const * self,
size_t index )
static

Definition at line 122 of file template.h.

122 {
123 ITEM const* item = NS(SELF, try_read)(self, index);
124 ASSERT(item);
125 return item;
126}
static VALUE const * try_read(SELF const *self, INDEX index)
Definition template.h:177
Here is the call graph for this function:

◆ remove_at()

void remove_at ( SELF * self,
size_t at,
size_t count )
static

Definition at line 158 of file template.h.

158 {
159 DEBUG_ASSERT(self);
160 ASSERT(at + count <= self->size);
161
162 if (count == 0) {
163 return;
164 }
165
166 for (size_t i = at; i < at + count; i++) {
167 ITEM_DELETE(&self->data[i]);
168 }
169
170 memmove(&self->data[at], &self->data[at + count], (self->size - (at + count)) * sizeof(ITEM));
171 self->size -= count;
172}
Here is the call graph for this function:

◆ reserve()

void reserve ( SELF * self,
size_t new_capacity )
static

Definition at line 88 of file template.h.

88 {
89 DEBUG_ASSERT(self);
90 if (new_capacity > self->capacity) {
91 ITEM* new_data =
92 (ITEM*)NS(ALLOC, realloc)(self->alloc, self->data, new_capacity * sizeof(ITEM));
93 ASSERT(new_data);
94 self->data = new_data;
95 self->capacity = new_capacity;
96 }
97}
Here is the call graph for this function:

◆ size()

size_t size ( SELF const * self)
static

Definition at line 235 of file template.h.

235 {
236 DEBUG_ASSERT(self);
237 return self->size;
238}
Here is the call graph for this function:

◆ try_pop()

bool try_pop ( SELF * self,
ITEM * destination )
static

Definition at line 205 of file template.h.

205 {
206 DEBUG_ASSERT(self);
207 if (LIKELY(self->size > 0)) {
208 self->size--;
209 *destination = self->data[self->size];
210 return true;
211 }
212 return false;
213}
Here is the call graph for this function:

◆ try_read()

ITEM const * try_read ( SELF const * self,
size_t index )
static

Definition at line 114 of file template.h.

114 {
115 DEBUG_ASSERT(self);
116 if (LIKELY(index < self->size)) {
117 return &self->data[index];
118 }
119 return NULL;
120}
Here is the call graph for this function:

◆ try_write()

ITEM * try_write ( SELF * self,
size_t index )
static

Definition at line 128 of file template.h.

128 {
129 DEBUG_ASSERT(self);
130 if (LIKELY(index < self->size)) {
131 return &self->data[index];
132 }
133 return NULL;
134}
Here is the call graph for this function:

◆ write()

ITEM * write ( SELF * self,
size_t index )
static

Definition at line 136 of file template.h.

136 {
137 ITEM* item = NS(SELF, try_write)(self, index);
138 ASSERT(item);
139 return item;
140}
static VALUE * try_write(SELF *self, INDEX index)
Definition template.h:159
Here is the call graph for this function: