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.
 
 
 
 

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