diff --git a/source/md.h b/source/md.h index 46010f9..06dd44c 100644 --- a/source/md.h +++ b/source/md.h @@ -257,6 +257,41 @@ typedef int64_t MD_b64; typedef float MD_f32; typedef double MD_f64; +//~ Abstract Arena + +typedef union MD_IntPtr MD_IntPtr; +union MD_IntPtr +{ + MD_u64 u64; + void *ptr; +}; + +typedef enum MD_ArenaOperation +{ + MD_ArenaOperation_GetPos, + MD_ArenaOperation_Push, + MD_ArenaOperation_PopTo, + MD_ArenaOperation_PushAlign, + MD_ArenaOperation_SetAutoAlign, +} MD_ArenaOperation; + +typedef MD_IntPtr MD_ArenaFunc(struct MD_Arena *arena, MD_ArenaOperation op, MD_u64 v); + +typedef struct MD_Arena MD_Arena; +struct MD_Arena +{ + MD_ArenaFunc *func; +}; + +//~ Arena Helpers + +typedef struct MD_ArenaTemp MD_ArenaTemp; +struct MD_ArenaTemp +{ + MD_Arena *arena; + MD_u64 pos; +}; + //~ Basic Unicode string types. typedef struct MD_String8 MD_String8; @@ -668,6 +703,16 @@ MD_FUNCTION void* MD_AllocZero(MD_u64 size); // allocation approach changes). #define MD_PushArrayZero(T,c) (T*)MD_AllocZero(sizeof(T)*(c)) +//~ Arena Functions + +MD_FUNCTION void* MD_ArenaPush(MD_Arena *arena, MD_u64 v); +MD_FUNCTION MD_ArenaTemp MD_ArenaBeginTemp(MD_Arena *arena); +MD_FUNCTION void MD_ArenaEndTemp(MD_ArenaTemp temp); +MD_FUNCTION void MD_ArenaSetAlign(MD_Arena *arena, MD_u64 v); +MD_FUNCTION void MD_ArenaPushAlign(MD_Arena *arena, MD_u64 v); + +#define MD_PushArrayAr(a,T,c) (T*)(MD_ArenaPush((a), sizeof(T)*(c))) + //~ Characters MD_FUNCTION MD_b32 MD_CharIsAlpha(MD_u8 c); diff --git a/source/md_impl.c b/source/md_impl.c index c3e1e25..2922fa4 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -56,6 +56,42 @@ MD_AllocZero(MD_u64 size) #endif } +//~ Arena Functions + +MD_FUNCTION void* +MD_ArenaPush(MD_Arena *arena, MD_u64 v) +{ + MD_IntPtr result = arena->func(arena, MD_ArenaOperation_Push, v); + return(result.ptr); +} + +MD_FUNCTION MD_ArenaTemp +MD_ArenaBeginTemp(MD_Arena *arena) +{ + MD_IntPtr pos = arena->func(arena, MD_ArenaOperation_GetPos, 0); + MD_ArenaTemp result = MD_ZERO_STRUCT; + result.arena = arena; + result.pos = pos.u64; + return(result); +} + +MD_FUNCTION void +MD_ArenaEndTemp(MD_ArenaTemp temp) +{ + temp.arena->func(temp.arena, MD_ArenaOperation_PopTo, temp.pos); +} + +MD_FUNCTION void +MD_ArenaSetAlign(MD_Arena *arena, MD_u64 v){ + arena->func(arena, MD_ArenaOperation_SetAutoAlign, v); +} + +MD_FUNCTION void +MD_ArenaPushAlign(MD_Arena *arena, MD_u64 v){ + arena->func(arena, MD_ArenaOperation_PushAlign, v); +} + + //~ Characters MD_FUNCTION_IMPL MD_b32