ds.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. #ifndef __DS_H__
  2. #define __DS_H__
  3. #include <stdint.h>
  4. #include <malloc.h>
  5. #include <string.h>
  6. #include <stdatomic.h>
  7. #include <pthread.h>
  8. // -----------------------
  9. // non-thread-safe vectors
  10. // -----------------------
  11. // declare a vector
  12. #define VEC(t) \
  13. struct { \
  14. size_t len, alloc; \
  15. t* data; \
  16. }
  17. // initialisze a vector
  18. #define VEC_INIT(x) \
  19. do { \
  20. (x)->data = NULL; \
  21. (x)->len = 0; \
  22. (x)->alloc = 0; \
  23. } while(0)
  24. // helpers
  25. #define VEC_LEN(x) ((x)->len)
  26. #define VEC_ALLOC(x) ((x)->alloc)
  27. #define VEC_DATA(x) ((x)->data)
  28. #define VEC_ITEM(x, i) (VEC_DATA(x)[(i)])
  29. #define VEC_TAIL(x) (VEC_DATA(x)[VEC_LEN(x)-1])
  30. #define VEC_HEAD(x) (VEC_DATA(x)[0])
  31. #define VEC_FIND(x, ptr_o) vec_find(VEC_DATA(x), VEC_LEN(x), sizeof(*VEC_DATA(x)), ptr_o)
  32. #define VEC_TRUNC(x) (VEC_LEN(x) = 0)
  33. //
  34. #define VEC_GROW(x) vec_resize((void**)&VEC_DATA(x), &VEC_ALLOC(x), sizeof(*VEC_DATA(x)))
  35. // check if a size increase is needed to insert one more item
  36. #define VEC_CHECK(x) \
  37. do { \
  38. if(VEC_LEN(x) >= VEC_ALLOC(x)) { \
  39. VEC_GROW(x); \
  40. } \
  41. } while(0)
  42. // operations
  43. // increase size and assign the new entry
  44. #define VEC_PUSH(x, e) \
  45. do { \
  46. VEC_CHECK(x); \
  47. VEC_DATA(x)[VEC_LEN(x)] = (e); \
  48. VEC_LEN(x)++; \
  49. } while(0)
  50. // increase size but don't assign
  51. #define VEC_INC(x) \
  52. do { \
  53. VEC_CHECK(x); \
  54. VEC_LEN(x)++; \
  55. } while(0)
  56. #define VEC_PEEK(x) VEC_DATA(x)[VEC_LEN(x) - 1]
  57. #define VEC_POP(x, e) \
  58. do { \
  59. VEC_CHECK(x); \
  60. (e) = VEC_PEEK(x); \
  61. VEC_LEN(x)--; \
  62. } while(0)
  63. #define VEC_POP1(x) \
  64. do { \
  65. VEC_CHECK(x); \
  66. VEC_LEN(x)--; \
  67. } while(0)
  68. // ruins order but is O(1). meh.
  69. #define VEC_RM(x, i) \
  70. do { \
  71. if(VEC_LEN(x) < (i)) break; \
  72. VEC_ITEM(x, i) = VEC_PEEK(x); \
  73. VEC_LEN(x)--; \
  74. } while(0)
  75. // preserves order. O(n)
  76. #define VEC_RM_SAFE(x, i) \
  77. do { \
  78. if(VEC_LEN(x) < (i)) break; \
  79. memmove( \
  80. VEC_DATA(x) + ((i) * sizeof(*VEC_DATA(x))), \
  81. VEC_DATA(x) + (((i) + 1) * sizeof(*VEC_DATA(x))), \
  82. VEC_LEN(x) - (((i) - 1) * sizeof(*VEC_DATA(x))) \
  83. ); \
  84. VEC_LEN(x)--; \
  85. } while(0)
  86. // TODO: vec_set_ins // sorted insert
  87. // TODO: vec_set_rem
  88. // TODO: vec_set_has
  89. // TODO: vec_purge // search and delete of all entries
  90. #define VEC_FREE(x) \
  91. do { \
  92. if(VEC_DATA(x)) free(VEC_DATA(x)); \
  93. VEC_DATA(x) = NULL; \
  94. VEC_LEN(x) = 0; \
  95. VEC_ALLOC(x) = 0; \
  96. } while(0)
  97. #define VEC_COPY(copy, orig) \
  98. do { \
  99. void* tmp; \
  100. tmp = realloc(VEC_DATA(copy), VEC_ALLOC(orig) * sizeof(*VEC_DATA(orig)) ); \
  101. if(!tmp) { \
  102. fprintf(stderr, "Out of memory in vector copy"); \
  103. return; \
  104. } \
  105. \
  106. VEC_DATA(copy) = tmp; \
  107. VEC_LEN(copy) = VEC_LEN(orig); \
  108. VEC_ALLOC(copy) = VEC_ALLOC(orig); \
  109. \
  110. memcpy(VEC_DATA(copy), VEC_DATA(orig), VEC_LEN(orig) * sizeof(*VEC_DATA(orig))); \
  111. } while(0)
  112. #define VEC_REVERSE(x) \
  113. do { \
  114. size_t i, j; \
  115. void* tmp = alloca(sizeof(*VEC_DATA(x))); \
  116. for(i = 0, j = VEC_LEN(x); i < j; i++, j--) { \
  117. memcpy(tmp, VEC_DATA(x)[i]); \
  118. memcpy(VEC_DATA(x)[i], VEC_DATA(x)[j]); \
  119. memcpy(VEC_DATA(x)[j], tmp); \
  120. } \
  121. } while(0)
  122. #define VEC_SPLICE(x, y, where) \
  123. do { \
  124. if(VEC_ALLOC(x) < VEC_LEN(x) + VEC_LEN(y)) { \
  125. vec_resize_to((void**)&VEC_DATA(x), &VEC_ALLOC(x), sizeof(*VEC_DATA(x)), VEC_LEN(x) + VEC_LEN(y)); \
  126. } \
  127. \
  128. memcpy( /* move the rest of x forward */ \
  129. VEC_DATA(x) + where + VEC_LEN(y), \
  130. VEC_DATA(x) + where, \
  131. (VEC_LEN(x) - where) * sizeof(*VEC_DATA(x)) \
  132. ); \
  133. memcpy( /* copy y into the space created */ \
  134. VEC_DATA(x) + where, \
  135. VEC_DATA(y), \
  136. VEC_LEN(y) * sizeof(*VEC_DATA(y)) \
  137. ); \
  138. } while(0)
  139. #define VEC_SORT(x, fn) \
  140. qsort(VEC_DATA(x), VEC_LEN(x), sizeof(*VEC_DATA(x)), (void*)fn);
  141. /*
  142. Loop macro magic
  143. https://www.chiark.greenend.org.uk/~sgtatham/mp/
  144. HashTable obj;
  145. HT_LOOP(&obj, key, char*, val) {
  146. printf("loop: %s, %s", key, val);
  147. }
  148. effective source:
  149. #define HT_LOOP(obj, keyname, valtype, valname)
  150. if(0)
  151. finished: ;
  152. else
  153. for(char* keyname;;) // internal declarations, multiple loops to avoid comma op funny business
  154. for(valtype valname;;)
  155. for(void* iter = NULL ;;)
  156. if(HT_next(obj, iter, &keyname, &valname))
  157. goto main_loop;
  158. else
  159. while(1)
  160. if(1) {
  161. // when the user uses break
  162. goto finished;
  163. }
  164. else
  165. while(1)
  166. if(!HT_next(obj, iter, &keyname, &valname)) {
  167. // normal termination
  168. goto finished;
  169. }
  170. else
  171. main_loop:
  172. // { user block; not in macro }
  173. */
  174. #define VEC__PASTEINNER(a, b) a ## b
  175. #define VEC__PASTE(a, b) VEC__PASTEINNER(a, b)
  176. #define VEC__ITER(key, val) VEC__PASTE(VEC_iter_ ## key ## __ ## val ## __, __LINE__)
  177. #define VEC__FINISHED(key, val) VEC__PASTE(VEC_finished__ ## key ## __ ## val ## __, __LINE__)
  178. #define VEC__MAINLOOP(key, val) VEC__PASTE(VEC_main_loop__ ## key ## __ ## val ## __, __LINE__)
  179. #define VEC_EACH(obj, index, valname) \
  180. if(0) \
  181. VEC__FINISHED(index, val): ; \
  182. else \
  183. for(typeof(*VEC_DATA(obj)) valname ;;) \
  184. for(size_t index = 0;;) \
  185. if(index < VEC_LEN(obj) && (valname = VEC_ITEM(obj, index), 1)) \
  186. goto VEC__MAINLOOP(index, val); \
  187. else \
  188. while(1) \
  189. if(1) { \
  190. goto VEC__FINISHED(index, val); \
  191. } \
  192. else \
  193. while(1) \
  194. if(++index >= VEC_LEN(obj) || (valname = VEC_ITEM(obj, index), 0)) { \
  195. goto VEC__FINISHED(index, val); \
  196. } \
  197. else \
  198. VEC__MAINLOOP(index, val) :
  199. // { user block; not in macro }
  200. // this version only iterates the index
  201. #define VEC_LOOP(obj, index) \
  202. if(0) \
  203. VEC__FINISHED(index, val): ; \
  204. else \
  205. for(size_t index = 0;;) \
  206. if(index < VEC_LEN(obj)) \
  207. goto VEC__MAINLOOP(index, val); \
  208. else \
  209. while(1) \
  210. if(1) { \
  211. goto VEC__FINISHED(index, val); \
  212. } \
  213. else \
  214. while(1) \
  215. if(++index >= VEC_LEN(obj)) { \
  216. goto VEC__FINISHED(index, val); \
  217. } \
  218. else \
  219. VEC__MAINLOOP(index, val) :
  220. // { user block; not in macro }
  221. void vec_resize(void** data, size_t* size, size_t elem_size);
  222. ptrdiff_t vec_find(void* data, size_t len, size_t stride, void* search);
  223. void vec_resize_to(void** data, size_t* size, size_t elem_size, size_t new_size);
  224. /*********************************
  225. Linked Lists
  226. **********************************
  227. minimal struct signature:
  228. typedef struct Link {
  229. struct Link* next;
  230. struct Link* prev;
  231. } Link;
  232. typedef struct List {
  233. Link* head;
  234. Link* tail;
  235. int length;
  236. } List;
  237. these macros are not perfect. they create temporary variables and should not be nested.
  238. */
  239. #define LIST_DECL(type, prop) \
  240. typedef struct type ## _Link { \
  241. struct type ## _Link *next, *prev; \
  242. type prop; \
  243. } type ## _Link; \
  244. typedef struct type ## _List { \
  245. struct type ## _Link *head, *tail; \
  246. int length; \
  247. } type ## _List;
  248. #define LIST_INIT(list) \
  249. (list)->head = NULL; \
  250. (list)->tail = NULL; \
  251. (list)->length = 0;
  252. #define LIST_APPEND(list, prop, x) \
  253. do { \
  254. typeof((list)->head) __new_link = calloc(1, sizeof(*__new_link)); \
  255. __new_link->prev = (list)->tail; \
  256. if(__new_link->prev) __new_link->prev->next = __new_link; \
  257. (list)->tail = __new_link; \
  258. if((list)->head == NULL) (list)->head = __new_link; \
  259. __new_link->prop = (x); \
  260. (list)->length++; \
  261. } while(0);
  262. #define LIST_PREPEND(list, prop, x) \
  263. do { \
  264. typeof((list)->head) __new_link = calloc(1, sizeof(*__new_link)); \
  265. __new_link->next = (list)->head; \
  266. if(__new_link->next) __new_link->next->prev = __new_link; \
  267. (list)->head = __new_link; \
  268. if((list)->tail == NULL) (list)->tail = __new_link; \
  269. __new_link->prop = x; \
  270. (list)->length++; \
  271. } while(0);
  272. #define LIST_INS_AFTER(list, exist, prop, x) \
  273. do { \
  274. typeof((list)->head) __new_link = calloc(1, sizeof(*__new_link)); \
  275. __new_link->next = (exist)->next; \
  276. __new_link->prev = exist; \
  277. (exist)->next = __new_link; \
  278. if(__new_link->next) __new_link->next->prev = __new_link; \
  279. if((list)->tail == (exist)) (list)->tail = __new_link; \
  280. __new_link->prop = x; \
  281. } while(0);
  282. #define LIST_REMOVE(list, link) \
  283. do { \
  284. typeof((list)->head) __link = (link); \
  285. if((__link) == (list)->head) (list)->head = (__link)->next; \
  286. if((__link) == (list)->tail) (list)->tail = (__link)->prev; \
  287. if((__link)->prev) (__link)->prev->next = (__link)->next; \
  288. if((__link)->next) (__link)->next->prev = (__link)->prev; \
  289. free(__link); \
  290. (list)->length = (list)->length == 0 ? 0 : (list)->length - 1; \
  291. } while(0);
  292. // allows for cyclic iteration
  293. #define LIST_NEXT_LOOP(list, link) \
  294. ((link)->next ? (link)->next : (list)->head)
  295. #define LIST_PREV_LOOP(list, link) \
  296. ((link)->prev ? (link)->prev : (list)->tail)
  297. // concat or copy a list
  298. #define LIST_CONCAT(src, dest) \
  299. do { \
  300. typeof((src)->head) __link = (src)->head; \
  301. while(__link) { \
  302. typeof((src)->head) __new_link = calloc(1, sizeof(*__new_link)); \
  303. memcpy(__new_link, __link, sizeof(*__link)); \
  304. __new_link->next = NULL; \
  305. __new_link->prev = (dest)->tail; \
  306. if((dest)->tail) (dest)->tail->next = __new_link; \
  307. if((dest)->head == NULL) (dest)->head = __new_link; \
  308. (dest)->tail = __new_link; \
  309. (dest)->length++; \
  310. __link = __link->next; \
  311. } \
  312. } while(0);
  313. // does not create a new list from the output
  314. #define LIST_MAP(list, fn) \
  315. do { \
  316. typeof((list)->head) __link = (list)->head; \
  317. while(__link) { \
  318. (fn)(__link); \
  319. __link = __link->next; \
  320. } \
  321. } while(0);
  322. #define LIST_FREE(list) \
  323. do { \
  324. typeof((list)->head) __link = (list)->head; \
  325. while(__link) { \
  326. typeof((list)->head) __tmp = __link; \
  327. __link = __link->next; \
  328. free(__tmp); \
  329. } \
  330. (list)->head = NULL; \
  331. (list)->tail = NULL; \
  332. (list)->length = 0; \
  333. } while(0);
  334. #define LIST__PASTEINNER(a, b) a ## b
  335. #define LIST__PASTE(a, b) LIST__PASTEINNER(a, b)
  336. #define LIST__FINISHED(iter) LIST__PASTE(LIST_finished__ ## iter ## __, __LINE__)
  337. #define LIST__MAINLOOP(iter) LIST__PASTE(LIST_main_loop__ ## iter ## __, __LINE__)
  338. #define LIST_LOOP(list, iter) \
  339. if(0) \
  340. LIST__FINISHED(iter): ; \
  341. else \
  342. for(typeof((list)->head) iter = (list)->head;;) \
  343. if(iter != NULL) \
  344. goto LIST__MAINLOOP(iter); \
  345. else \
  346. while(1) \
  347. if(1) { \
  348. goto LIST__FINISHED(iter); \
  349. } \
  350. else \
  351. while(1) \
  352. if(iter = iter->next, iter == NULL) { \
  353. goto LIST__FINISHED(iter); \
  354. } \
  355. else \
  356. LIST__MAINLOOP(iter) :
  357. // { user block; not in macro }
  358. #endif // __DS_H__