You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

337 lines
7.3 KiB

  1. #pragma once
  2. #include <stdlib.h>
  3. #include <initializer_list>
  4. #ifdef FTB_INTERNAL_DEBUG
  5. # include <stdio.h>
  6. #endif
  7. #include "types.hpp"
  8. #include "macros.hpp"
  9. template <typename type>
  10. struct Stack_Array_List {
  11. type* data;
  12. u32 length;
  13. u32 count;
  14. Stack_Array_List(u32 length) {
  15. data = (type*)alloca(length);
  16. #ifdef FTB_INTERNAL_DEBUG
  17. if (data == nullptr) {
  18. fprintf(stderr, "ERROR: alloca did return nullptr \n");
  19. }
  20. #endif
  21. this->length = length;
  22. this->count = 0;
  23. }
  24. static Stack_Array_List<type> create_from(std::initializer_list<type> l) {
  25. Stack_Array_List<type> ret(l.size());
  26. for (type t : l) {
  27. ret.data[ret.count++] = t;
  28. }
  29. return ret;
  30. }
  31. void extend(std::initializer_list<type> l) {
  32. for (type e : l) {
  33. append(e);
  34. }
  35. }
  36. void clear() {
  37. count = 0;
  38. }
  39. type* begin() {
  40. return data;
  41. }
  42. type* end() {
  43. return data+(count);
  44. }
  45. void remove_index(u32 index) {
  46. #ifdef FTB_INTERNAL_DEBUG
  47. if (index >= count)
  48. fprintf(stderr, "ERROR: removing index that is not in use\n");
  49. #endif
  50. data[index] = data[--count];
  51. }
  52. void append(type element) {
  53. #ifdef FTB_INTERNAL_DEBUG
  54. if (count == length) {
  55. fprintf(stderr, "ERROR: Stack_Array_List is full!\n");
  56. }
  57. #endif
  58. data[count] = element;
  59. count++;
  60. }
  61. type& operator[](u32 index) {
  62. return data[index];
  63. }
  64. };
  65. template <typename type>
  66. struct Array_List {
  67. type* data;
  68. u32 length;
  69. u32 count;
  70. void alloc(u32 initial_capacity = 16) {
  71. data = (type*)malloc(initial_capacity * sizeof(type));
  72. count = 0;
  73. length = initial_capacity;
  74. }
  75. static Array_List<type> create_from(std::initializer_list<type> l) {
  76. Array_List<type> ret;
  77. ret.alloc_from(l);
  78. return ret;
  79. }
  80. void alloc_from(std::initializer_list<type> l) {
  81. length = max(l.size(), 1); // alloc at least one
  82. data = (type*)malloc(length * sizeof(type));
  83. count = 0;
  84. // TODO(Felix): Use memcpy here
  85. for (type t : l) {
  86. data[count++] = t;
  87. }
  88. }
  89. void extend(std::initializer_list<type> l) {
  90. reserve(l.size());
  91. // TODO(Felix): Use memcpy here
  92. for (type e : l) {
  93. append(e);
  94. }
  95. }
  96. void dealloc() {
  97. free(data);
  98. data = nullptr;
  99. }
  100. void clear() {
  101. count = 0;
  102. }
  103. bool contains_linear_search(type elem) {
  104. for (u32 i = 0; i < count; ++i) {
  105. if (data[i] == elem)
  106. return true;
  107. }
  108. return false;
  109. }
  110. bool contains_binary_search(type elem) {
  111. return sorted_find(elem) != -1;
  112. }
  113. Array_List<type> clone() {
  114. Array_List<type> ret;
  115. ret.length = length;
  116. ret.count = count;
  117. ret.data = (type*)malloc(length * sizeof(type));
  118. // TODO(Felix): Maybe use memcpy here
  119. for (u32 i = 0; i < count; ++i) {
  120. ret.data[i] = data[i];
  121. }
  122. return ret;
  123. }
  124. void copy_values_from(Array_List<type> other) {
  125. // clear the array
  126. count = 0;
  127. // make sure we have allocated enough
  128. reserve(other.count);
  129. // copy stuff
  130. count = other.count;
  131. memcpy(data, other.data, sizeof(type) * other.count);
  132. }
  133. type* begin() {
  134. return data;
  135. }
  136. type* end() {
  137. return data+(count);
  138. }
  139. void remove_index(u32 index) {
  140. data[index] = data[--count];
  141. }
  142. void append(type element) {
  143. if (count == length) {
  144. length *= 2;
  145. data = (type*)realloc(data, length * sizeof(type));
  146. }
  147. data[count] = element;
  148. count++;
  149. }
  150. void reserve(u32 amount) {
  151. if (count+amount >= (u32)length) {
  152. length *= 2;
  153. data = (type*)realloc(data, length * sizeof(type));
  154. }
  155. }
  156. type& operator[](u32 index) {
  157. return data[index];
  158. }
  159. void _merge(u32 start, u32 mid, u32 end) {
  160. u32 start2 = mid + 1;
  161. /* If the direct merge is already sorted */
  162. if ((size_t)data[mid] <= (size_t)data[start2]) {
  163. return;
  164. }
  165. /* Two pointers to maintain start of both arrays to merge */
  166. while (start <= mid && start2 <= end) {
  167. if ((size_t)data[start] <= (size_t)data[start2]) {
  168. start++;
  169. }
  170. else {
  171. type value = data[start2];
  172. u32 index = start2;
  173. /* Shift all the elements between element 1; element 2, right by 1. */
  174. while (index != start) {
  175. data[index] = data[index - 1];
  176. index--;
  177. }
  178. data[start] = value;
  179. /* Update all the pointers */
  180. start++;
  181. mid++;
  182. start2++;
  183. }
  184. }
  185. }
  186. void sort(s32 left=-1, s32 right=-1) {
  187. if (left == -1) {
  188. if (count == 0)
  189. return;
  190. sort(0, count - 1);
  191. return;
  192. } else if (left == right) {
  193. return;
  194. }
  195. u32 middle = left + (right-left) / 2;
  196. sort(left, middle);
  197. sort(middle+1, right);
  198. _merge(left, middle, right);
  199. }
  200. s32 sorted_find(type elem, s32 left=-1, s32 right=-1) {
  201. if (left == -1) {
  202. return sorted_find(elem, 0, count - 1);
  203. } else if (left == right) {
  204. if ((size_t)data[left] == (size_t)elem)
  205. return left;
  206. return -1;
  207. } else if (right < left)
  208. return -1;
  209. u32 middle = left + (right-left) / 2;
  210. if ((size_t)data[middle] < (size_t)elem)
  211. return sorted_find(elem, middle+1, right);
  212. if ((size_t)data[middle] > (size_t)elem)
  213. return sorted_find(elem, left, middle-1);
  214. return middle;
  215. }
  216. };
  217. template <typename type>
  218. struct Auto_Array_List : public Array_List<type> {
  219. Auto_Array_List(u32 length) {
  220. this->alloc(length);
  221. }
  222. Auto_Array_List() {
  223. this->alloc(16);
  224. }
  225. Auto_Array_List(std::initializer_list<type> l) {
  226. this->alloc(l.size());
  227. for (type e : l) {
  228. this->append(e);
  229. }
  230. }
  231. ~Auto_Array_List() {
  232. free(this->data);
  233. this->data = nullptr;
  234. }
  235. };
  236. template <typename type>
  237. struct Queue {
  238. Array_List<type> arr_list;
  239. u32 next_index;
  240. void alloc(u32 initial_capacity = 16) {
  241. next_index = 0;
  242. arr_list.alloc(initial_capacity);
  243. }
  244. void dealloc() {
  245. arr_list.dealloc();
  246. }
  247. void push_back(type e) {
  248. arr_list.append(e);
  249. }
  250. type get_next() {
  251. #ifdef FTB_INTERNAL_DEBUG
  252. if (next_index >= arr_list.length) {
  253. fprintf(stderr, "ERROR: Out of bounds access in queue\n");
  254. }
  255. #endif
  256. return arr_list.data[next_index++];
  257. }
  258. bool is_empty() {
  259. return next_index == arr_list.count;
  260. }
  261. int get_count() {
  262. return arr_list.count - next_index;
  263. }
  264. bool contains(type elem) {
  265. for (u32 i = next_index; i < arr_list.count; ++i) {
  266. if (arr_list[i] == elem)
  267. return true;
  268. }
  269. return false;
  270. }
  271. void clear() {
  272. next_index = 0;
  273. arr_list.clear();
  274. }
  275. };