#pragma once
// base_arena.h - Linear arena allocator
// Simplified from raddebugger's virtual-memory-backed arena to a malloc-based one.
// Suitable for per-frame scratch allocations and persistent state.

#include "base/base_core.h"

////////////////////////////////
// Arena type

struct Arena {
    U8  *base;
    U64  pos;
    U64  cap;
};

// Temporary scope (save/restore position)
struct Temp {
    Arena *arena;
    U64    pos;
};

////////////////////////////////
// Arena functions

Arena *arena_alloc(U64 cap);
void   arena_release(Arena *arena);
void  *arena_push(Arena *arena, U64 size);
void  *arena_push_no_zero(Arena *arena, U64 size);
U64    arena_pos(Arena *arena);
void   arena_pop_to(Arena *arena, U64 pos);
void   arena_clear(Arena *arena);

////////////////////////////////
// Temporary scope helpers

inline Temp temp_begin(Arena *arena) { return {arena, arena->pos}; }
inline void temp_end(Temp temp)      { arena_pop_to(temp.arena, temp.pos); }

////////////////////////////////
// Push helper macros

#define push_array(arena, T, count)         ((T *)arena_push((arena), sizeof(T) * (count)))
#define push_array_no_zero(arena, T, count) ((T *)arena_push_no_zero((arena), sizeof(T) * (count)))
