import aliases; import math; import std.stdio; import core.stdc.string : memset; import core.memory; import platform; const DEFAULT_ALIGNMENT = (void *).sizeof * 2; struct Arena { u8* mem; u64 length; u64 pos; }; T* MAlloc(T)() { void* mem = MemAlloc(T.sizeof); return cast(T*)mem; } T[] MAllocArray(T)(u64 count) { void* mem = MemAlloc(T.sizeof * count); return (cast(T*)mem)[0 .. count]; } void MFree(T)(T* ptr) { MemFree(cast(void*)ptr, T.sizeof); } void MFreeArray(T)(T[] slice) { MemFree(cast(void*)slice.ptr, cast(u64)slice.length * T.sizeof); } T* Alloc(T)() { void* mem = pureMalloc(T.sizeof); memset(mem, 0, T.sizeof); return (cast(T*)mem); } T[] AllocArray(T)(u64 count) { void* mem = pureMalloc(T.sizeof * count); memset(mem, 0, T.sizeof * count); return (cast(T*)mem)[0 .. count]; } Arena CreateArena(u64 size) { Arena arena = { mem: cast(u8 *)pureMalloc(size), length: size, pos: 0, }; assert(arena.mem != null, "Unable to allocate memory for arena"); return arena; }; T[] AllocArray(T)(Arena* arena, u64 count) { void* mem = AllocAlign(arena, T.sizeof * count, DEFAULT_ALIGNMENT); memset(mem, 0, T.sizeof * count); return (cast(T*)mem)[0 .. count]; } T* Alloc(T)(Arena* arena) { void* mem = AllocAlign(arena, T.sizeof, DEFAULT_ALIGNMENT); memset(mem, 0, T.sizeof); return cast(T*)mem; }; void* AllocAlign(Arena* arena, u64 size, u64 alignment) { void* ptr = null; uintptr mem_pos = cast(uintptr)arena.mem; uintptr current = mem_pos + arena.pos; uintptr offset = AlignPow2(current, alignment) - mem_pos; if (offset+size <= arena.length) { ptr = &arena.mem[offset]; arena.pos = offset+size; } else { writefln("AllocAlign failure: out of memory, size requested: %llu", size); assert(0); } return ptr; }; void Reset(Arena* arena) { arena.pos = 0; } void Free(Arena* arena) { pureFree(arena.mem); } void FreeArray(T)(T[] arr) { pureFree(arr.ptr); } void Free(T)(T* ptr) { pureFree(ptr); }