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.h>
#include <derive-c/panic.h>
#include <derive-c/self.h>
#include <derive-c/allocs/std.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  SELF

Macros

#define ALLOC   stdalloc
 A simple vector.
#define T   derive_c_parameter_t
#define T_DELETE   derive_c_parameter_t_delete

Functions

static SELF new (ALLOC *alloc)
static SELF new_with_capacity (size_t capacity, ALLOC *alloc)
static SELF new_with_defaults (size_t size, T default_value, ALLOC *alloc)
static SELF shallow_clone (SELF const *self)
static T const * try_read (SELF const *self, size_t index)
static T const * read (SELF const *self, size_t index)
static Ttry_write (SELF *self, size_t index)
static Twrite (SELF *self, size_t index)
static Tpush (SELF *self, T value)
static bool try_pop (SELF *self, T *destination)
static T pop (SELF *self)
static size_t size (SELF const *self)
static void delete (SELF *self)
static Tnext (ITER *iter)
static size_t position (ITER const *iter)
static bool empty (ITER const *iter)
static ITER get_iter (SELF *self)
static T 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

◆ ALLOC

#define ALLOC   stdalloc

A simple vector.

Definition at line 15 of file template.h.

◆ T

#define T   derive_c_parameter_t

Definition at line 25 of file template.h.

◆ T_DELETE

#define T_DELETE   derive_c_parameter_t_delete

Definition at line 27 of file template.h.

Function Documentation

◆ delete()

void delete ( SELF * self)
static

Definition at line 170 of file template.h.

170 {
171 DEBUG_ASSERT(self);
172 if (self->data) {
173 for (size_t i = 0; i < self->size; i++) {
174 T_DELETE(&self->data[i]);
175 }
176 NAME(ALLOC, free)(self->alloc, self->data);
177 }
178}
#define ALLOC
An allocator that prints to stdout when it allocates or frees memory.
Definition template.h:17
static void free(SELF *self, void *ptr)
Definition template.h:62
#define NAME(pre, post)
Definition core.h:5
#define DEBUG_ASSERT(expr)
Definition panic.h:23
T data[INPLACE_CAPACITY]
Definition template.h:45
INPLACE_TYPE size
Definition template.h:44
ALLOC * alloc
Definition template.h:76
#define T_DELETE
Definition template.h:20
Here is the call graph for this function:

◆ empty() [1/2]

bool empty ( ITER const * iter)
static

Definition at line 202 of file template.h.

202 {
203 DEBUG_ASSERT(iter);
204 return iter->pos >= iter->vec->size;
205}
Here is the call graph for this function:

◆ empty() [2/2]

bool empty ( ITER_CONST const * iter)
static

Definition at line 238 of file template.h.

238 {
239 DEBUG_ASSERT(iter);
240 return iter->pos >= iter->vec->size;
241}
Here is the call graph for this function:

◆ get_iter()

ITER get_iter ( SELF * self)
static

Definition at line 207 of file template.h.

207 {
208 DEBUG_ASSERT(self);
209 return (ITER){
210 .vec = self,
211 .pos = 0,
212 };
213}
Here is the call graph for this function:

◆ get_iter_const()

ITER_CONST get_iter_const ( SELF const * self)
static

Definition at line 243 of file template.h.

243 {
244 DEBUG_ASSERT(self);
245 return (ITER_CONST){
246 .vec = self,
247 .pos = 0,
248 };
249}
Here is the call graph for this function:

◆ new()

SELF new ( ALLOC * alloc)
static

Definition at line 42 of file template.h.

42 {
43 SELF temp = (SELF){
44 .size = 0,
45 .capacity = 0,
46 .data = NULL,
47 .alloc = alloc,
48 };
49 return temp;
50}
#define SELF
Definition template.h:70

◆ new_with_capacity()

SELF new_with_capacity ( size_t capacity,
ALLOC * alloc )
static

Definition at line 52 of file template.h.

52 {
53 DEBUG_ASSERT(capacity > 0);
54 T* data = (T*)NAME(ALLOC, malloc)(alloc, capacity * sizeof(T));
55 ASSERT(LIKELY(data));
56 return (SELF){
57 .size = 0,
58 .capacity = capacity,
59 .data = data,
60 .alloc = alloc,
61 };
62}
static void * malloc(SELF *self, size_t size)
Definition template.h:29
#define T
Definition template.h:68
#define LIKELY(x)
Definition core.h:15
#define ASSERT(expr,...)
Definition panic.h:16
Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_with_defaults()

SELF new_with_defaults ( size_t size,
T default_value,
ALLOC * alloc )
static

Definition at line 64 of file template.h.

64 {
65 T* data = (T*)NAME(ALLOC, malloc)(alloc, size * sizeof(T));
66 for (size_t i = 0; i < size; i++) {
67 data[i] = default_value;
68 }
69 ASSERT(LIKELY(data));
70 return (SELF){
71 .size = size,
72 .capacity = size,
73 .data = data,
74 .alloc = alloc,
75 };
76}
static INDEX_TYPE size(SELF const *self)
Definition template.h:207
Here is the call graph for this function:
Here is the caller graph for this function:

