vec.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. #ifndef __sti__vec_h__
  2. #define __sti__vec_h__
  3. // Public Domain.
  4. #include <stddef.h> // size_t
  5. #include <sys/types.h> // ssize_t
  6. #include <string.h> // memcpy
  7. #include "macros.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. #define VEC_INIT(x) VEC_init(x)
  25. // helpers
  26. #define VEC_LEN(x) ((x)->len)
  27. #define VEC_len(x) ((x)->len)
  28. #define VEC_ALLOC(x) ((x)->alloc)
  29. #define VEC_alloc(x) ((x)->alloc)
  30. #define VEC_DATA(x) ((x)->data)
  31. #define VEC_data(x) ((x)->data)
  32. #define VEC_ITEM(x, i) (VEC_data(x)[(i)])
  33. #define VEC_item(x, i) (VEC_data(x)[(i)])
  34. #define VEC_TAIL(x) (VEC_data(x)[VEC_LEN(x)-1])
  35. #define VEC_tail(x) (VEC_data(x)[VEC_LEN(x)-1])
  36. #define VEC_HEAD(x) (VEC_data(x)[0])
  37. #define VEC_head(x) (VEC_data(x)[0])
  38. #define VEC_FIND(x, ptr_o) vec_find(VEC_data(x), VEC_LEN(x), sizeof(*VEC_data(x)), ptr_o)
  39. #define VEC_find(x, ptr_o) vec_find(VEC_data(x), VEC_LEN(x), sizeof(*VEC_data(x)), ptr_o)
  40. #define VEC_TRUNC(x) (VEC_LEN(x) = 0)
  41. #define VEC_trunc(x) (VEC_LEN(x) = 0)
  42. //
  43. #define VEC_GROW(x) vec_resize((void**)&VEC_data(x), &VEC_ALLOC(x), sizeof(*VEC_data(x)))
  44. // check if a size increase is needed to insert one more item
  45. #define VEC_CHECK(x) \
  46. do { \
  47. if(VEC_LEN(x) >= VEC_ALLOC(x)) { \
  48. VEC_GROW(x); \
  49. } \
  50. } while(0)
  51. // operations
  52. // increase size and assign the new entry
  53. #define VEC_PUSH(x, ...) VEC_push(x, __VA_ARGS__)
  54. #define VEC_push(x, ...) \
  55. do { \
  56. VEC_CHECK(x); \
  57. VEC_data(x)[VEC_LEN(x)] = (__VA_ARGS__); \
  58. VEC_LEN(x)++; \
  59. } while(0)
  60. // increase size and evaluates to a pointer to it
  61. #define VEC_INC(x) VEC_inc(x)
  62. #define VEC_inc(x) \
  63. ({ \
  64. VEC_CHECK(x); \
  65. VEC_LEN(x)++; \
  66. memset(&VEC_TAIL(x), 0, sizeof(*VEC_data(x))); \
  67. &VEC_TAIL(x); \
  68. })
  69. // set the size and zero the contents
  70. #define VEC_CALLOC(x, sz) VEC_calloc(x, sz)
  71. #define VEC_calloc(x, sz) \
  72. do { \
  73. if(VEC_ALLOC(x) < (sz)) { \
  74. vec_resize_to((void**)&VEC_data(x), &VEC_ALLOC(x), sizeof(*VEC_data(x)), (sz)); \
  75. } \
  76. VEC_LEN(x) = (sz); \
  77. memset(VEC_data(x), 0, sizeof(*VEC_data(x)) * (sz)); \
  78. } while(0)
  79. // Ensure that the vec is at least of a certain size, and zero any newly allocated portion
  80. #define VEC_CREALLOC(x, sz) VEC_crealloc(x, sz)
  81. #define VEC_crealloc(x, sz) \
  82. do { \
  83. if(VEC_ALLOC(x) < (sz)) { \
  84. vec_c_resize_to((void**)&VEC_data(x), &VEC_ALLOC(x), sizeof(*VEC_data(x)), (sz)); \
  85. VEC_LEN(x) = (sz); \
  86. } \
  87. } while(0)
  88. #define VEC_PREPEND(x, e) VEC_prepend(x, e)
  89. #define VEC_prepend(x, e) \
  90. do { \
  91. VEC_CHECK(x); \
  92. memmove( \
  93. VEC_data(x) + 1, \
  94. VEC_data(x), \
  95. VEC_LEN(x) * sizeof(*VEC_data(x)) \
  96. ); \
  97. VEC_data(x)[0] = (e); \
  98. VEC_LEN(x)++; \
  99. } while(0)
  100. #define VEC_PEEK(x) VEC_peek(x)
  101. #define VEC_peek(x) VEC_data(x)[VEC_LEN(x) - 1]
  102. #define VEC_POP(x, e) VEC_pop(x, e)
  103. #define VEC_pop(...) VEC_pop_N(PP_NARG(__VA_ARGS__), __VA_ARGS__)
  104. #define VEC_pop_N(n, ...) CAT(VEC_pop_, n)(__VA_ARGS__)
  105. #define VEC_pop_2(x, e) \
  106. do { \
  107. if(VEC_LEN(x) > 0) { \
  108. (e) = VEC_PEEK(x); \
  109. VEC_LEN(x)--; \
  110. } \
  111. } while(0)
  112. #define VEC_POP1(x) VEC_pop_1(x)
  113. #define VEC_pop_1(x) \
  114. ({ \
  115. if(VEC_LEN(x) > 0) { \
  116. VEC_LEN(x)--; \
  117. } \
  118. VEC_item(x, VEC_len(x)); \
  119. })
  120. // ruins order but is O(1). meh.
  121. #define VEC_RM(x, i) VEC_rm(x, i)
  122. #define VEC_rm(x, i) \
  123. do { \
  124. if(VEC_LEN(x) < (i)) break; \
  125. VEC_ITEM(x, i) = VEC_PEEK(x); \
  126. VEC_LEN(x)--; \
  127. } while(0)
  128. // preserves order. O(n)
  129. #define VEC_RM_SAFE(x, i) VEC_rm_safe(x, i)
  130. #define VEC_rm_safe(x, i) \
  131. do { \
  132. if(VEC_LEN(x) < (i)) break; \
  133. memmove( \
  134. (char*)VEC_data(x) + ((i) * sizeof(*VEC_data(x))), \
  135. (char*)VEC_data(x) + (((i) + 1) * sizeof(*VEC_data(x))), \
  136. (VEC_LEN(x) - (i)) * sizeof(*VEC_data(x)) \
  137. ); \
  138. VEC_LEN(x)--; \
  139. } while(0)
  140. // ruins order but is O(1). meh. TODO: add type check on the val
  141. #define VEC_rm_val(x, ptr_o) vec_rm_val((char*)VEC_data(x), &VEC_LEN(x), sizeof(*VEC_data(x)), ptr_o)
  142. #define VEC_RM_VAL(x, ptr_o) vec_rm_val((char*)VEC_data(x), &VEC_LEN(x), sizeof(*VEC_data(x)), ptr_o)
  143. // TODO: vec_set_ins // sorted insert
  144. // TODO: vec_set_rem
  145. // TODO: vec_set_has
  146. // TODO: vec_purge // search and delete of all entries
  147. #define VEC_FREE(x) VEC_free(x)
  148. #define VEC_free(x) \
  149. do { \
  150. if(VEC_data(x)) free(VEC_data(x)); \
  151. VEC_data(x) = NULL; \
  152. VEC_LEN(x) = 0; \
  153. VEC_ALLOC(x) = 0; \
  154. } while(0)
  155. #define VEC_COPY(dst, src) VEC_copy(dst, src)
  156. #define VEC_copy(dst, src) vec_copy( \
  157. (char**)&VEC_data(dst), (char*)VEC_data(src), \
  158. &VEC_ALLOC(dst), VEC_ALLOC(src), \
  159. &VEC_LEN(dst), VEC_LEN(src), \
  160. sizeof(*VEC_data(src)))
  161. #define VEC_REVERSE(x) VEC_reverse(x)
  162. #define VEC_reverse(x) \
  163. do { \
  164. size_t i, j; \
  165. void* tmp = alloca(sizeof(*VEC_data(x))); \
  166. for(i = 0, j = VEC_LEN(x); i < j; i++, j--) { \
  167. memcpy(tmp, VEC_data(x)[i]); \
  168. memcpy(VEC_data(x)[i], VEC_data(x)[j]); \
  169. memcpy(VEC_data(x)[j], tmp); \
  170. } \
  171. } while(0)
  172. #define VEC_INSERT_AT(x, e, i) VEC_insert_at(x, e, i)
  173. #define VEC_insert_at(x, e, i) \
  174. do { \
  175. VEC_CHECK(x); \
  176. memmove( /* move the rest of x forward */ \
  177. VEC_data(x) + (i) + 1, \
  178. VEC_data(x) + (i), \
  179. (VEC_LEN(x) - (i)) * sizeof(*VEC_data(x)) \
  180. ); \
  181. VEC_data(x)[i] = (e); \
  182. } while(0)
  183. #define VEC_SPLICE(x, y, where) VEC_splice(x, y, where)
  184. #define VEC_splice(x, y, where) \
  185. do { \
  186. if(VEC_ALLOC(x) < VEC_LEN(x) + VEC_LEN(y)) { \
  187. vec_resize_to((void**)&VEC_data(x), &VEC_ALLOC(x), sizeof(*VEC_data(x)), VEC_LEN(x) + VEC_LEN(y)); \
  188. } \
  189. \
  190. memmove( /* move the rest of x forward */ \
  191. VEC_data(x) + ((where) + VEC_LEN(y)), \
  192. VEC_data(x) + (where), \
  193. (VEC_LEN(x) - (where)) * sizeof(*VEC_data(x)) \
  194. ); \
  195. memcpy( /* copy y into the space created */ \
  196. VEC_data(x) + (where), \
  197. VEC_data(y), \
  198. VEC_LEN(y) * sizeof(*VEC_data(y)) \
  199. ); \
  200. VEC_LEN(x) += VEC_LEN(y); \
  201. } while(0)
  202. // concatenate y onto the end of x
  203. #define VEC_CAT(x, y) VEC_cat(x,y)
  204. #define VEC_cat(x, y) \
  205. do { \
  206. if(VEC_ALLOC(x) < VEC_LEN(x) + VEC_LEN(y)) { \
  207. vec_resize_to((void**)&VEC_data(x), &VEC_ALLOC(x), sizeof(*VEC_data(x)), VEC_LEN(x) + VEC_LEN(y)); \
  208. } \
  209. memcpy( \
  210. VEC_data(x) + VEC_LEN(x), \
  211. VEC_data(y), \
  212. VEC_LEN(y) * sizeof(*VEC_data(y)) \
  213. ); \
  214. VEC_LEN(x) += VEC_LEN(y); \
  215. } while(0)
  216. // make some space somewhere
  217. #define VEC_RESERVE(x, len, where) VEC_reserve(x,len,where)
  218. #define VEC_reserve(x, len, where) \
  219. do { \
  220. if(VEC_ALLOC(x) < VEC_LEN(x) + (len)) { \
  221. vec_resize_to((void**)&VEC_data(x), &VEC_ALLOC(x), sizeof(*VEC_data(x)), VEC_LEN(x) + (len)); \
  222. } \
  223. \
  224. memmove( /* move the rest of x forward */ \
  225. VEC_data(x) + (where) + (len), \
  226. VEC_data(x) + (where), \
  227. (VEC_LEN(x) - (where)) * sizeof(*VEC_data(x)) \
  228. ); \
  229. VEC_LEN(x) += (len); \
  230. } while(0)
  231. // copy data from y into x at where, overwriting existing data in x
  232. // extends x if it would overlap the end
  233. #define VEC_OVERWRITE(x, y, where) VEC_overwrite(x,y,where)
  234. #define VEC_overwrite(x, y, where) \
  235. do { \
  236. if(VEC_ALLOC(x) < VEC_LEN(y) + (where)) { \
  237. vec_resize_to((void**)&VEC_data(x), &VEC_ALLOC(x), sizeof(*VEC_data(x)), where + VEC_LEN(y)); \
  238. } \
  239. memcpy( /* copy y into the space created */ \
  240. VEC_data(x) + where, \
  241. VEC_data(y), \
  242. VEC_LEN(y) * sizeof(*VEC_data(y)) \
  243. ); \
  244. VEC_LEN(x) = MAX(VEC_LEN(x), VEC_LEN(y) + (where)); \
  245. } while(0)
  246. #define VEC_SORT(x, fn) VEC_sort(x, fn)
  247. #define VEC_sort(x, fn) \
  248. qsort(VEC_data(x), VEC_LEN(x), sizeof(*VEC_data(x)), (int(*)(const void*,const void*))fn);
  249. #define VEC_SORT_R(x, fn, s) VEC_sort_r(x,fn,s)
  250. #define VEC_sort_r(x, fn, s) \
  251. qsort_r(VEC_data(x), VEC_LEN(x), sizeof(*VEC_data(x)), (int(*)(const void*,const void*,void*))fn, (void*)s);
  252. // moves the specified index into sorted position inside an otherwise sorted vec
  253. // IMPORTANT: the vec is assumed to be sorted except the specified index
  254. // returns the new index
  255. #define VEC_BUBBLE_INDEX(x, i, fn) VEC_bubble_index(x,i,fn)
  256. #define VEC_bubble_index(x, i, fn) \
  257. vec_bubble_index(VEC_data(x), VEC_LEN(x), sizeof(*VEC_data(x)), (i), (int(*)(const void*,const void*))fn);
  258. #define VEC_UNIQ(x, fn) VEC_uniq(x,fn)
  259. #define VEC_uniq(x, fn) \
  260. vec_uniq(VEC_data(x), &VEC_LEN(x), sizeof(*VEC_data(x)), (int(*)(const void*,const void*))fn);
  261. #define VEC_UNIQ_R(x, fn) VEC_uniq_r(x, fn)
  262. #define VEC_uniq_r(x, fn) \
  263. vec_uniq_r(VEC_data(x), &VEC_LEN(x), sizeof(*VEC_data(x)), (int(*)(const void*,const void*))fn);
  264. /*
  265. Loop macro magic
  266. https://www.chiark.greenend.org.uk/~sgtatham/mp/
  267. HashTable obj;
  268. HT_LOOP(&obj, key, char*, val) {
  269. printf("loop: %s, %s", key, val);
  270. }
  271. effective source:
  272. #define HT_LOOP(obj, keyname, valtype, valname)
  273. if(0)
  274. finished: ;
  275. else
  276. for(char* keyname;;) // internal declarations, multiple loops to avoid comma op funny business
  277. for(valtype valname;;)
  278. for(void* iter = NULL ;;)
  279. if(HT_next(obj, iter, &keyname, &valname))
  280. goto main_loop;
  281. else
  282. while(1)
  283. if(1) {
  284. // when the user uses break
  285. goto finished;
  286. }
  287. else
  288. while(1)
  289. if(!HT_next(obj, iter, &keyname, &valname)) {
  290. // normal termination
  291. goto finished;
  292. }
  293. else
  294. main_loop:
  295. // { user block; not in macro }
  296. */
  297. #define VEC__PASTEINNER(a, b) a ## b
  298. #define VEC__PASTE(a, b) VEC__PASTEINNER(a, b)
  299. #define VEC__ITER(key, val) VEC__PASTE(VEC_iter_ ## key ## __ ## val ## __, __LINE__)
  300. #define VEC__FINISHED(key, val) VEC__PASTE(VEC_finished__ ## key ## __ ## val ## __, __LINE__)
  301. #define VEC__MAINLOOP(key, val) VEC__PASTE(VEC_main_loop__ ## key ## __ ## val ## __, __LINE__)
  302. #define VEC_EACH(obj, index, valname) \
  303. if(0) \
  304. VEC__FINISHED(index, val): ; \
  305. else \
  306. for(typeof(*VEC_data(obj)) valname ;;) \
  307. for(size_t index = 0;;) \
  308. if(index < VEC_LEN(obj) && (valname = VEC_ITEM(obj, index), 1)) \
  309. goto VEC__MAINLOOP(index, val); \
  310. else \
  311. while(1) \
  312. if(1) { \
  313. goto VEC__FINISHED(index, val); \
  314. } \
  315. else \
  316. while(1) \
  317. if(++index >= VEC_LEN(obj) || (valname = VEC_ITEM(obj, index), 0)) { \
  318. goto VEC__FINISHED(index, val); \
  319. } \
  320. else \
  321. VEC__MAINLOOP(index, val) :
  322. // { user block; not in macro }
  323. // pointer version
  324. #define VEC_EACHP(obj, index, valname) \
  325. if(0) \
  326. VEC__FINISHED(index, val): ; \
  327. else \
  328. for(typeof(*VEC_data(obj))* valname ;;) \
  329. for(size_t index = 0;;) \
  330. if(index < VEC_LEN(obj) && (valname = &VEC_ITEM(obj, index), 1)) \
  331. goto VEC__MAINLOOP(index, val); \
  332. else \
  333. while(1) \
  334. if(1) { \
  335. goto VEC__FINISHED(index, val); \
  336. } \
  337. else \
  338. while(1) \
  339. if(++index >= VEC_LEN(obj) || (valname = &VEC_ITEM(obj, index), 0)) { \
  340. goto VEC__FINISHED(index, val); \
  341. } \
  342. else \
  343. VEC__MAINLOOP(index, val) :
  344. // { user block; not in macro }
  345. // reverse
  346. #define VEC_R_EACH(obj, index, valname) \
  347. if(0) \
  348. VEC__FINISHED(index, val): ; \
  349. else \
  350. for(typeof(*VEC_data(obj)) valname ;;) \
  351. for(ptrdiff_t index = (ptrdiff_t)VEC_LEN(obj) - 1;;) \
  352. if(index >= 0 && (valname = VEC_ITEM(obj, index), 1)) \
  353. goto VEC__MAINLOOP(index, val); \
  354. else \
  355. while(1) \
  356. if(1) { \
  357. goto VEC__FINISHED(index, val); \
  358. } \
  359. else \
  360. while(1) \
  361. if(--index < 0 || (valname = VEC_ITEM(obj, index), 0)) { \
  362. goto VEC__FINISHED(index, val); \
  363. } \
  364. else \
  365. VEC__MAINLOOP(index, val) :
  366. // { user block; not in macro }
  367. // reverse
  368. #define VEC_R_EACHP(obj, index, valname) \
  369. if(0) \
  370. VEC__FINISHED(index, val): ; \
  371. else \
  372. for(typeof(*VEC_data(obj))* valname ;;) \
  373. for(ptrdiff_t index = (ptrdiff_t)VEC_LEN(obj) - 1;;) \
  374. if(index >= 0 && (valname = &VEC_ITEM(obj, index), 1)) \
  375. goto VEC__MAINLOOP(index, val); \
  376. else \
  377. while(1) \
  378. if(1) { \
  379. goto VEC__FINISHED(index, val); \
  380. } \
  381. else \
  382. while(1) \
  383. if(--index < 0 || (valname = &VEC_ITEM(obj, index), 0)) { \
  384. goto VEC__FINISHED(index, val); \
  385. } \
  386. else \
  387. VEC__MAINLOOP(index, val) :
  388. // { user block; not in macro }
  389. // this version only iterates the index
  390. #define VEC_LOOP(obj, index) \
  391. if(0) \
  392. VEC__FINISHED(index, val): ; \
  393. else \
  394. for(size_t index = 0;;) \
  395. if(index < VEC_LEN(obj)) \
  396. goto VEC__MAINLOOP(index, val); \
  397. else \
  398. while(1) \
  399. if(1) { \
  400. goto VEC__FINISHED(index, val); \
  401. } \
  402. else \
  403. while(1) \
  404. if(++index >= VEC_LEN(obj)) { \
  405. goto VEC__FINISHED(index, val); \
  406. } \
  407. else \
  408. VEC__MAINLOOP(index, val) :
  409. // { user block; not in macro }
  410. // reverse; this version only iterates the index
  411. #define VEC_R_LOOP(obj, index) \
  412. if(0) \
  413. VEC__FINISHED(index, val): ; \
  414. else \
  415. for(ptrdiff_t index = (ptrdiff_t)VEC_LEN(obj) - 1;;) \
  416. if(index >= 0) \
  417. goto VEC__MAINLOOP(index, val); \
  418. else \
  419. while(1) \
  420. if(1) { \
  421. goto VEC__FINISHED(index, val); \
  422. } \
  423. else \
  424. while(1) \
  425. if(--index < 0) { \
  426. goto VEC__FINISHED(index, val); \
  427. } \
  428. else \
  429. VEC__MAINLOOP(index, val) :
  430. // { user block; not in macro }
  431. // Do not use these directly.
  432. void vec_resize(void** data, size_t* size, size_t elem_size);
  433. ptrdiff_t vec_find(void* data, size_t len, size_t stride, void* search);
  434. ptrdiff_t vec_rm_val(char* data, size_t* len, size_t stride, void* search);
  435. void vec_resize_to(void** data, size_t* size, size_t elem_size, size_t new_size);
  436. void vec_c_resize_to(void** data, size_t* size, size_t elem_size, size_t new_size);
  437. void vec_copy(
  438. char** dst_data, char* src_data,
  439. size_t* dst_alloc, size_t src_alloc,
  440. size_t* dst_len, size_t src_len,
  441. size_t elem_size
  442. );
  443. ssize_t vec_bubble_index(void* data, size_t len, size_t stride, size_t index, int (*cmp)(const void*,const void*));
  444. void vec_uniq(void* data, size_t* lenp, size_t stride, int (*cmp)(const void*,const void*));
  445. void vec_uniq_r(void* data, size_t* lenp, size_t stride, int (*cmp)(const void*,const void*,void*), void* arg);
  446. #endif // __sti__vec_h__