33 #define IMPLEMENT_DEQUE_STRUCT(struct_name, type) \ 34 typedef struct struct_name { \ 40 void (*destructor)(type); \ 60 #define PROTOTYPE_DEQUE(struct_name, type) \ 61 struct_name new_##struct_name(size_t); \ 62 struct_name new_destructable_##struct_name(size_t, void (*)(type)); \ 63 void destroy_##struct_name(struct_name*); \ 64 void empty_##struct_name(struct_name*); \ 65 bool is_empty_##struct_name(struct_name*); \ 66 size_t length_##struct_name(struct_name*); \ 67 type* as_array_##struct_name(struct_name*, size_t*); \ 68 void apply_##struct_name(struct_name*, void (*)(type)); \ 69 void push_front_##struct_name(struct_name*, type); \ 70 void push_back_##struct_name(struct_name*, type); \ 71 type pop_front_##struct_name(struct_name*); \ 72 type pop_back_##struct_name(struct_name*); \ 73 type peek_front_##struct_name(struct_name*); \ 74 type peek_back_##struct_name(struct_name*); \ 75 void update_front_##struct_name(struct_name*, type); \ 76 void update_back_##struct_name(struct_name*, type); \ 77 void update_and_destroy_front_##struct_name(struct_name*, type); \ 78 void update_and_destroy_back_##struct_name(struct_name*, type); 93 #define IMPLEMENT_DEQUE(struct_name, type) \ 95 void apply_##struct_name(struct_name*, void (*)(type)); \ 97 struct_name new_##struct_name(size_t init_cap) { \ 101 ret.cap = init_cap; \ 105 ret.data = (type*) malloc(ret.cap * sizeof(type)); \ 107 if (ret.data == NULL) { \ 108 fprintf(stderr, "ERROR: Failed to allocate struct_name" \ 113 ret.front = ret.back = 0; \ 114 ret.destructor = NULL; \ 119 struct_name new_destructable_##struct_name(size_t init_cap, \ 120 void (*destructor)(type)){ \ 121 struct_name ret = new_##struct_name(init_cap); \ 122 ret.destructor = destructor; \ 126 void destroy_##struct_name(struct_name* deq) { \ 127 assert(deq != NULL); \ 129 if (deq->data == NULL) \ 132 if (deq->destructor != NULL) \ 133 apply_##struct_name(deq, deq->destructor); \ 135 if (deq->data != NULL) \ 139 deq->cap = deq->front = deq->back = 0; \ 142 void empty_##struct_name(struct_name* deq) { \ 143 assert(deq != NULL); \ 144 assert(deq->data != NULL); \ 146 if (deq->destructor != NULL) \ 147 apply_##struct_name(deq, deq->destructor); \ 149 deq->front = deq->back = 0; \ 152 bool is_empty_##struct_name(struct_name* deq) { \ 153 assert(deq != NULL); \ 154 assert(deq->data != NULL); \ 155 return deq->front == deq->back; \ 158 size_t length_##struct_name(struct_name* deq) { \ 159 assert(deq != NULL); \ 160 assert(deq->data != NULL); \ 161 return (deq->back - deq->front + deq->cap) % deq->cap; \ 164 static void __reallign_##struct_name(struct_name* deq) { \ 165 assert(deq != NULL); \ 166 assert(deq->data != NULL); \ 168 if (deq->front != 0) { \ 169 type* old_data = deq->data; \ 170 size_t len = length_##struct_name(deq); \ 172 deq->data = (type*) malloc(deq->cap * sizeof(type)); \ 174 if (deq->data == NULL) { \ 175 fprintf(stderr, "ERROR: Failed to reallocate struct_name" \ 182 for (i = 0; i < len; ++i) \ 183 deq->data[i] = old_data[(deq->front + i) % deq->cap]; \ 192 type* as_array_##struct_name(struct_name* deq, size_t* len) { \ 193 assert(deq != NULL); \ 194 assert(deq->data != NULL); \ 196 __reallign_##struct_name(deq); \ 198 type* ret = deq->data; \ 201 *len = length_##struct_name(deq); \ 204 deq->cap = deq->front = deq->back = 0; \ 209 void apply_##struct_name(struct_name* deq, void (*func)(type)) { \ 210 assert(deq != NULL); \ 211 assert(deq->data != NULL); \ 213 size_t len = length_##struct_name(deq); \ 215 for (size_t i = 0; i < len; ++i) { \ 216 func(deq->data[(deq->front + i) % deq->cap]); \ 220 static void __on_push_##struct_name(struct_name* deq) { \ 221 if (deq->front == (deq->back + 1) % deq->cap) { \ 222 type* old_data = deq->data; \ 223 size_t old_cap = deq->cap; \ 225 deq->cap = 2 * deq->cap; \ 226 deq->data = (type*) malloc(deq->cap * sizeof(type)); \ 228 if (deq->data == NULL) { \ 229 fprintf(stderr, "ERROR: Failed to reallocate struct_name" \ 236 for (i = 0; i < old_cap - 1; ++i) \ 237 deq->data[i] = old_data[(deq->front + i) % old_cap]; \ 246 static void __on_pop_##struct_name(struct_name* deq) { \ 247 if (is_empty_##struct_name(deq)) { \ 248 fprintf(stderr, "ERROR: Cannot pop from of struct_name while it " \ 254 void push_front_##struct_name(struct_name* deq, type element) { \ 255 assert(deq != NULL); \ 256 assert(deq->data != NULL); \ 257 __on_push_##struct_name(deq); \ 258 deq->front = (deq->front + deq->cap - 1) % deq->cap; \ 259 deq->data[deq->front] = element; \ 262 void push_back_##struct_name(struct_name* deq, type element) { \ 263 assert(deq != NULL); \ 264 assert(deq->data != NULL); \ 265 __on_push_##struct_name(deq); \ 266 deq->data[deq->back] = element; \ 267 deq->back = (deq->back + 1) % deq->cap; \ 270 type pop_front_##struct_name(struct_name* deq) { \ 271 assert(deq != NULL); \ 272 assert(deq->data != NULL); \ 273 __on_pop_##struct_name(deq); \ 274 size_t old_front = deq->front; \ 275 deq->front = (deq->front + 1) % deq->cap; \ 276 return deq->data[old_front]; \ 279 type pop_back_##struct_name(struct_name* deq) { \ 280 assert(deq != NULL); \ 281 assert(deq->data != NULL); \ 282 __on_pop_##struct_name(deq); \ 283 deq->back = (deq->back + deq->cap - 1) % deq->cap; \ 284 return deq->data[deq->back]; \ 287 type peek_front_##struct_name(struct_name* deq) { \ 288 assert(deq != NULL); \ 289 assert(deq->data != NULL); \ 290 assert(!is_empty_##struct_name(deq)); \ 291 return deq->data[deq->front]; \ 294 type peek_back_##struct_name(struct_name* deq) { \ 295 assert(deq != NULL); \ 296 assert(deq->data != NULL); \ 297 assert(!is_empty_##struct_name(deq)); \ 298 return deq->data[(deq->back + deq->cap - 1) % deq->cap]; \ 301 void update_front_##struct_name(struct_name* deq, type element) { \ 302 assert(deq != NULL); \ 303 assert(deq->data != NULL); \ 304 assert(!is_empty_##struct_name(deq)); \ 305 deq->data[deq->front] = element; \ 308 void update_back_##struct_name(struct_name* deq, type element) { \ 309 assert(deq != NULL); \ 310 assert(deq->data != NULL); \ 311 assert(!is_empty_##struct_name(deq)); \ 312 deq->data[(deq->back + deq->cap - 1) % deq->cap] = element; \ 315 void update_and_destroy_front_##struct_name(struct_name* deq, \ 317 assert(deq != NULL); \ 318 assert(deq->data != NULL); \ 319 assert(!is_empty_##struct_name(deq)); \ 321 size_t idx = deq->front; \ 323 if (deq->destructor != NULL) \ 324 deq->destructor(deq->data[idx]); \ 326 deq->data[idx] = element; \ 329 void update_and_destroy_back_##struct_name(struct_name* deq, \ 331 assert(deq != NULL); \ 332 assert(deq->data != NULL); \ 333 assert(!is_empty_##struct_name(deq)); \ 335 size_t idx = (deq->back + deq->cap - 1) % deq->cap; \ 337 if (deq->destructor != NULL) \ 338 deq->destructor(deq->data[idx]); \ 340 deq->data[idx] = element; \ char Type
An example type used for example purposes only.
Definition: deque.h:346
size_t front
Definition: deque.h:365
size_t back
Definition: deque.h:366
A data structure generated by IMPLEMENT_DEQUE_STRUCT() to store the state of a deque.
Definition: deque.h:362
size_t cap
Definition: deque.h:364
Type * data
Definition: deque.h:363
struct Example Example
This way you do not have to type "struct Example" each time you wish to refer to an Example structure...
void(* destructor)(Type)
Definition: deque.h:368
#define PROTOTYPE_DEQUE(struct_name, type)
Generates prototypes for functions that manipulate Double Ended Queue structures. ...
Definition: deque.h:60