#ifndef MEMORY_CC #define MEMORY_CC #include #include #include "common.cc" typedef u8* (*Allocator_Allocate)(u8* self, usize length, usize align); typedef void (*Allocator_Deallocate)(u8* self, u8* ptr); struct Allocator { u8* self; Allocator_Allocate allocate; Allocator_Deallocate deallocate; }; u8* allocate(Allocator* allocator, usize size, usize align) { return allocator->allocate(allocator->self, size, align); } void deallocate(Allocator* allocator, u8* ptr) { allocator->deallocate(allocator->self, ptr); } static inline u8* heap_allocate(u8* self, usize size, usize align) { (void)self; return (u8*)mi_aligned_alloc(align, size); } static inline void heap_deallocate(u8* self, u8* ptr) { (void)self; mi_free(ptr); } Allocator* heap_allocator() { thread_local Allocator HEAP_ALLOCATOR = {nullptr, heap_allocate, heap_deallocate}; return &HEAP_ALLOCATOR; } template bool slice_copy(Allocator* allocator, const Slice* source, Slice* out) { T* new_ptr = allocate(allocator, source->size(), alignof(T)); if (new_ptr == nullptr) return false; memcpy((u8*)new_ptr, (u8*)source->ptr, source->length); out->length = source->length; out->ptr = new_ptr; return true; } template void slice_deallocate(Allocator* allocator, Slice* slice) { if (slice->ptr == nullptr) return; deallocate(allocator, (u8*)slice->ptr); slice->ptr = nullptr; slice->length = 0; } #endif