diff options
Diffstat (limited to 'Array.c')
| -rw-r--r-- | Array.c | 80 |
1 files changed, 80 insertions, 0 deletions
@@ -0,0 +1,80 @@ +#include "Array.h" +#include "Types.h" +#include <stdlib.h> +#include <string.h> + +struct ArrayMeta { + BumpArena b; + usize element_size; + usize count; + usize length; +}; + +static inline struct ArrayMeta* +Array_metadata(void* arr) { + return arr - sizeof(struct ArrayMeta); +} + +typedef void* Array; + +Array +Array_new(BumpArena b, usize element_size, usize length) { + if (NULL == b) + return NULL; + + struct ArrayMeta am = { + .b = b, + .element_size = element_size, + .count = 0, + .length = length, + }; + + void* start = Balloc(b, sizeof(am) + element_size * length); + memcpy(start, &am, sizeof(am)); + return start + sizeof(am); +} + +usize +Array_length(Array arr) { + if (NULL == arr) + return 0; + return Array_metadata(arr)->length; +} + +usize +Array_count(Array arr) { + if (NULL == arr) + return 0; + return Array_metadata(arr)->count; +} + +Result +Array_push(Array arr, void *value) { + if (NULL == arr) + return R_Uninitialized; + + struct ArrayMeta *am = Array_metadata(arr); + + if (am->count >= am->length) { + if (!Bresizeable(am->b, arr)) + abort(); + Bresize(am->b, sizeof(*am) + am->element_size * (am->length <<= 2)); + } + + memcpy(arr + am->count++ * am->element_size, value, am->element_size); + + return R_Ok; +} + +void* +Array_pop(Array arr) { + if (NULL == arr) + return NULL; + + struct ArrayMeta *am = Array_metadata(arr); + + if (am->count == 0) + return NULL; + + return arr + am->element_size * --am->count; +} |
