Kohi Game Engine
darray.h
Go to the documentation of this file.
1 
20 #pragma once
21 
22 #include "defines.h"
23 
24 typedef struct darray_header {
30 
39 KAPI void* _darray_create(u64 length, u64 stride, struct frame_allocator_int* frame_allocator);
40 
48 KAPI void* _darray_resize(void* array);
49 
57 KAPI void* _darray_push(void* array, const void* value_ptr);
58 
68 KAPI void* _darray_insert_at(void* array, u64 index, void* value_ptr);
69 
79 KAPI void* _darray_duplicate(u64 stride, void* array);
80 
82 #define DARRAY_DEFAULT_CAPACITY 1
83 
85 #define DARRAY_RESIZE_FACTOR 2
86 
93 #define darray_create(type) \
94  (type*)_darray_create(DARRAY_DEFAULT_CAPACITY, sizeof(type), 0)
95 
103 #define darray_create_with_allocator(type, allocator) \
104  _darray_create(DARRAY_DEFAULT_CAPACITY, sizeof(type), allocator)
105 
113 #define darray_reserve(type, capacity) \
114  _darray_create(capacity, sizeof(type), 0)
115 
124 #define darray_reserve_with_allocator(type, capacity, allocator) \
125  _darray_create(capacity, sizeof(type), allocator)
126 
131 KAPI void darray_destroy(void* array);
132 
139 #define darray_push(array, value) \
140  { \
141  typeof(value) __k_temp_dingus_value__ = value; \
142  array = _darray_push(array, &__k_temp_dingus_value__); \
143  }
144 // NOTE: could use __auto_type for temp above, but intellisense
145 // for VSCode flags it as an unknown type. typeof() seems to
146 // work just fine, though. Both are GNU extensions.
147 
153 KAPI void darray_pop(void* array, void* dest);
154 
163 #define darray_insert_at(array, index, value) \
164  { \
165  typeof(value) __k_temp_dingus_value__ = value; \
166  array = _darray_insert_at(array, index, &__k_temp_dingus_value__); \
167  }
168 
177 KAPI void* darray_pop_at(void* array, u64 index, void* dest);
178 
183 KAPI void darray_clear(void* array);
184 
190 KAPI u64 darray_capacity(void* array);
191 
197 KAPI u64 darray_length(void* array);
198 
204 KAPI u64 darray_stride(void* array);
205 
213 KAPI void darray_length_set(void* array, u64 value);
214 
224 #define darray_duplicate(type, array) (type*)_darray_duplicate(sizeof(type), array)
225 
230 KAPI void _kdarray_init(u32 length, u32 stride, u32 capacity, struct frame_allocator_int* allocator, u32* out_length, u32* out_stride, u32* out_capacity, void** block, struct frame_allocator_int** out_allocator);
231 KAPI void _kdarray_free(u32* length, u32* capacity, u32* stride, void** block, struct frame_allocator_int** out_allocator);
232 KAPI void _kdarray_ensure_size(u32 required_length, u32 stride, u32* out_capacity, struct frame_allocator_int* allocator, void** block, void** base_block);
233 
234 typedef struct darray_base {
239  void* p_data;
241 
242 typedef struct darray_iterator {
246  b8 (*end)(const struct darray_iterator* it);
247  void* (*value)(const struct darray_iterator* it);
248  void (*next)(struct darray_iterator* it);
249  void (*prev)(struct darray_iterator* it);
251 
258 
259 #define DARRAY_TYPE_NAMED(type, name) \
260  typedef struct darray_##name { \
261  darray_base base; \
262  type* data; \
263  darray_iterator (*begin)(darray_base * arr); \
264  darray_iterator (*rbegin)(darray_base * arr); \
265  } darray_##name; \
266  \
267  KINLINE darray_##name darray_##name##_reserve_with_allocator(u32 capacity, struct frame_allocator_int* allocator) { \
268  darray_##name arr; \
269  _kdarray_init(0, sizeof(type), capacity, allocator, &arr.base.length, &arr.base.stride, &arr.base.capacity, (void**)&arr.data, &arr.base.allocator); \
270  arr.base.p_data = arr.data; \
271  arr.begin = darray_iterator_begin; \
272  arr.rbegin = darray_iterator_rbegin; \
273  return arr; \
274  } \
275  \
276  KINLINE darray_##name darray_##name##_create_with_allocator(struct frame_allocator_int* allocator) { \
277  darray_##name arr; \
278  _kdarray_init(0, sizeof(type), DARRAY_DEFAULT_CAPACITY, allocator, &arr.base.length, &arr.base.stride, &arr.base.capacity, (void**)&arr.data, &arr.base.allocator); \
279  arr.base.p_data = arr.data; \
280  arr.begin = darray_iterator_begin; \
281  arr.rbegin = darray_iterator_rbegin; \
282  return arr; \
283  } \
284  \
285  KINLINE darray_##name darray_##name##_reserve(u32 capacity) { \
286  darray_##name arr; \
287  _kdarray_init(0, sizeof(type), capacity, 0, &arr.base.length, &arr.base.stride, &arr.base.capacity, (void**)&arr.data, &arr.base.allocator); \
288  arr.base.p_data = arr.data; \
289  arr.begin = darray_iterator_begin; \
290  arr.rbegin = darray_iterator_rbegin; \
291  return arr; \
292  } \
293  \
294  KINLINE darray_##name darray_##name##_create(void) { \
295  darray_##name arr; \
296  _kdarray_init(0, sizeof(type), DARRAY_DEFAULT_CAPACITY, 0, &arr.base.length, &arr.base.stride, &arr.base.capacity, (void**)&arr.data, &arr.base.allocator); \
297  arr.base.p_data = arr.data; \
298  arr.begin = darray_iterator_begin; \
299  arr.rbegin = darray_iterator_rbegin; \
300  return arr; \
301  } \
302  \
303  KINLINE darray_##name* darray_##name##_push(darray_##name* arr, type data) { \
304  _kdarray_ensure_size(arr->base.length + 1, arr->base.stride, &arr->base.capacity, arr->base.allocator, (void**)&arr->data, (void**)&arr->base.p_data); \
305  arr->data[arr->base.length] = data; \
306  arr->base.length++; \
307  return arr; \
308  } \
309  \
310  KINLINE b8 darray_##name##_pop(darray_##name* arr, type* out_value) { \
311  if (arr->base.length < 1) { \
312  return false; \
313  } \
314  *out_value = arr->data[arr->base.length - 1]; \
315  arr->base.length--; \
316  return true; \
317  } \
318  \
319  KINLINE b8 darray_##name##_pop_at(darray_##name* arr, u32 index, type* out_value) { \
320  if (index >= arr->base.length) { \
321  return false; \
322  } \
323  *out_value = arr->data[index]; \
324  for (u32 i = index; i < arr->base.length; ++i) { \
325  arr->data[i] = arr->data[i + 1]; \
326  } \
327  arr->base.length--; \
328  return true; \
329  } \
330  \
331  KINLINE b8 darray_##name##_insert_at(darray_##name* arr, u32 index, type data) { \
332  if (index > arr->base.length) { \
333  return false; \
334  } \
335  _kdarray_ensure_size(arr->base.length + 1, arr->base.stride, &arr->base.capacity, arr->base.allocator, (void**)&arr->data, (void**)&arr->base.p_data); \
336  arr->base.length++; \
337  for (u32 i = arr->base.length; i > index; --i) { \
338  arr->data[i] = arr->data[i - 1]; \
339  } \
340  arr->data[index] = data; \
341  return true; \
342  } \
343  \
344  KINLINE darray_##name* darray_##name##_clear(darray_##name* arr) { \
345  arr->base.length = 0; \
346  return arr; \
347  } \
348  \
349  KINLINE void darray_##name##_destroy(darray_##name* arr) { \
350  _kdarray_free(&arr->base.length, &arr->base.capacity, &arr->base.stride, (void**)&arr->data, &arr->base.allocator); \
351  arr->begin = 0; \
352  arr->rbegin = 0; \
353  }
354 
355 // Create an array type of the given type. For advanced types or pointers, use ARRAY_TYPE_NAMED directly.
356 #define DARRAY_TYPE(type) DARRAY_TYPE_NAMED(type, type)
357 
358 // Create array types for well-known types
359 
361 
366 
371 
374 
375 // Create array types for well-known "advanced" types, such as strings.
376 DARRAY_TYPE_NAMED(const char*, string);
KAPI void _kdarray_free(u32 *length, u32 *capacity, u32 *stride, void **block, struct frame_allocator_int **out_allocator)
struct darray_iterator darray_iterator
KAPI void darray_length_set(void *array, u64 value)
Sets the length of the given array. This ensures the array has the required capacity to be able to se...
KAPI void * darray_pop_at(void *array, u64 index, void *dest)
Pops an entry out of the array at the given index and places it into dest (if provided)....
KAPI void darray_pop(void *array, void *dest)
Pops an entry out of the array and places it into dest (if provided).
KAPI u64 darray_capacity(void *array)
Gets the given array's capacity.
KAPI void * _darray_insert_at(void *array, u64 index, void *value_ptr)
Inserts a copy of the given value into the supplied array at the given index. Triggers an array resiz...
KAPI void darray_iterator_next(darray_iterator *it)
KAPI void * _darray_duplicate(u64 stride, void *array)
Duplicates the given array to a completely fresh copy, including header data as well as actual data c...
KAPI void darray_destroy(void *array)
Destroys the provided array, freeing any memory allocated by it.
KAPI void * _darray_resize(void *array)
Resizes the given array using internal resizing amounts. Causes a new allocation.
struct darray_header darray_header
KAPI void _kdarray_ensure_size(u32 required_length, u32 stride, u32 *out_capacity, struct frame_allocator_int *allocator, void **block, void **base_block)
KAPI u64 darray_stride(void *array)
Gets the stride (element size) of the given array.
KAPI void * darray_iterator_value(const darray_iterator *it)
KAPI b8 darray_iterator_end(const darray_iterator *it)
KAPI darray_iterator darray_iterator_rbegin(darray_base *arr)
KAPI void darray_clear(void *array)
Clears all entries from the array. Does not release any internally-allocated memory.
KAPI void darray_iterator_prev(darray_iterator *it)
KAPI darray_iterator darray_iterator_begin(darray_base *arr)
KAPI void * _darray_create(u64 length, u64 stride, struct frame_allocator_int *frame_allocator)
Creates a new darray of the given length and stride. Note that this performs a dynamic memory allocat...
struct darray_base darray_base
KAPI u64 darray_length(void *array)
Gets the length (number of elements) in the given array.
KAPI void _kdarray_init(u32 length, u32 stride, u32 capacity, struct frame_allocator_int *allocator, u32 *out_length, u32 *out_stride, u32 *out_capacity, void **block, struct frame_allocator_int **out_allocator)
#define DARRAY_TYPE(type)
Definition: darray.h:356
#define DARRAY_TYPE_NAMED(type, name)
Definition: darray.h:259
KAPI void * _darray_push(void *array, const void *value_ptr)
Pushes a new entry to the given array. Resizes if necessary.
This file contains global type definitions which are used throughout the entire engine and applicatio...
#define KAPI
Import/export qualifier.
Definition: defines.h:205
unsigned int u32
Unsigned 32-bit integer.
Definition: defines.h:25
signed char i8
Signed 8-bit integer.
Definition: defines.h:33
_Bool b8
8-bit boolean type
Definition: defines.h:58
float f32
32-bit floating point number
Definition: defines.h:47
double f64
64-bit floating point number
Definition: defines.h:50
signed int i32
Signed 32-bit integer.
Definition: defines.h:39
unsigned short u16
Unsigned 16-bit integer.
Definition: defines.h:22
signed short i16
Signed 16-bit integer.
Definition: defines.h:36
unsigned long long u64
Unsigned 64-bit integer.
Definition: defines.h:28
signed long long i64
Signed 64-bit integer.
Definition: defines.h:42
unsigned char u8
Unsigned 8-bit integer.
Definition: defines.h:19
Definition: darray.h:234
u32 capacity
Definition: darray.h:237
u32 length
Definition: darray.h:235
void * p_data
Definition: darray.h:239
u32 stride
Definition: darray.h:236
struct frame_allocator_int * allocator
Definition: darray.h:238
Definition: darray.h:24
u64 capacity
Definition: darray.h:25
u64 length
Definition: darray.h:26
struct frame_allocator_int * allocator
Definition: darray.h:28
u64 stride
Definition: darray.h:27
Definition: darray.h:242
darray_base * arr
Definition: darray.h:243
i32 dir
Definition: darray.h:245
i32 pos
Definition: darray.h:244
void(* next)(struct darray_iterator *it)
Definition: darray.h:248
b8(* end)(const struct darray_iterator *it)
Definition: darray.h:246
void(* prev)(struct darray_iterator *it)
Definition: darray.h:249
Definition: kmemory.h:21