◆ next() [1/2]

T * next ( ITER * iter)
static

Definition at line 187 of file template.h.

187 {
188 DEBUG_ASSERT(iter);
189 if (iter->pos < iter->vec->size) {
190 T* item = &iter->vec->data[iter->pos];
191 iter->pos++;
192 return item;
193 }
194 return NULL;
195}
Here is the call graph for this function:

◆ next() [2/2]

T const * next ( ITER_CONST * iter)
static

Definition at line 223 of file template.h.

223 {
224 DEBUG_ASSERT(iter);
225 if (iter->pos < iter->vec->size) {
226 T const* item = &iter->vec->data[iter->pos];
227 iter->pos++;
228 return item;
229 }
230 return NULL;
231}
Here is the call graph for this function:

◆ pop()

T pop ( SELF * self)
static

Definition at line 159 of file template.h.

159 {
160 T entry;
161 ASSERT(NAME(SELF, try_pop)(self, &entry));
162 return entry;
163}
static bool try_pop(SELF *self, T *destination)
Definition template.h:108
Here is the call graph for this function:

◆ position() [1/2]

size_t position ( ITER const * iter)
static

Definition at line 197 of file template.h.

197 {
198 DEBUG_ASSERT(iter);
199 return iter->pos;
200}
Here is the call graph for this function:

◆ position() [2/2]

size_t position ( ITER_CONST const * iter)
static

Definition at line 233 of file template.h.

233 {
234 DEBUG_ASSERT(iter);
235 return iter->pos;
236}
Here is the call graph for this function:

◆ push()

T * push ( SELF * self,
T value )
static

Definition at line 119 of file template.h.

119 {
120 DEBUG_ASSERT(self);
121 if (self->size == self->capacity) {
122 T* new_data;
123 size_t new_capacity;
124 if (self->data == NULL) {
125 DEBUG_ASSERT(self->capacity == 0);
126 // JUSTIFY: Allocating capacity of 4
127 // - Avoid repeat reallocations on growing a vector from
128 // size sero (from new)
129 // Otherwise an arbitrary choice (given we do not know the size of T)
130 new_capacity = 8;
131 new_data = (T*)NAME(ALLOC, malloc)(self->alloc, new_capacity * sizeof(T));
132 } else {
133 // JUSTIFY: Growth factor of 2
134 // - Simple arithmetic (for debugging)
135 // - Same as used by GCC's std::vector implementation
136 new_capacity = self->capacity * 2;
137 new_data = (T*)NAME(ALLOC, realloc)(self->alloc, self->data, new_capacity * sizeof(T));
138 }
139 ASSERT(new_data);
140 self->capacity = new_capacity;
141 self->data = new_data;
142 }
143 T* entry = &self->data[self->size];
144 *entry = value;
145 self->size++;
146 return entry;
147}
static void * realloc(SELF *self, void *ptr, size_t size)
Definition template.h:51
size_t capacity
Definition template.h:94
Here is the call graph for this function:

◆ read()

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

Definition at line 99 of file template.h.

99 {
100 T const* value = NAME(SELF, try_read)(self, index);
101 ASSERT(value);
102 return value;
103}
static V const * try_read(SELF const *self, INDEX index)
Definition template.h:174
Here is the call graph for this function:

◆ shallow_clone()

SELF shallow_clone ( SELF const * self)
static

Definition at line 78 of file template.h.

78 {
79 DEBUG_ASSERT(self);
80 T* data = (T*)NAME(ALLOC, malloc)(self->alloc, self->capacity * sizeof(T));
81 ASSERT(data);
82 memcpy(data, self->data, self->size * sizeof(T));
83 return (SELF){
84 .size = self->size,
85 .capacity = self->capacity,
86 .data = data,
87 .alloc = self->alloc,
88 };
89}
Here is the call graph for this function:

◆ size()

size_t size ( SELF const * self)
static

Definition at line 165 of file template.h.

165 {
166 DEBUG_ASSERT(self);
167 return self->size;
168}
Here is the call graph for this function:

◆ try_pop()

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

Definition at line 149 of file template.h.

149 {
150 DEBUG_ASSERT(self);
151 if (LIKELY(self->size > 0)) {
152 self->size--;
153 *destination = self->data[self->size];
154 return true;
155 }
156 return false;
157}
Here is the call graph for this function:

◆ try_read()

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

Definition at line 91 of file template.h.

91 {
92 DEBUG_ASSERT(self);
93 if (LIKELY(index < self->size)) {
94 return &self->data[index];
95 }
96 return NULL;
97}
Here is the call graph for this function:

◆ try_write()

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

Definition at line 105 of file template.h.

105 {
106 DEBUG_ASSERT(self);
107 if (LIKELY(index < self->size)) {
108 return &self->data[index];
109 }
110 return NULL;
111}
Here is the call graph for this function:

◆ write()

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

Definition at line 113 of file template.h.

113 {
114 T* value = NAME(SELF, try_write)(self, index);
115 ASSERT(value);
116 return value;
117}
static V * try_write(SELF *self, INDEX index)
Definition template.h:156
Here is the call graph for this function: