diff options
Diffstat (limited to 'include/zix/allocator.h')
-rw-r--r-- | include/zix/allocator.h | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/include/zix/allocator.h b/include/zix/allocator.h new file mode 100644 index 0000000..73e2207 --- /dev/null +++ b/include/zix/allocator.h @@ -0,0 +1,152 @@ +/* + Copyright 2021 David Robillard <d@drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef ZIX_ALLOCATOR_H +#define ZIX_ALLOCATOR_H + +#include "zix/attributes.h" + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @addtogroup zix + @{ + @name Allocator + @{ +*/ + +/// Opaque user data for allocation functions +typedef void ZixAllocatorHandle; + +/** + General malloc-like memory allocation function. + + This works like the standard C malloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED ( + *ZixMallocFunc)(ZixAllocatorHandle* ZIX_NULLABLE handle, size_t size); + +/** + General calloc-like memory allocation function. + + This works like the standard C calloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED (*ZixCallocFunc)(ZixAllocatorHandle* ZIX_NULLABLE + handle, + size_t nmemb, + size_t size); + +/** + General realloc-like memory reallocation function. + + This works like the standard C remalloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED (*ZixReallocFunc)(ZixAllocatorHandle* ZIX_NULLABLE + handle, + void* ZIX_NULLABLE ptr, + size_t size); + +/** + General free-like memory deallocation function. + + This works like the standard C remalloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void (*ZixFreeFunc)(ZixAllocatorHandle* ZIX_NULLABLE handle, + void* ZIX_NULLABLE ptr); + +/** + A memory allocator. + + This object-like structure provides an interface like the standard C + functions malloc(), calloc(), realloc(), and free(). It allows the user to + pass a custom allocator to be used by data structures. +*/ +typedef struct { + ZixAllocatorHandle* ZIX_NULLABLE handle; + ZixMallocFunc ZIX_NONNULL malloc; + ZixCallocFunc ZIX_NONNULL calloc; + ZixReallocFunc ZIX_NONNULL realloc; + ZixFreeFunc ZIX_NONNULL free; +} ZixAllocator; + +/// Return the default allocator which simply uses the system allocator +ZIX_CONST_API +const ZixAllocator* ZIX_NONNULL +zix_default_allocator(void); + +/// Convenience wrapper that defers to malloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_malloc(const ZixAllocator* const ZIX_NULLABLE allocator, const size_t size) +{ + const ZixAllocator* const actual = + allocator ? allocator : zix_default_allocator(); + + return actual->malloc(actual->handle, size); +} + +/// Convenience wrapper that defers to calloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_calloc(const ZixAllocator* const ZIX_NULLABLE allocator, + const size_t nmemb, + const size_t size) +{ + const ZixAllocator* const actual = + allocator ? allocator : zix_default_allocator(); + + return actual->calloc(actual->handle, nmemb, size); +} + +/// Convenience wrapper that defers to realloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_realloc(const ZixAllocator* const ZIX_NULLABLE allocator, + void* const ZIX_NULLABLE ptr, + const size_t size) +{ + const ZixAllocator* const actual = + allocator ? allocator : zix_default_allocator(); + + return actual->realloc(actual->handle, ptr, size); +} + +/// Convenience wrapper that defers to free() if allocator is null +static inline void +zix_free(const ZixAllocator* const ZIX_NULLABLE allocator, + void* const ZIX_NULLABLE ptr) +{ + const ZixAllocator* const actual = + allocator ? allocator : zix_default_allocator(); + + actual->free(actual->handle, ptr); +} + +/** + @} + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ZIX_ALLOCATOR_H */ |