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); 91 #define IMPLEMENT_DEQUE(struct_name, type) \ 92 struct_name new_##struct_name(size_t); \ 93 struct_name new_destructable_##struct_name(size_t, void (*)(type)); \ 94 void destroy_##struct_name(struct_name*); \ 95 void empty_##struct_name(struct_name*); \ 96 bool is_empty_##struct_name(struct_name*); \ 97 size_t length_##struct_name(struct_name*); \ 98 type* as_array_##struct_name(struct_name*, size_t*); \ 99 void apply_##struct_name(struct_name*, void (*)(type)); \ 100 void push_front_##struct_name(struct_name*, type); \ 101 void push_back_##struct_name(struct_name*, type); \ 102 type pop_front_##struct_name(struct_name*); \ 103 type pop_back_##struct_name(struct_name*); \ 104 type peek_front_##struct_name(struct_name*); \ 105 type peek_back_##struct_name(struct_name*); \ 106 void update_front_##struct_name(struct_name*, type); \ 107 void update_back_##struct_name(struct_name*, type); \ 109 struct_name new_##struct_name(size_t init_cap) { \ 113 ret.cap = init_cap; \ 117 ret.data = (type*) malloc(init_cap * sizeof(type)); \ 119 if (ret.data == NULL) { \ 120 fprintf(stderr, "ERROR: Failed to allocate struct_name" \ 125 ret.front = ret.back = 0; \ 126 ret.destructor = NULL; \ 131 struct_name new_destructable_##struct_name(size_t init_cap, \ 132 void (*destructor)(type)){ \ 133 struct_name ret = new_##struct_name(init_cap); \ 134 ret.destructor = destructor; \ 138 void destroy_##struct_name(struct_name* deq) { \ 139 assert(deq != NULL); \ 141 if (deq->data == NULL) \ 144 if (deq->destructor != NULL) \ 145 apply_##struct_name(deq, deq->destructor); \ 147 if (deq->data != NULL) \ 151 deq->cap = deq->front = deq->back = 0; \ 154 void empty_##struct_name(struct_name* deq) { \ 155 assert(deq != NULL); \ 156 assert(deq->data != NULL); \ 157 deq->front = deq->back = 0; \ 160 bool is_empty_##struct_name(struct_name* deq) { \ 161 assert(deq != NULL); \ 162 assert(deq->data != NULL); \ 163 return deq->front == deq->back; \ 166 size_t length_##struct_name(struct_name* deq) { \ 167 assert(deq != NULL); \ 168 assert(deq->data != NULL); \ 169 return (deq->back - deq->front + deq->cap) % deq->cap; \ 172 static void __reallign_##struct_name(struct_name* deq) { \ 173 assert(deq != NULL); \ 174 assert(deq->data != NULL); \ 176 if (deq->front != 0) { \ 177 type* old_data = deq->data; \ 178 size_t len = length_##struct_name(deq); \ 180 deq->data = (type*) malloc(deq->cap * sizeof(type)); \ 182 if (deq->data == NULL) { \ 183 fprintf(stderr, "ERROR: Failed to reallocate struct_name" \ 190 for (i = 0; i < len; ++i) \ 191 deq->data[i] = old_data[(deq->front + i) % deq->cap]; \ 200 type* as_array_##struct_name(struct_name* deq, size_t* len) { \ 201 assert(deq != NULL); \ 202 assert(deq->data != NULL); \ 204 __reallign_##struct_name(deq); \ 206 type* ret = deq->data; \ 209 *len = length_##struct_name(deq); \ 212 deq->cap = deq->front = deq->back = 0; \ 217 void apply_##struct_name(struct_name* deq, void (*func)(type)) { \ 218 assert(deq != NULL); \ 219 assert(deq->data != NULL); \ 221 size_t len = length_##struct_name(deq); \ 223 for (size_t i = 0; i < len; ++i) { \ 224 func(deq->data[(deq->front + i) % deq->cap]); \ 228 static void __on_push_##struct_name(struct_name* deq) { \ 229 if (deq->front == (deq->back + 1) % deq->cap) { \ 230 type* old_data = deq->data; \ 231 size_t old_cap = deq->cap; \ 233 deq->cap = 2 * deq->cap; \ 234 deq->data = (type*) malloc(deq->cap * sizeof(type)); \ 236 if (deq->data == NULL) { \ 237 fprintf(stderr, "ERROR: Failed to reallocate struct_name" \ 244 for (i = 0; i < old_cap - 1; ++i) \ 245 deq->data[i] = old_data[(deq->front + i) % old_cap]; \ 254 static void __on_pop_##struct_name(struct_name* deq) { \ 255 if (is_empty_##struct_name(deq)) { \ 256 fprintf(stderr, "ERROR: Cannot pop from of struct_name while it " \ 262 void push_front_##struct_name(struct_name* deq, type element) { \ 263 assert(deq != NULL); \ 264 assert(deq->data != NULL); \ 265 __on_push_##struct_name(deq); \ 266 deq->front = (deq->front + deq->cap - 1) % deq->cap; \ 267 deq->data[deq->front] = element; \ 270 void push_back_##struct_name(struct_name* deq, type element) { \ 271 assert(deq != NULL); \ 272 assert(deq->data != NULL); \ 273 __on_push_##struct_name(deq); \ 274 deq->data[deq->back] = element; \ 275 deq->back = (deq->back + 1) % deq->cap; \ 278 type pop_front_##struct_name(struct_name* deq) { \ 279 assert(deq != NULL); \ 280 assert(deq->data != NULL); \ 281 __on_pop_##struct_name(deq); \ 282 size_t old_front = deq->front; \ 283 deq->front = (deq->front + 1) % deq->cap; \ 284 return deq->data[old_front]; \ 287 type pop_back_##struct_name(struct_name* deq) { \ 288 assert(deq != NULL); \ 289 assert(deq->data != NULL); \ 290 __on_pop_##struct_name(deq); \ 291 deq->back = (deq->back + deq->cap - 1) % deq->cap; \ 292 return deq->data[deq->back]; \ 295 type peek_front_##struct_name(struct_name* deq) { \ 296 assert(deq != NULL); \ 297 assert(deq->data != NULL); \ 298 assert(!is_empty_##struct_name(deq)); \ 299 return deq->data[deq->front]; \ 302 type peek_back_##struct_name(struct_name* deq) { \ 303 assert(deq != NULL); \ 304 assert(deq->data != NULL); \ 305 assert(!is_empty_##struct_name(deq)); \ 306 return deq->data[(deq->back + deq->cap - 1) % deq->cap]; \ 309 void update_front_##struct_name(struct_name* deq, type element) { \ 310 assert(deq != NULL); \ 311 assert(deq->data != NULL); \ 312 assert(!is_empty_##struct_name(deq)); \ 313 deq->data[deq->front] = element; \ 316 void update_back_##struct_name(struct_name* deq, type element) { \ 317 assert(deq != NULL); \ 318 assert(deq->data != NULL); \ 319 assert(!is_empty_##struct_name(deq)); \ 320 deq->data[(deq->back + deq->cap - 1) % deq->cap] = element; \ 335 #define IMPLEMENT_DEQUE_MEMORY_POOL(struct_name, type) \ 336 struct_name new_##struct_name(size_t); \ 337 struct_name new_destructable_##struct_name(size_t, void (*)(type)); \ 338 void destroy_##struct_name(struct_name*); \ 339 void empty_##struct_name(struct_name*); \ 340 bool is_empty_##struct_name(struct_name*); \ 341 size_t length_##struct_name(struct_name*); \ 342 type* as_array_##struct_name(struct_name*, size_t*); \ 343 void apply_##struct_name(struct_name*, void (*)(type)); \ 344 void push_front_##struct_name(struct_name*, type); \ 345 void push_back_##struct_name(struct_name*, type); \ 346 type pop_front_##struct_name(struct_name*); \ 347 type pop_back_##struct_name(struct_name*); \ 348 type peek_front_##struct_name(struct_name*); \ 349 type peek_back_##struct_name(struct_name*); \ 350 void update_front_##struct_name(struct_name*, type); \ 351 void update_back_##struct_name(struct_name*, type); \ 353 struct_name new_##struct_name(size_t init_cap) { \ 357 ret.cap = init_cap; \ 361 ret.data = (type*) memory_pool_alloc(init_cap * sizeof(type)); \ 363 if (ret.data == NULL) { \ 364 fprintf(stderr, "ERROR: Failed to reallocate struct_name" \ 369 ret.front = ret.back = 0; \ 370 ret.destructor = NULL; \ 375 struct_name new_destructable_##struct_name(size_t init_cap, \ 376 void (*destructor)(type)){ \ 377 struct_name ret = new_##struct_name(init_cap); \ 378 ret.destructor = destructor; \ 382 void destroy_##struct_name(struct_name* deq) { \ 383 assert(deq != NULL); \ 385 if (deq->data == NULL) \ 388 if (deq->destructor != NULL) \ 389 apply_##struct_name(deq, deq->destructor); \ 393 deq->front = deq->back = 0; \ 396 void empty_##struct_name(struct_name* deq) { \ 397 assert(deq != NULL); \ 398 assert(deq->data != NULL); \ 399 deq->front = deq->back = 0; \ 402 bool is_empty_##struct_name(struct_name* deq) { \ 403 assert(deq != NULL); \ 404 assert(deq->data != NULL); \ 405 return deq->front == deq->back; \ 408 size_t length_##struct_name(struct_name* deq) { \ 409 assert(deq != NULL); \ 410 assert(deq->data != NULL); \ 411 return (deq->back - deq->front + deq->cap) % deq->cap; \ 414 static void __reallign_##struct_name(struct_name* deq) { \ 415 assert(deq != NULL); \ 416 assert(deq->data != NULL); \ 418 if (deq->front != 0) { \ 419 type* old_data = deq->data; \ 420 size_t len = length_##struct_name(deq); \ 422 deq->data = (type*) memory_pool_alloc(deq->cap * sizeof(type)); \ 424 if (deq->data == NULL) { \ 425 fprintf(stderr, "ERROR: Failed to reallocate struct_name" \ 432 for (i = 0; i < len; ++i) \ 433 deq->data[i] = old_data[(deq->front + i) % deq->cap]; \ 440 type* as_array_##struct_name(struct_name* deq, size_t* len) { \ 441 assert(deq != NULL); \ 442 assert(deq->data != NULL); \ 444 __reallign_##struct_name(deq); \ 446 type* ret = deq->data; \ 449 *len = length_##struct_name(deq); \ 452 deq->cap = deq->front = deq->back = 0; \ 457 void apply_##struct_name(struct_name* deq, void (*func)(type)) { \ 458 assert(deq != NULL); \ 459 assert(deq->data != NULL); \ 461 size_t len = length_##struct_name(deq); \ 463 for (size_t i = 0; i < len; ++i) { \ 464 func(deq->data[(deq->front + i) % deq->cap]); \ 468 static void __on_push_##struct_name(struct_name* deq) { \ 469 if (deq->front == (deq->back + 1) % deq->cap) { \ 470 type* old_data = deq->data; \ 471 size_t old_cap = deq->cap; \ 473 deq->cap = 2 * deq->cap; \ 474 deq->data = (type*) memory_pool_alloc(deq->cap * sizeof(type)); \ 476 if (deq->data == NULL) { \ 477 fprintf(stderr, "ERROR: Failed to reallocate struct_name" \ 484 for (i = 0; i < old_cap - 1; ++i) \ 485 deq->data[i] = old_data[(deq->front + i) % old_cap]; \ 492 static void __on_pop_##struct_name(struct_name* deq) { \ 493 if (is_empty_##struct_name(deq)) { \ 494 fprintf(stderr, "ERROR: Cannot pop from of struct_name while it " \ 500 void push_front_##struct_name(struct_name* deq, type element) { \ 501 assert(deq != NULL); \ 502 assert(deq->data != NULL); \ 503 __on_push_##struct_name(deq); \ 504 deq->front = (deq->front + deq->cap - 1) % deq->cap; \ 505 deq->data[deq->front] = element; \ 508 void push_back_##struct_name(struct_name* deq, type element) { \ 509 assert(deq != NULL); \ 510 assert(deq->data != NULL); \ 511 __on_push_##struct_name(deq); \ 512 deq->data[deq->back] = element; \ 513 deq->back = (deq->back + 1) % deq->cap; \ 516 type pop_front_##struct_name(struct_name* deq) { \ 517 assert(deq != NULL); \ 518 assert(deq->data != NULL); \ 519 __on_pop_##struct_name(deq); \ 520 size_t old_front = deq->front; \ 521 deq->front = (deq->front + 1) % deq->cap; \ 522 return deq->data[old_front]; \ 525 type pop_back_##struct_name(struct_name* deq) { \ 526 assert(deq != NULL); \ 527 assert(deq->data != NULL); \ 528 __on_pop_##struct_name(deq); \ 529 deq->back = (deq->back + deq->cap - 1) % deq->cap; \ 530 return deq->data[deq->back]; \ 533 type peek_front_##struct_name(struct_name* deq) { \ 534 assert(deq != NULL); \ 535 assert(deq->data != NULL); \ 536 assert(!is_empty_##struct_name(deq)); \ 537 return deq->data[deq->front]; \ 540 type peek_back_##struct_name(struct_name* deq) { \ 541 assert(deq != NULL); \ 542 assert(deq->data != NULL); \ 543 assert(!is_empty_##struct_name(deq)); \ 544 return deq->data[(deq->back + deq->cap - 1) % deq->cap]; \ 547 void update_front_##struct_name(struct_name* deq, type element) { \ 548 assert(deq != NULL); \ 549 assert(deq->data != NULL); \ 550 assert(!is_empty_##struct_name(deq)); \ 551 deq->data[deq->front] = element; \ 554 void update_back_##struct_name(struct_name* deq, type element) { \ 555 assert(deq != NULL); \ 556 assert(deq->data != NULL); \ 557 assert(!is_empty_##struct_name(deq)); \ 558 deq->data[(deq->back + deq->cap - 1) % deq->cap] = element; \ char Type
An example type used for example purposes only.
Definition: deque.h:570
#define IMPLEMENT_DEQUE_STRUCT(struct_name, type)
Generates a structure for use with Double Ended Queues.
Definition: deque.h:33
A data structure generated by IMPLEMENT_DEQUE_STRUCT() to store the state of a deque.
Definition: deque.h:584
#define PROTOTYPE_DEQUE(struct_name, type)
Generates prototypes for functions that manipulate Double Ended Queue structures. ...
Definition: deque.h:60