Queue.h 5.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #ifndef CORE_QUEUE_H
  2. #define CORE_QUEUE_H
  3. #include <assert.h>
  4. #include "core/ToString.h"
  5. #include "core/Types.h"
  6. #include "core/Utility.h"
  7. #define QUEUE(T, N) \
  8. typedef struct { \
  9. size_t writeIndex; \
  10. size_t readIndex; \
  11. size_t length; \
  12. size_t capacity; \
  13. T* data; \
  14. } Queue##N; \
  15. \
  16. void initQueue##N(Queue##N* r, size_t capacity); \
  17. void destroyQueue##N(Queue##N* r); \
  18. void pushQueueData##N(Queue##N* r, T data); \
  19. T* getQueueIndex##N(const Queue##N* r, size_t index); \
  20. void clearQueue##N(Queue##N* r); \
  21. void popQueueData##N(Queue##N* r); \
  22. typedef size_t (*ToString##N)(const T* data, char* buffer, size_t n); \
  23. size_t toStringQueue##N(const Queue##N* r, char* buffer, size_t n, \
  24. ToString##N c);
  25. #define QUEUE_SOURCE(T, N) \
  26. void initQueue##N(Queue##N* r, size_t capacity) { \
  27. *r = ((Queue##N){0, 0, 0, capacity, nullptr}); \
  28. } \
  29. \
  30. void destroyQueue##N(Queue##N* r) { \
  31. coreFree(r->data); \
  32. *r = (Queue##N){0}; \
  33. } \
  34. \
  35. void pushQueueData##N(Queue##N* r, T data) { \
  36. if(r->length >= r->capacity) { \
  37. return; \
  38. } else if(r->data == nullptr) { \
  39. r->data = coreAllocate(r->capacity * sizeof(T)); \
  40. } \
  41. r->data[r->writeIndex] = data; \
  42. r->writeIndex = (r->writeIndex + 1) % r->capacity; \
  43. r->length++; \
  44. } \
  45. \
  46. T* getQueueIndex##N(const Queue##N* r, size_t index) { \
  47. return r->data + ((index + r->readIndex) % r->capacity); \
  48. } \
  49. \
  50. void clearQueue##N(Queue##N* r) { \
  51. r->writeIndex = 0; \
  52. r->readIndex = 0; \
  53. r->length = 0; \
  54. } \
  55. \
  56. void popQueueData##N(Queue##N* r) { \
  57. assert(r->length > 0); \
  58. r->length--; \
  59. r->readIndex = (r->readIndex + 1) % r->capacity; \
  60. } \
  61. \
  62. size_t toStringQueue##N(const Queue##N* r, char* buffer, size_t n, \
  63. ToString##N c) { \
  64. size_t w = 0; \
  65. stringAdd(&w, &buffer, &n, toString(buffer, n, "[")); \
  66. size_t end = r->length; \
  67. if(end > 0) { \
  68. end--; \
  69. for(size_t i = 0; i < end; i++) { \
  70. stringAdd(&w, &buffer, &n, \
  71. c(getQueueIndex##N(r, i), buffer, n)); \
  72. stringAdd(&w, &buffer, &n, toString(buffer, n, ", ")); \
  73. } \
  74. stringAdd(&w, &buffer, &n, \
  75. c(getQueueIndex##N(r, end), buffer, n)); \
  76. } \
  77. stringAdd(&w, &buffer, &n, toString(buffer, n, "]")); \
  78. return w; \
  79. }
  80. #endif