Add typed_list
This commit is contained in:
parent
92f8430454
commit
2095580409
29
src/typed_list.c
Normal file
29
src/typed_list.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "list/typed_list.h"
|
||||||
|
#include "mem_arena.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
list_void *_create_list(Arena *arena, u64 size, u64 count) {
|
||||||
|
list_void *list = (list_void *)_alloc_for_list(arena, sizeof(list_void));
|
||||||
|
if (!list) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->items = (void *)_alloc_for_list(arena, size * count);
|
||||||
|
if (!list->items) {
|
||||||
|
munmap(list, sizeof(list_void));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(list->items, 0, sizeof(size * count));
|
||||||
|
|
||||||
|
list->capacity = count;
|
||||||
|
list->count = 0;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *_alloc_for_list(Arena *arena, u64 size) {
|
||||||
|
return wapp_mem_arena_alloc(arena, size);
|
||||||
|
}
|
79
src/typed_list.h
Normal file
79
src/typed_list.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#ifndef TYPED_LIST_H
|
||||||
|
#define TYPED_LIST_H
|
||||||
|
|
||||||
|
#include "aliases.h"
|
||||||
|
#include "mem_arena.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define BASE_LIST_CAPACITY 1024
|
||||||
|
|
||||||
|
#define CONCAT(A, B) A##B
|
||||||
|
#define LIST_TYPE_NAME(T) CONCAT(list_, T)
|
||||||
|
|
||||||
|
#define MAKE_LIST_TYPE(T) \
|
||||||
|
typedef struct { \
|
||||||
|
T *items; \
|
||||||
|
u64 capacity; \
|
||||||
|
u64 count; \
|
||||||
|
} LIST_TYPE_NAME(T)
|
||||||
|
|
||||||
|
#define list_create(T, ARENA) \
|
||||||
|
(LIST_TYPE_NAME(T) *)_create_list(ARENA, sizeof(T), BASE_LIST_CAPACITY)
|
||||||
|
#define list_create_with_capacity(T, ARENA, CAPACITY) \
|
||||||
|
(LIST_TYPE_NAME(T) *)_create_list(ARENA, sizeof(T), CAPACITY)
|
||||||
|
|
||||||
|
#define _increase_list_capacity(T, ARENA, LP, CAP) \
|
||||||
|
do { \
|
||||||
|
u64 new_capacity = LP->capacity * 2; \
|
||||||
|
T *tmp = _alloc_for_list(ARENA, sizeof(T) * new_capacity); \
|
||||||
|
assert(tmp != NULL && "Failed to increase capacity"); \
|
||||||
|
\
|
||||||
|
memcpy(tmp, LP->items, sizeof(T) * LP->count); \
|
||||||
|
\
|
||||||
|
LP->capacity = new_capacity; \
|
||||||
|
LP->items = tmp; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define list_append(T, ARENA, LP, ITEM) \
|
||||||
|
do { \
|
||||||
|
if (LP->count + 1 >= LP->capacity) { \
|
||||||
|
_increase_list_capacity(T, ARENA, LP, LP->capacity * 2); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
LP->items[(LP->count)++] = ITEM; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define list_remove(LP, IDX) \
|
||||||
|
do { \
|
||||||
|
LP->items[IDX] = LP->items[(LP->count)--]; \
|
||||||
|
} while (0)
|
||||||
|
#define list_pop(LP) (LP->count -= 1)
|
||||||
|
|
||||||
|
#define list_set(LP, IDX, ITEM) LP->items[IDX] = ITEM
|
||||||
|
#define list_get(LP, IDX) LP->items[IDX]
|
||||||
|
|
||||||
|
#define list_merge(T, ARENA, DST, LP1, LP2) \
|
||||||
|
do { \
|
||||||
|
u64 new_count = LP1->count + LP2->count; \
|
||||||
|
u64 capacity = \
|
||||||
|
new_count < BASE_LIST_CAPACITY ? BASE_LIST_CAPACITY : new_count * 2; \
|
||||||
|
\
|
||||||
|
DST = (LIST_TYPE_NAME(T) *)_create_list(ARENA, new_count, capacity); \
|
||||||
|
assert(DST != NULL && "Failed to allocate new list"); \
|
||||||
|
\
|
||||||
|
u64 lp1_copy_size = sizeof(T) * LP1->count; \
|
||||||
|
u64 lp2_copy_size = sizeof(T) * LP2->count; \
|
||||||
|
memcpy(DST->items, LP1->items, lp1_copy_size); \
|
||||||
|
T *dst = &(DST->items[LP1->count]); \
|
||||||
|
memcpy(dst, LP2->items, lp2_copy_size); \
|
||||||
|
DST->capacity = capacity; \
|
||||||
|
DST->count = new_count; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
MAKE_LIST_TYPE(void);
|
||||||
|
|
||||||
|
list_void *_create_list(Arena *arena, u64 size, u64 count);
|
||||||
|
void *_alloc_for_list(Arena *arena, u64 size);
|
||||||
|
|
||||||
|
#endif // !TYPED_LIST_H
|
Loading…
Reference in New Issue
Block a user