From a95f1ee641c44e2cce57551ffe652286bff418d6 Mon Sep 17 00:00:00 2001 From: Maciej Samborski Date: Mon, 25 Nov 2024 16:14:18 +0100 Subject: [PATCH] Initial commit --- cgc.h | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 cgc.h diff --git a/cgc.h b/cgc.h new file mode 100644 index 0000000..86ce103 --- /dev/null +++ b/cgc.h @@ -0,0 +1,112 @@ +#ifndef CGC_H_ +#define CGC_H_ + +#include + +#define GC_DEFAULT_CAP 16 + +typedef struct { + void * ptr; + size_t id; +} GCItem; + +typedef struct { + GCItem * items; + size_t size; + size_t capacity; +} GC; + +typedef size_t GCIndex; + +GC gcInit(void); +void gcDeinit(GC gc); +void gcGrowBuffer(GC * gc); +GCIndex gcAddItem(GC * gc, void * ptr); +void * gcAlloc(GC * gc, size_t n); +void gcUpdateItem(GC * gc, GCIndex id, void * ptr); +void * gcGetPtrAt(GC gc, GCIndex id); + +#ifdef CGC_IMPLEMENTATION + +GC gcInit() +{ + void * items = calloc(GC_DEFAULT_CAP, sizeof(GCItem)); + if (items == NULL) { + fprintf(stderr, "ERROR: Failed to allocate GC!\n"); + exit(1); + } + + return (GC) { + .items = items, + .size = 0, + .capacity = GC_DEFAULT_CAP, + }; +} + +void gcDeinit(GC gc) +{ + for (size_t i = 0; i < gc.size; ++i) + free(gc.items[i].ptr); + + free(gc.items); +} + +void gcGrowBuffer(GC * gc) +{ + if (gc->items == NULL) + { + fprintf(stderr, "ERROR: GC is not initialized!\n"); + exit(1); + } + + size_t newCap = (size_t) (gc->capacity * 1.5); + + void * items = calloc(newCap, sizeof(GCItem)); + if (items == NULL) { + fprintf(stderr, "ERROR: Failed to allocate GC!\n"); + exit(1); + } + memcpy(items, gc->items, gc->capacity * sizeof(GCItem)); + free(gc->items); + gc->items = items; + gc->capacity = newCap; +} + +GCIndex gcAddItem(GC * gc, void * ptr) +{ + if (gc->size >= gc->capacity) + gcGrowBuffer(gc); + + gc->size += 1; + gc->items[gc->size - 1] = (GCItem) { + .id = gc->size - 1, + .ptr = ptr, + }; + + return gc->size - 1; +} + +void * gcAlloc(GC * gc, size_t n) +{ + void * ptr = calloc(1, n); + if (ptr == NULL) return NULL; + + gcAddItem(gc, ptr); + + return ptr; +} + +void gcUpdateItem(GC * gc, GCIndex id, void * ptr) +{ + free(gc->items[id].ptr); + gc->items[id].ptr = ptr; +} + +void * gcGetPtrAt(GC gc, GCIndex id) +{ + return gc.items[id].ptr; +} + +#endif // CGC_IMPLEMENTATION + +#endif // CGC_H_