Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

168 linhas
3.9 KiB

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