Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

317 wiersze
6.9 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. Array_List<type> clone() {
  104. Array_List<type> ret;
  105. ret.length = length;
  106. ret.count = count;
  107. ret.data = (type*)malloc(length * sizeof(type));
  108. // TODO(Felix): Maybe use memcpy here
  109. for (u32 i = 0; i < count; ++i) {
  110. ret.data[i] = data[i];
  111. }
  112. return ret;
  113. }
  114. void copy_values_from(Array_List<type> other) {
  115. // clear the array
  116. count = 0;
  117. // make sure we have allocated enough
  118. reserve(other.count);
  119. // copy stuff
  120. count = other.count;
  121. memcpy(data, other.data, sizeof(type) * other.count);
  122. }
  123. type* begin() {
  124. return data;
  125. }
  126. type* end() {
  127. return data+(count);
  128. }
  129. void remove_index(u32 index) {
  130. data[index] = data[--count];
  131. }
  132. void append(type element) {
  133. if (count == length) {
  134. length *= 2;
  135. data = (type*)realloc(data, length * sizeof(type));
  136. }
  137. data[count] = element;
  138. count++;
  139. }
  140. void reserve(u32 amount) {
  141. if (count+amount >= (u32)length) {
  142. length *= 2;
  143. data = (type*)realloc(data, length * sizeof(type));
  144. }
  145. }
  146. type& operator[](u32 index) {
  147. return data[index];
  148. }
  149. void _merge(u32 start, u32 mid, u32 end) {
  150. u32 start2 = mid + 1;
  151. /* If the direct merge is already sorted */
  152. if ((size_t)data[mid] <= (size_t)data[start2]) {
  153. return;
  154. }
  155. /* Two pointers to maintain start of both arrays to merge */
  156. while (start <= mid && start2 <= end) {
  157. if ((size_t)data[start] <= (size_t)data[start2]) {
  158. start++;
  159. }
  160. else {
  161. type value = data[start2];
  162. u32 index = start2;
  163. /* Shift all the elements between element 1; element 2, right by 1. */
  164. while (index != start) {
  165. data[index] = data[index - 1];
  166. index--;
  167. }
  168. data[start] = value;
  169. /* Update all the pointers */
  170. start++;
  171. mid++;
  172. start2++;
  173. }
  174. }
  175. }
  176. void sort(s32 left=-1, s32 right=-1) {
  177. if (left == -1) {
  178. if (count == 0)
  179. return;
  180. sort(0, count - 1);
  181. return;
  182. } else if (left == right) {
  183. return;
  184. }
  185. u32 middle = left + (right-left) / 2;
  186. sort(left, middle);
  187. sort(middle+1, right);
  188. _merge(left, middle, right);
  189. }
  190. s32 sorted_find(type elem, s32 left=-1, s32 right=-1) {
  191. if (left == -1) {
  192. return sorted_find(elem, 0, count - 1);
  193. } else if (left == right) {
  194. if ((size_t)data[left] == (size_t)elem)
  195. return left;
  196. return -1;
  197. } else if (right < left)
  198. return -1;
  199. u32 middle = left + (right-left) / 2;
  200. if ((size_t)data[middle] < (size_t)elem)
  201. return sorted_find(elem, middle+1, right);
  202. if ((size_t)data[middle] > (size_t)elem)
  203. return sorted_find(elem, left, middle-1);
  204. return middle;
  205. }
  206. };
  207. template <typename type>
  208. struct Auto_Array_List : public Array_List<type> {
  209. Auto_Array_List(u32 length) {
  210. this->alloc(length);
  211. }
  212. Auto_Array_List() {
  213. this->alloc(16);
  214. }
  215. Auto_Array_List(std::initializer_list<type> l) {
  216. this->alloc(l.size());
  217. for (type e : l) {
  218. this->append(e);
  219. }
  220. }
  221. ~Auto_Array_List() {
  222. free(this->data);
  223. this->data = nullptr;
  224. }
  225. };
  226. template <typename type>
  227. struct Queue {
  228. Array_List<type> arr_list;
  229. u32 next_index;
  230. void alloc(u32 initial_capacity = 16) {
  231. next_index = 0;
  232. arr_list.alloc(initial_capacity);
  233. }
  234. void dealloc() {
  235. arr_list.dealloc();
  236. }
  237. void push_back(type e) {
  238. arr_list.append(e);
  239. }
  240. type get_next() {
  241. #ifdef FTB_INTERNAL_DEBUG
  242. if (next_index >= arr_list.length) {
  243. fprintf(stderr, "ERROR: Out of bounds access in queue\n");
  244. }
  245. #endif
  246. return arr_list.data[next_index++];
  247. }
  248. bool is_empty() {
  249. return next_index == arr_list.count;
  250. }
  251. int get_count() {
  252. return arr_list.count - next_index;
  253. }
  254. void clear() {
  255. next_index = 0;
  256. arr_list.clear();
  257. }
  258. };