List.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #ifndef CORE_LIST_H
  2. #define CORE_LIST_H
  3. #include <assert.h>
  4. #include "core/ToString.h"
  5. #include "core/Types.h"
  6. #include "core/Utility.h"
  7. #define LIST(T, N) \
  8. struct ListT##N { \
  9. size_t length; \
  10. size_t capacity; \
  11. T* data; \
  12. }; \
  13. typedef struct ListT##N List##N; \
  14. \
  15. void initList##N(List##N* l); \
  16. void destroyList##N(List##N* l); \
  17. void reserveListEntries##N(List##N* l, size_t n); \
  18. void addListData##N(List##N* l, T data); \
  19. void addLastListData##N(List##N* l); \
  20. T* addEmptyListData##N(List##N* l); \
  21. T* getListIndex##N(const List##N* l, size_t index); \
  22. T* getListLast##N(const List##N* l); \
  23. void clearList##N(List##N* l); \
  24. void removeListIndexBySwap##N(List##N* l, size_t index); \
  25. void removeListIndex##N(List##N* l, size_t index); \
  26. void removeListLast##N(List##N* l); \
  27. T* getListStart##N(const List##N* l); \
  28. T* getListEnd##N(const List##N* l); \
  29. size_t toStringList##N(const List##N* l, char* buffer, size_t n, \
  30. CoreToString c);
  31. #define LIST_SOURCE(T, N) \
  32. void initList##N(List##N* l) { \
  33. *l = (List##N){0, 0, nullptr}; \
  34. } \
  35. \
  36. void destroyList##N(List##N* l) { \
  37. coreFree(l->data); \
  38. *l = (List##N){0}; \
  39. } \
  40. \
  41. void reserveListEntries##N(List##N* l, size_t n) { \
  42. if(n > l->capacity) { \
  43. l->capacity = n; \
  44. l->data = coreReallocate(l->data, sizeof(T) * n); \
  45. } \
  46. } \
  47. \
  48. void addListData##N(List##N* l, T data) { \
  49. *addEmptyListData##N(l) = data; \
  50. } \
  51. \
  52. void addLastListData##N(List##N* l) { \
  53. addListData##N(l, *getListLast##N(l)); \
  54. } \
  55. \
  56. T* addEmptyListData##N(List##N* l) { \
  57. if(l->length >= l->capacity) { \
  58. reserveListEntries##N(l, l->capacity + \
  59. coreMaxSize(4lu, l->capacity / 4)); \
  60. } \
  61. return l->data + l->length++; \
  62. } \
  63. \
  64. T* getListIndex##N(const List##N* l, size_t index) { \
  65. assert(index < l->length); \
  66. return l->data + index; \
  67. } \
  68. \
  69. T* getListLast##N(const List##N* l) { \
  70. return getListIndex##N(l, l->length - 1); \
  71. } \
  72. \
  73. void clearList##N(List##N* l) { \
  74. l->length = 0; \
  75. } \
  76. \
  77. void removeListIndexBySwap##N(List##N* l, size_t index) { \
  78. assert(index < l->length); \
  79. size_t length = l->length - 1; \
  80. if(index != length) { \
  81. l->data[index] = l->data[length]; \
  82. } \
  83. l->length = length; \
  84. } \
  85. \
  86. void removeListIndex##N(List##N* l, size_t index) { \
  87. assert(index < l->length); \
  88. l->length--; \
  89. T* p = l->data + index; \
  90. T* end = getListEnd##N(l); \
  91. while(p != end) { \
  92. *p = *(p + 1); \
  93. p++; \
  94. } \
  95. } \
  96. \
  97. void removeListLast##N(List##N* l) { \
  98. removeListIndexBySwap##N(l, l->length - 1); \
  99. } \
  100. \
  101. T* getListStart##N(const List##N* l) { \
  102. return l->data; \
  103. } \
  104. \
  105. T* getListEnd##N(const List##N* l) { \
  106. return l->data + l->length; \
  107. } \
  108. \
  109. size_t toStringList##N(const List##N* l, char* buffer, size_t n, \
  110. CoreToString c) { \
  111. size_t w = 0; \
  112. coreStringAdd(&w, &buffer, &n, coreToString(buffer, n, "[")); \
  113. T* end = getListEnd##N(l); \
  114. T* p = getListStart##N(l); \
  115. while(p != end) { \
  116. coreStringAdd(&w, &buffer, &n, c(p, buffer, n)); \
  117. p++; \
  118. if(p != end) { \
  119. coreStringAdd(&w, &buffer, &n, coreToString(buffer, n, ", ")); \
  120. } \
  121. } \
  122. coreStringAdd(&w, &buffer, &n, coreToString(buffer, n, "]")); \
  123. return w; \
  124. }
  125. #endif