Initial commit
This commit is contained in:
commit
a95f1ee641
|
@ -0,0 +1,112 @@
|
||||||
|
#ifndef CGC_H_
|
||||||
|
#define CGC_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#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_
|
Loading…
Reference in New Issue