/* * Stack-based allocator. */ #pragma once #include #include /// Stack-based allocator. typedef struct memstack { size_t capacity; // Total size available. uint8_t* base; // Base pointer to memory. uint8_t* watermark; // Pointer to next free area of memory. bool owned; // True if memory is owned by the memstack. bool trap; // Whether to trap when allocating beyond capacity. } memstack; /// Create a stack-based allocator. /// /// `stack` may be user-provided or null. /// - If null, the allocator malloc()s the memory for them. /// - If given, `stack` must be at least `capacity` bytes. /// /// The memory is zeroed out for convenience. bool memstack_make(memstack*, size_t capacity, void* memory); /// Destroy the stack. /// /// If the allocator owns the memory, then this function frees it. void memstack_del(memstack*); /// Clear the stack. void memstack_clear(memstack*); /// Allocate a new block. /// Return null if the block does not fit in the remaining memory. /// When there is no space left in the stack, allocation can either trap /// (default) or gracefully return null. Call mem_enable_traps() to toggle this /// behaviour. /// Newly allocated blocks are conveniently zeroed out. void* memstack_alloc(memstack*, size_t bytes); /// Return the stack's used size in bytes. size_t memstack_size(const memstack*); /// Return the stack's total capacity in bytes. size_t memstack_capacity(const memstack*); /// Set whether to trap when attempting to allocate beyond capacity. void memstack_enable_traps(memstack*, bool);