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.
 
 
 
 

186 rivejä
4.2 KiB

  1. #pragma once
  2. #include <stdlib.h>
  3. #include <initializer_list>
  4. #include "types.hpp"
  5. #include "macros.hpp"
  6. template <typename type>
  7. struct Array_List {
  8. type* data;
  9. u32 length;
  10. u32 count;
  11. void alloc(u32 initial_capacity = 16) {
  12. data = (type*)malloc(initial_capacity * sizeof(type));
  13. count = 0;
  14. length = initial_capacity;
  15. }
  16. void alloc_from(std::initializer_list<type> l) {
  17. length = max(l.size(), 1); // alloc at least one
  18. data = (type*)malloc(length * sizeof(type));
  19. count = 0;
  20. for (type t : l) {
  21. data[count++] = t;
  22. }
  23. }
  24. void extend(std::initializer_list<type> l) {
  25. reserve(l.size());
  26. for (type e : l) {
  27. append(e);
  28. }
  29. }
  30. void dealloc() {
  31. free(data);
  32. data = nullptr;
  33. }
  34. void clear() {
  35. count = 0;
  36. }
  37. Array_List<type> clone() {
  38. Array_List<type> ret;
  39. ret.length = length;
  40. ret.count = count;
  41. ret.data = (type*)malloc(length * sizeof(type));
  42. for (u32 i = 0; i < count; ++i) {
  43. ret.data[i] = data[i];
  44. }
  45. return ret;
  46. }
  47. type* begin() {
  48. return data;
  49. }
  50. type* end() {
  51. return data+(count);
  52. }
  53. void remove_index(u32 index) {
  54. data[index] = data[--count];
  55. }
  56. void append(type element) {
  57. if (count == length) {
  58. length *= 2;
  59. data = (type*)realloc(data, length * sizeof(type));
  60. }
  61. data[count] = element;
  62. count++;
  63. }
  64. void reserve(u32 amount) {
  65. if (count+amount >= (u32)length) {
  66. length *= 2;
  67. data = (type*)realloc(data, length * sizeof(type));
  68. }
  69. }
  70. type& operator[](u32 index) {
  71. return data[index];
  72. }
  73. void _merge(u32 start, u32 mid, u32 end) {
  74. u32 start2 = mid + 1;
  75. /* If the direct merge is already sorted */
  76. if ((size_t)data[mid] <= (size_t)data[start2]) {
  77. return;
  78. }
  79. /* Two pointers to maintain start of both arrays to merge */
  80. while (start <= mid && start2 <= end) {
  81. if ((size_t)data[start] <= (size_t)data[start2]) {
  82. start++;
  83. }
  84. else {
  85. type value = data[start2];
  86. u32 index = start2;
  87. /* Shift all the elements between element 1; element 2, right by 1. */
  88. while (index != start) {
  89. data[index] = data[index - 1];
  90. index--;
  91. }
  92. data[start] = value;
  93. /* Update all the pointers */
  94. start++;
  95. mid++;
  96. start2++;
  97. }
  98. }
  99. }
  100. void sort(s32 left=-1, s32 right=-1) {
  101. if (left == -1) {
  102. if (count == 0)
  103. return;
  104. sort(0, count - 1);
  105. return;
  106. } else if (left == right) {
  107. return;
  108. }
  109. u32 middle = left + (right-left) / 2;
  110. sort(left, middle);
  111. sort(middle+1, right);
  112. _merge(left, middle, right);
  113. }
  114. u32 sorted_find(type elem, s32 left=-1, s32 right=-1) {
  115. if (left == -1) {
  116. return sorted_find(elem, 0, count - 1);
  117. } else if (left == right) {
  118. if ((size_t)data[left] == (size_t)elem)
  119. return left;
  120. return -1;
  121. } else if (right < left)
  122. return -1;
  123. u32 middle = left + (right-left) / 2;
  124. if ((size_t)data[middle] < (size_t)elem)
  125. return sorted_find(elem, middle+1, right);
  126. if ((size_t)data[middle] > (size_t)elem)
  127. return sorted_find(elem, left, middle-1);
  128. return middle;
  129. }
  130. };
  131. template <typename type>
  132. struct Auto_Array_List : public Array_List<type> {
  133. Auto_Array_List(u32 length) {
  134. this->alloc(length);
  135. }
  136. Auto_Array_List() {
  137. this->alloc(16);
  138. }
  139. Auto_Array_List(std::initializer_list<type> l) {
  140. this->alloc(l.size());
  141. for (type e : l) {
  142. this->append(e);
  143. }
  144. }
  145. ~Auto_Array_List() {
  146. free(this->data);
  147. this->data = nullptr;
  148. }
  149. };