| 128 | |
| 129 | template <typename T> |
| 130 | struct array_t { |
| 131 | T *data; |
| 132 | int32_t count; |
| 133 | int32_t capacity; |
| 134 | |
| 135 | int32_t add (const T &item) { if (count+1 > capacity) { resize(capacity * 2 < 4 ? 4 : capacity * 2); } data[count] = item; count += 1; return count - 1; } |
| 136 | void add_range (const T *list, int32_t num) { if (count+num > capacity) { resize(capacity * 2 < count+num ? count+num : capacity * 2); } ARRAY_MEMCPY(&data[count], list, sizeof(T)*num); count += num; } |
| 137 | void insert (int32_t at, const T &item); |
| 138 | void resize (int32_t to_capacity); |
| 139 | void trim () { resize(count); } |
| 140 | void remove (int32_t at); |
| 141 | void pop () { remove(count - 1); } |
| 142 | void clear () { count = 0; } |
| 143 | T &last () const { return data[count - 1]; } |
| 144 | inline void set (int32_t id, const T &val) { data[id] = val; } |
| 145 | inline T &get (int32_t id) const { return data[id]; } |
| 146 | inline T &operator[] (int32_t id) const { return data[id]; } |
| 147 | void reverse (); |
| 148 | array_t<T> copy () const; |
| 149 | void each (void (*e)(T &)) { for (int32_t i=0; i<count; i++) e(data[i]); } |
| 150 | void each (void (*e)(const T &)) const { for (int32_t i=0; i<count; i++) e(data[i]); } |
| 151 | void each (void (*e)(void *)) { for (int32_t i=0; i<count; i++) e(data[i]); } |
| 152 | template <typename U> |
| 153 | void each_with (U *with, void (*e)(U*, const T &)) const { for (int32_t i=0; i<count; i++) e(with, data[i]); } |
| 154 | template <typename U> |
| 155 | U each_with (void (*e)(U *, const T &)) const { U result = {}; for (int32_t i = 0; i < count; i++) e(&result, data[i]); } |
| 156 | template <typename U> |
| 157 | U each_sum (U (*e)(const T &)) const { U result = 0; for (int32_t i = 0; i < count; i++) result += e(data[i]); return result; } |
| 158 | template <typename U> |
| 159 | array_t<U> each_new (U (*e)(const T &)) const { array_t<U> result = {}; result.resize(count); for (int32_t i=0; i<count; i++) result.add(e(data[i])); return result; } |
| 160 | void free (); |
| 161 | |
| 162 | static array_t<T> make (int32_t capacity) { array_t<T> result = {}; result.resize(capacity); return result; } |
| 163 | static array_t<T> make_fill(int32_t capacity, const T ©_from) { array_t<T> result = {}; result.resize(capacity); result.count = capacity; for(int32_t i=0;i<capacity;i+=1) result.data[i]=copy_from; return result; } |
| 164 | static array_t<T> make_from(T *use_memory, int32_t count) { return {use_memory, count, count}; } |
| 165 | |
| 166 | ////////////////////////////////////// |
| 167 | // Linear search methods |
| 168 | |
| 169 | int32_t index_of (const T &item) const { for (int32_t i = 0; i < count; i++) if (memcmp(&data[i], &item, sizeof(T)) == 0) return i; return -1; } |
| 170 | template <typename _T, typename D> |
| 171 | int32_t index_where(const D _T::*key, const D &item) const { const size_t offset = (size_t)&((_T*)0->*key); for (int32_t i = 0; i < count; i++) if (memcmp(((uint8_t *)&data[i]) + offset, &item, sizeof(D)) == 0) return i; return -1; } |
| 172 | int32_t index_where(bool (*c)(const T &item, void *user_data), void *user_data) const { for (int32_t i=0; i<count; i++) if (c(data[i], user_data)) return i; return -1;} |
| 173 | int32_t index_where(bool (*c)(const T &item)) const { for (int32_t i=0; i<count; i++) if (c(data[i])) return i; return -1;} |
| 174 | int32_t index_best_small(int32_t (*c)(const T &item)) const { int32_t best = 0x7fffffff; int32_t result = -1; for (int32_t i=0; i<count; i++) { int32_t r = c(data[i]); if (r < best) { best = r; result = i;} } return result; } |
| 175 | int32_t index_best_large(int32_t (*c)(const T &item)) const { int32_t best = 0x80000000; int32_t result = -1; for (int32_t i=0; i<count; i++) { int32_t r = c(data[i]); if (r > best) { best = r; result = i;} } return result;} |
| 176 | template <typename U> |
| 177 | int32_t index_best_small_with(U with, int32_t (*c)(U, const T &item)) const { int32_t best = 0x7fffffff; int32_t result = -1; for (int32_t i=0; i<count; i++) { int32_t r = c(with, data[i]); if (r < best) { best = r; result = i;} } return result; } |
| 178 | template <typename U> |
| 179 | int32_t index_best_large_with(U with, int32_t (*c)(U, const T &item)) const { int32_t best = -0x80000000; int32_t result = -1; for (int32_t i=0; i<count; i++) { int32_t r = c(with, data[i]); if (r > best) { best = r; result = i;} } return result; } |
| 180 | |
| 181 | ////////////////////////////////////// |
| 182 | // Binary search methods |
| 183 | |
| 184 | int32_t binary_search(const T &item) const; |
| 185 | |
| 186 | // Extra template parameters mean this needs completely defined right here. |
| 187 | // Does not work on pointers. |
nothing calls this directly
no outgoing calls
no test coverage detected