diff --git a/include/list/typed_list.h b/include/list/typed_list.h new file mode 100644 index 0000000..f65a94e --- /dev/null +++ b/include/list/typed_list.h @@ -0,0 +1,60 @@ +#ifndef TYPED_LIST_H +#define TYPED_LIST_H + +#include "c_cpp_aliases/aliases.h" +#include +#include + +#define BASE_LIST_CAPACITY 1024 + +#define CONCAT(A, B, C) A##B##C +#define LIST_TYPE_NAME(T) CONCAT(list_, T, _t) + +#define MAKE_LIST_TYPE(T) \ + typedef struct { \ + T *items; \ + u64 capacity; \ + u64 count; \ + } LIST_TYPE_NAME(T) + +#define create_list(T) \ + (LIST_TYPE_NAME(T) *)_create_list(sizeof(T), BASE_LIST_CAPACITY) +#define create_list_with_capacity(T, CAPACITY) \ + (LIST_TYPE_NAME(T) *)_create_list(sizeof(T), CAPACITY) + +#define destroy_list(T, LP) \ + do { \ + munmap(LP->items, sizeof(T) * LP->capacity); \ + LP->items = NULL; \ + LP->count = 0; \ + LP->capacity = 0; \ + munmap(LP, sizeof(LIST_TYPE_NAME(T))); \ + } while (0) + +#define append(T, LP, ITEM) \ + do { \ + if (LP->count + 1 >= LP->capacity) { \ + u64 new_capacity = LP->capacity * 2; \ + T *tmp = _alloc_for_list(sizeof(T) * new_capacity); \ + assert(tmp != NULL && "Failed to increase capacity"); \ + \ + memcpy(tmp, LP->items, sizeof(T) * LP->count); \ + \ + i32 deallocated = munmap(LP->items, sizeof(T) * LP->capacity); \ + assert(deallocated == 0 && "Failed to deallocate old memory"); \ + \ + LP->capacity = new_capacity; \ + LP->items = tmp; \ + } \ + \ + LP->items[(LP->count)++] = ITEM; \ + } while (0) + +#define get(LP, IDX) LP->items[IDX] + +MAKE_LIST_TYPE(void); + +list_void_t *_create_list(u64 size, u64 count); +void *_alloc_for_list(u64 size); + +#endif // !TYPED_LIST_H diff --git a/src/list/typed_list.c b/src/list/typed_list.c new file mode 100644 index 0000000..3386f02 --- /dev/null +++ b/src/list/typed_list.c @@ -0,0 +1,26 @@ +#include "list/typed_list.h" +#include +#include + +list_void_t *_create_list(u64 size, u64 count) { + list_void_t *list = (list_void_t *)_alloc_for_list(sizeof(list_void_t)); + if (!list) { + return NULL; + } + + list->items = (void *)_alloc_for_list(size * count); + if (!list->items) { + munmap(list, sizeof(list_void_t)); + return NULL; + } + + list->capacity = count; + list->count = 0; + + return list; +} + +void *_alloc_for_list(u64 size) { + return mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_NORESERVE | MAP_SHARED, -1, 0); +}