List.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. typedef size_t (*ToString##N)(const T* data, char* buffer, size_t n); \
  30. size_t toStringList##N(const List##N* l, char* buffer, size_t n, \
  31. ToString##N c);
  32. #define LIST_SOURCE(T, N) \
  33. void initList##N(List##N* l) { \
  34. *l = (List##N){0, 0, nullptr}; \
  35. } \
  36. \
  37. void destroyList##N(List##N* l) { \
  38. coreFree(l->data); \
  39. *l = (List##N){0}; \
  40. } \
  41. \
  42. void reserveListEntries##N(List##N* l, size_t n) { \
  43. if(n > l->capacity) { \
  44. l->capacity = n; \
  45. l->data = coreReallocate(l->data, sizeof(T) * n); \
  46. } \
  47. } \
  48. \
  49. void addListData##N(List##N* l, T data) { \
  50. *addEmptyListData##N(l) = data; \
  51. } \
  52. \
  53. void addLastListData##N(List##N* l) { \
  54. addListData##N(l, *getListLast##N(l)); \
  55. } \
  56. \
  57. T* addEmptyListData##N(List##N* l) { \
  58. if(l->length >= l->capacity) { \
  59. reserveListEntries##N(l, l->capacity + \
  60. maxSize(4lu, l->capacity / 4)); \
  61. } \
  62. return l->data + l->length++; \
  63. } \
  64. \
  65. T* getListIndex##N(const List##N* l, size_t index) { \
  66. assert(index < l->length); \
  67. return l->data + index; \
  68. } \
  69. \
  70. T* getListLast##N(const List##N* l) { \
  71. return getListIndex##N(l, l->length - 1); \
  72. } \
  73. \
  74. void clearList##N(List##N* l) { \
  75. l->length = 0; \
  76. } \
  77. \
  78. void removeListIndexBySwap##N(List##N* l, size_t index) { \
  79. assert(index < l->length); \
  80. size_t length = l->length - 1; \
  81. if(index != length) { \
  82. l->data[index] = l->data[length]; \
  83. } \
  84. l->length = length; \
  85. } \
  86. \
  87. void removeListIndex##N(List##N* l, size_t index) { \
  88. assert(index < l->length); \
  89. l->length--; \
  90. T* p = l->data + index; \
  91. T* end = getListEnd##N(l); \
  92. while(p != end) { \
  93. *p = *(p + 1); \
  94. p++; \
  95. } \
  96. } \
  97. \
  98. void removeListLast##N(List##N* l) { \
  99. removeListIndexBySwap##N(l, l->length - 1); \
  100. } \
  101. \
  102. T* getListStart##N(const List##N* l) { \
  103. return l->data; \
  104. } \
  105. \
  106. T* getListEnd##N(const List##N* l) { \
  107. return l->data + l->length; \
  108. } \
  109. \
  110. size_t toStringList##N(const List##N* l, char* buffer, size_t n, \
  111. ToString##N c) { \
  112. size_t w = 0; \
  113. stringAdd(&w, &buffer, &n, toString(buffer, n, "[")); \
  114. T* end = getListEnd##N(l); \
  115. T* p = getListStart##N(l); \
  116. while(p != end) { \
  117. stringAdd(&w, &buffer, &n, c(p, buffer, n)); \
  118. p++; \
  119. if(p != end) { \
  120. stringAdd(&w, &buffer, &n, toString(buffer, n, ", ")); \
  121. } \
  122. } \
  123. stringAdd(&w, &buffer, &n, toString(buffer, n, "]")); \
  124. return w; \
  125. }
  126. #endif