#pragma once #include /* size_t */ struct allocator { #ifndef NDEBUG struct allocator *self; #endif void *(*allocate)(struct allocator *allocator, size_t n); void (*deallocate)(struct allocator *allocator, void *ptr); }; extern struct allocator default_allocator; /* allocator interface */ void *allocator_malloc(struct allocator *allocator, size_t n); void allocator_free(struct allocator *allocator, void *ptr); /* helper functions */ char *allocator_strdup(struct allocator *allocator, const char *str); void *allocator_malloc_zero(struct allocator *allocator, size_t n); #define ALLOCATE(n) \ allocator_malloc(&allocator_default_allocator, (n)) #define ALLOCATE_ZERO(n) \ allocator_malloc_zero(&allocator_default_allocator, (n)) #define FREE(ptr) \ (allocator_free(&allocator_default_allocator, (ptr)), (ptr) = NULL) #define NEW(ptr) ((ptr) = ALLOCATE(sizeof *(ptr))) #define NEW0(ptr) ((ptr) = ALLOCATE_ZERO(sizeof *(ptr)))