Skip to content

Instantly share code, notes, and snippets.

@stillwwater
Created February 21, 2025 18:26
Show Gist options
  • Save stillwwater/46240dcf0b4925aedb9943f29b0d3e03 to your computer and use it in GitHub Desktop.
Save stillwwater/46240dcf0b4925aedb9943f29b0d3e03 to your computer and use it in GitHub Desktop.
#include "array.h"
// arenasize:
// virtual address size of the backing arenai
void *
make_array(usize arenasize, usize elementsize, char *name)
{
struct arena *arena = make_arena(arenasize, name);
struct array_header *array = arena_alloc_align(arena, 16, sizeof *array);
array->arena = arena;
array->count = 0;
array->elementsize = elementsize;
return array->data;
}
void
free_array(void *data)
{
struct array_header *array = array_header_ptr(data);
free_arena(array->arena);
}
void *
_array_alloc(void *data, usize count)
{
struct array_header *array = array_header_ptr(data);
// alignment is 1 because elementsize will ensure elements are correctly
// packed
void *slot = arena_alloc_align(array->arena, 1, array->elementsize * count);
array->count += count;
return slot;
}
void
_array_appendn(void *data, void *values, usize elementsize, usize n)
{
struct array_header *array = array_header_ptr(data);
assert(elementsize == array->elementsize);
void *slot = _array_alloc(data, n);
memcpy(slot, values, elementsize * n);
}
void
_array_remove(void *data, usize index)
{
struct array_header *array = array_header_ptr(data);
assert(array->elementsize);
assert(index < array->count);
// swap slot with the last element
void *end = array->data + array->elementsize * (array->count - 1);
void *slot = array->data + array->elementsize * index;
memcpy(slot, end, array->elementsize);
array->arena->allocated -= array->elementsize;
array->count -= 1;
}
struct array_header {
// 16 bytes for alignment
struct arena *arena;
uint32 elementsize;
uint32 count;
char data[];
};
#define array_header_ptr(data) ((struct array_header *)((void *)data - sizeof(struct array_header)))
#define array_alloc(data, count) _array_alloc(data, count)
#define array_append(data, value) _array_appendn(data, &value, sizeof(value), 1)
#define array_appendn(data, values, n) _array_appendn(data, values, sizeof(*values), n)
#define array_remove(data, index) _array_remove(data, index)
#define array_count(data) (array_header_ptr(data)->count)
void *make_array(usize arenasize, usize elementsize, char *name);
void free_array(void *data);
void *_array_alloc(void *data, usize count);
void _array_append(void *data, void *value, usize elementsize);
void _array_appendn(void *data, void *value, usize elementsize, usize n);
void _array_remove(void *data, usize index);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment