Compare commits

..

No commits in common. "gc" and "master" have entirely different histories.
gc ... master

3 changed files with 234 additions and 413 deletions

114
cgc.h
View File

@ -1,114 +0,0 @@
#ifndef CGC_H_
#define CGC_H_
#include <stdio.h>
#include <stdlib.h>
#define GC_DEFAULT_CAP 16
#include <string.h>
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 elemNo, size_t elemSize);
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 = gc->capacity * 2;
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 elemNo, size_t elemSize)
{
void * ptr = calloc(elemNo, elemSize);
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_

377
da.h
View File

@ -5,14 +5,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#define EHAN_IMPLEMENTATION #define EHAN_IMPLEMENTATION
#include "ehan.h" #include "ehan.h"
#define CGC_IMPLEMENTATION
#include "cgc.h"
enum daFields { enum daFields {
SIZE = 0, SIZE = 0,
CAPACITY = 1, CAPACITY = 1,
@ -21,12 +17,12 @@ enum daFields {
}; };
typedef void * dynarr; typedef void * dynarr;
dynarr _daCreate(size_t initCapacity, size_t type, size_t size); GenericReturn _daCreate(size_t initCapacity, size_t type, size_t size);
GenericReturn _daPushLit(dynarr * da, size_t item); GenericReturn _daPushLit(dynarr * da, size_t item);
GenericReturn _daPushFlt(dynarr * da, float item); GenericReturn _daPushFlt(dynarr * da, float item);
GenericReturn _daPushStr(dynarr * da, const char * str); GenericReturn _daPushStr(dynarr * da, const char * str);
dynarr daCopy(dynarr da); GenericReturn daCopy(dynarr da);
dynarr daResize(dynarr da); GenericReturn daResize(dynarr da);
void _daPop(dynarr da, void * element); void _daPop(dynarr da, void * element);
void daPopDiscard(dynarr da); void daPopDiscard(dynarr da);
void daFree(dynarr da); void daFree(dynarr da);
@ -56,57 +52,23 @@ void daBzero(dynarr da);
#define daPop(da, item) _daPop(da, &item) #define daPop(da, item) _daPop(da, &item)
#define daGet(da, index) (da[index]) #define daGet(da, index) (da[index])
#define daAppend(daImpl, value) ({ \ #endif // DA_H_
if (daImpl != NULL) \
{ \
if (daSize(daImpl) >= daCap(daImpl)) \
daImpl = daResize(daImpl); \
\
if (daImpl != NULL) { \
daImpl[daSize(daImpl)] = value; \
*(((size_t *) daImpl) - 3) += 1; \
errno = 0; \
} else { \
errno = 1; \
} \
} else { \
errno = 1; \
} \
})
#ifdef DA_IMPLEMENTATION #ifdef DA_IMPLEMENTATION
#ifdef DA_GC GenericReturn _daCreate(size_t cap, size_t type, size_t size)
GC daGarbageCollector = {0};
void daInitGC()
{ {
daGarbageCollector = gcInit(); if (cap == 0) cap = 1;
}
void daDeinitGC()
{
gcDeinit(daGarbageCollector);
}
#endif
dynarr _daCreate(size_t cap, size_t type, size_t size)
{
size_t realCap = (((int)(cap / 8)) + 1 ) * 8;
#ifdef DA_GC
size_t * da = (size_t *) gcAlloc(&daGarbageCollector, 1, type * realCap + DATA * sizeof(size_t));
#else
size_t * da = (size_t *) calloc(1, type * realCap + DATA * sizeof(size_t));
#endif
size_t * da = (size_t *) malloc(type * cap + DATA * sizeof(size_t));
if (da == NULL) if (da == NULL)
return NULL; return ehanError("Failed to allocate resources for a dynamic array!");
da[SIZE] = size; da[SIZE] = size;
da[CAPACITY] = realCap; da[CAPACITY] = cap;
da[TYPE] = type; da[TYPE] = type;
return (dynarr) (da + DATA); return ehanValue((dynarr) (da + DATA));
} }
void daFree(dynarr da) void daFree(dynarr da)
@ -115,139 +77,140 @@ void daFree(dynarr da)
free((size_t *) da - DATA); free((size_t *) da - DATA);
} }
dynarr daCopy(dynarr da) GenericReturn daCopy(dynarr da)
{
if (da == NULL) return NULL;
dynarr newArr = _daCreate(daCap(da), daType(da), daSize(da));
if (newArr == NULL)
return NULL;
memcpy(newArr, da, daSize(da) * daType(da));
return newArr;
}
dynarr daResize(dynarr da)
{ {
if (da == NULL) if (da == NULL)
return NULL; return ehanError("Expected: 'dynarr' got 'NULL'");
dynarr newArr = _daCreate((size_t) daCap(da) * 1.5, daType(da), daSize(da)); GenericReturn temp = _daCreate(daCap(da), daType(da), daSize(da));
if (newArr == NULL) if (ehanCheck(temp))
return NULL; return ehanError(resultError(temp));
dynarr newArr = resultGeneric(dynarr, temp);
memcpy(newArr, da, daSize(da) * daType(da)); memcpy(newArr, da, daSize(da) * daType(da));
return ehanValue(newArr);
// TODO: Make use of the GCIndex returned from gcAlloc !
for (size_t i = 0; i < daGarbageCollector.size; ++i)
{
if (daGarbageCollector.items[i].ptr == da)
gcUpdateItem(&daGarbageCollector, i, newArr);
}
#ifndef DA_GC
daFree(da);
#endif
return newArr;
} }
//GenericReturn _daPushLit(dynarr * da, size_t item) GenericReturn daResize(dynarr da)
//{ {
// if (daSize(*da) >= daCap(*da)) if (da == NULL)
// { return ehanError("Expected: 'dynarr' got 'NULL'");
// *da = daResize(*da);
// GenericReturn temp = _daCreate(daCap(da) * 2, daType(da), daSize(da));
// if (da == NULL)
// return ehanError("Failed to reallocate new da!"); if (ehanCheck(temp))
// } return ehanError(resultError(temp));
//
// printf("A %zu\n", daType(*da)); dynarr newArr = resultGeneric(dynarr, temp);
//
// switch (daType(*da)) memcpy(newArr, da, daSize(da) * daType(da));
// { daFree(da);
// case 1: { return ehanValue(newArr);
// *((char *)*da + daType(*da) * daSize(*da)) = item; }
// } break;
// GenericReturn _daPushLit(dynarr * da, size_t item)
// case 2: { {
// *(short *)((char *)*da + daType(*da) * daSize(*da)) = item; if (daSize(*da) >= daCap(*da))
// } break; {
// GenericReturn temp = daResize(*da);
// case 4: {
// *(int *)((char *)*da + daType(*da) * daSize(*da)) = item; if (ehanCheck(temp))
// } break; return ehanError(resultError(temp));
//
// case 8: { *da = resultGeneric(dynarr, temp);
// *(long long int *)((char *)*da + daType(*da) * daSize(*da)) = item; }
// } break;
// switch (daType(*da))
// default: {
// return ehanError("Wrong type size"); case 1: {
// } *((char *)*da + daType(*da) * daSize(*da)) = item;
// printf("B\n"); } break;
// *daField(*da, SIZE) += 1;
// case 2: {
// return ehanValue(0); *(short *)((char *)*da + daType(*da) * daSize(*da)) = item;
//} } break;
//
//GenericReturn _daPushFlt(dynarr * da, float item) case 4: {
//{ *(int *)((char *)*da + daType(*da) * daSize(*da)) = item;
// if (daSize(*da) >= daCap(*da)) } break;
// {
// if (!daResize(*da)) case 8: {
// return ehanError("Failed to reallocate new da!"); *(long long int *)((char *)*da + daType(*da) * daSize(*da)) = item;
// } } break;
//
// switch (daType(*da)) default:
// { return ehanError("Wrong type size");
// case 4: { }
// *(float *)((char *)*da + daType(*da) * daSize(*da)) = item; *daField(*da, SIZE) += 1;
// } break;
// return ehanValue(0);
// case 8: { }
// *(double *)((char *)*da + daType(*da) * daSize(*da)) = item;
// } break; GenericReturn _daPushFlt(dynarr * da, float item)
// {
// case 16: { if (daSize(*da) >= daCap(*da))
// *(long double *)((char *)*da + daType(*da) * daSize(*da)) = item; {
// } break; GenericReturn temp = daResize(*da);
//
// default: if (ehanCheck(temp))
// return ehanError("Wrong type size"); return ehanError(resultError(temp));
// }
// *da = resultGeneric(dynarr, temp);
// *daField(*da, SIZE) += 1; }
//
// return ehanValue(0); switch (daType(*da))
//} {
// case 4: {
//GenericReturn _daPushStr(dynarr * da, const char * str) *(float *)((char *)*da + daType(*da) * daSize(*da)) = item;
//{ } break;
// if (daSize(*da) >= daCap(*da))
// { case 8: {
// if (!daResize(*da)) *(double *)((char *)*da + daType(*da) * daSize(*da)) = item;
// return ehanError("Failed to reallocate new da!"); } break;
// }
// case 16: {
// memcpy((char *)(*da) + daSize(*da) * daType(*da), &str, daType(*da)); *(long double *)((char *)*da + daType(*da) * daSize(*da)) = item;
// *daField(*da, SIZE) += 1; } break;
//
// return ehanValue(0); default:
//} return ehanError("Wrong type size");
// }
//void _daPop(dynarr da, void * elem)
//{ *daField(*da, SIZE) += 1;
// *daField(da, SIZE) -= 1;
// memcpy(elem, (char *)da + daSize(da) * daType(da), daType(da)); return ehanValue(0);
//} }
//
//void daPopDiscard(dynarr da) GenericReturn _daPushStr(dynarr * da, const char * str)
//{ {
// *daField(da, SIZE) -= 1; if (daSize(*da) >= daCap(*da))
//} {
GenericReturn temp = daResize(*da);
if (ehanCheck(temp))
return ehanError(resultError(temp));
*da = resultGeneric(dynarr, temp);
}
memcpy((char *)(*da) + daSize(*da) * daType(*da), &str, daType(*da));
*daField(*da, SIZE) += 1;
return ehanValue(0);
}
void _daPop(dynarr da, void * elem)
{
*daField(da, SIZE) -= 1;
memcpy(elem, (char *)da + daSize(da) * daType(da), daType(da));
}
void daPopDiscard(dynarr da)
{
*daField(da, SIZE) -= 1;
}
size_t * daField(dynarr da, enum daFields field) size_t * daField(dynarr da, enum daFields field)
{ {
@ -279,40 +242,38 @@ size_t daType(dynarr da)
return ((size_t *) da - DATA)[TYPE]; return ((size_t *) da - DATA)[TYPE];
} }
//void daForeach(dynarr da, func f) void daForeach(dynarr da, func f)
//{ {
// for (size_t i = 0; i < daSize(da); ++i) for (size_t i = 0; i < daSize(da); ++i)
// f((char *) da + i * daType(da)); f((char *) da + i * daType(da));
//} }
//
//heapstr daToCStr(dynarr da) heapstr daToCStr(dynarr da)
//{ {
// char * buffer = (char *) calloc(1, daSize(da) + 1); char * buffer = (char *) calloc(1, daSize(da) + 1);
// if (buffer == NULL) return NULL; if (buffer == NULL) return NULL;
//
// memcpy(buffer, da, daSize(da) * daType(da)); memcpy(buffer, da, daSize(da) * daType(da));
// return buffer; return buffer;
//} }
//
//void daBzero(dynarr da) void daBzero(dynarr da)
//{ {
// memset(da, '\0', daCap(da)); memset(da, '\0', daCap(da));
// *daField(da, SIZE) = 0; *daField(da, SIZE) = 0;
//} }
//
//void * daGetRef(dynarr da, size_t index) void * daGetRef(dynarr da, size_t index)
//{ {
// if (index >= daSize(da)) if (index >= daSize(da))
// { {
// fprintf(stderr, ("*------------------------------*\n")); fprintf(stderr, ("*------------------------------*\n"));
// fprintf(stderr, ("ERROR: Access out of bounds\n")); fprintf(stderr, ("ERROR: Access out of bounds\n"));
// fprintf(stderr, ("*------------------------------*\n")); fprintf(stderr, ("*------------------------------*\n"));
// return NULL; return NULL;
// } }
//
// return (void *)((char *)da + index * daType(da)); return (void *)((char *)da + index * daType(da));
//} }
#endif // DA_IMPLEMENTATION #endif // DA_IMPLEMENTATION
#endif // DA_H_

152
example.c
View File

@ -1,58 +1,24 @@
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#define DA_GC
#define DA_IMPLEMENTATION #define DA_IMPLEMENTATION
#include "da.h" #include "da.h"
#if 1 #define EHAN_IMPLEMENTATION
#include <stdio.h> #include "ehan.h"
#if 0
int main(void) int main(void)
{ {
daInitGC(); dynarr(char *) da = daCreate(char *,4).val;
dynarr(int) da = daCreate(int, 8); for (size_t i = 0; i < 1000; ++i) {
dynarr(char *) da2 = daCreate(char *, 8); daPushStr(da, "hi");
dynarr(float) da3 = daCreate(float, 1);
if (!da) goto exit;
if (!da2) goto exit;
if (!da3) goto exit;
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
printf("errno: %d\n", errno);
daAppend(da, 69);
printf("errno: %d\n", errno);
printf("%d\n", da[0]);
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
da = daResize(da);
if (!da) goto exit;
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
printf("DA2 -----\n");
daAppend(da2, "Hello, ");
daAppend(da2, "World!");
#define N 100000
for (size_t i = 0; i < N; ++i)
{
daAppend(da2, "AAA");
if (errno == 1) goto exit;
} }
printf("%s%s\n", da2[0], da2[1]); for (size_t i = 0; i < daSize(da); ++i) {
printf("%zu %zu %zu\n", daSize(da2), daCap(da2), daType(da2)); ILog("%zu: %s\n", i, da[i]);
}
printf("DA3 -----\n"); daFree(da);
daAppend(da3, 69.69);
daAppend(da3, 420.420);
printf("%.2f:%.3f\n", da3[0], da3[1]);
exit:
daDeinitGC();
return 0; return 0;
} }
@ -73,13 +39,21 @@ int main(void)
printf("DA1\n"); printf("DA1\n");
printf("----------\n"); printf("----------\n");
dynarr(unsigned short) da = daCreate(unsigned short, 1); GenericReturn gr = daCreate(unsigned short, 1);
if (ehanCheck(gr))
{
ELog("%s\n", resultError(gr));
exit(1);
}
dynarr(unsigned short) da = resultGeneric(dynarr(unsigned short), gr);
daPush(da, 69); daPush(da, 69);
daPush(da, 420); daPush(da, 420);
daPush(da, 1337); daPush(da, 1337);
daPush(da, 34); daPush(da, 34);
daPush(da, 35); daPush(da, 35);
daPush(da, 1667); daPush(da, 1667);
unsigned short x = 0; unsigned short x = 0;
@ -91,69 +65,69 @@ int main(void)
printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da)); printf("%zu %zu %zu\n", daSize(da), daCap(da), daType(da));
//printf("----------\n"); printf("----------\n");
//printf("DA2\n"); printf("DA2\n");
//printf("----------\n"); printf("----------\n");
//dynarr(char) da2 = daCreate(char, 1); dynarr(char) da2 = daCreate(char, 1).val;
//daPush(da2, 'H'); daPush(da2, 'H');
//daPush(da2, 'i'); daPush(da2, 'i');
//daPush(da2, ' '); daPush(da2, ' ');
//daPush(da2, 'm'); daPush(da2, 'm');
//daPush(da2, 'o'); daPush(da2, 'o');
//daPush(da2, 'm'); daPush(da2, 'm');
//daPush(da2, '?'); daPush(da2, '?');
//daPush(da2, '?'); daPush(da2, '?');
//*(char *)daGetRef(da2, 6) = '!'; *(char *)daGetRef(da2, 6) = '!';
//daPopDiscard(da2); daPopDiscard(da2);
//heapstr message = daToCStr(da2); heapstr message = daToCStr(da2);
//printf("%s\n", message); printf("%s\n", message);
//printf("----------\n"); printf("----------\n");
//printf("DA3\n"); printf("DA3\n");
//printf("----------\n"); printf("----------\n");
//dynarr(char *) da3 = daCreate(char *, 1); dynarr(char *) da3 = daCreate(char *, 1).val;
//for (size_t i = 0; i < 1000000; ++i) { for (size_t i = 0; i < 1000000; ++i) {
// daPush(da3, "Test"); daPush(da3, "Test");
//} }
//char * str; char * str;
//daPop(da3, str); daPop(da3, str);
//printf("%s\n", str); printf("%s\n", str);
//printf("----------\n"); printf("----------\n");
//printf("DA4\n"); printf("DA4\n");
//printf("----------\n"); printf("----------\n");
//dynarr(double) da4 = daCreate(double, 1); dynarr(double) da4 = daCreate(double, 1).val;
//daPush(da4, 69.692343); daPush(da4, 69.692343);
//printf("float: %F\n", da4[0]); printf("float: %F\n", da4[0]);
//printf("----------\n"); printf("----------\n");
//printf("DA5\n"); printf("DA5\n");
//printf("----------\n"); printf("----------\n");
//dynarr(char *) da5 = daCreate(char *, 1); dynarr(char *) da5 = daCreate(char *, 1).val;
//daPush(da5, "Hello, "); daPush(da5, "Hello, ");
//daPush(da5, "World!"); daPush(da5, "World!");
//DLog("%s%s\n", da5[0], da5[1]); DLog("%s%s\n", da5[0], da5[1]);
cleanup: cleanup:
//daFree(da5); daFree(da5);
//daFree(da4); daFree(da4);
//daFree(da3); daFree(da3);
//free(message); free(message);
//daFree(da2); daFree(da2);
daFree(da); daFree(da);
return 0; return 0;