aboutsummaryrefslogtreecommitdiffstats
path: root/src/zix/allocator.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/zix/allocator.h')
-rw-r--r--src/zix/allocator.h186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/zix/allocator.h b/src/zix/allocator.h
new file mode 100644
index 0000000..bcffda5
--- /dev/null
+++ b/src/zix/allocator.h
@@ -0,0 +1,186 @@
+// Copyright 2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#ifndef ZIX_ALLOCATOR_H
+#define ZIX_ALLOCATOR_H
+
+#include "zix/attributes.h"
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ @addtogroup zix
+ @{
+ @name Allocator
+ @{
+*/
+
+struct ZixAllocatorImpl;
+
+/**
+ A memory allocator.
+
+ This object-like structure provides an interface like the standard C
+ functions malloc(), calloc(), realloc(), free(), and aligned_alloc(). It
+ contains function pointers that differ from their standard counterparts by
+ taking a context parameter (a pointer to this struct), which allows the user
+ to implement custom stateful allocators.
+*/
+typedef struct ZixAllocatorImpl ZixAllocator;
+
+/**
+ 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)( //
+ ZixAllocator* ZIX_NULLABLE allocator,
+ 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)( //
+ ZixAllocator* ZIX_NULLABLE allocator,
+ 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)( //
+ ZixAllocator* ZIX_NULLABLE allocator,
+ 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)( //
+ ZixAllocator* ZIX_NULLABLE allocator,
+ void* ZIX_NULLABLE ptr);
+
+/**
+ General aligned_alloc-like memory deallocation function.
+
+ This works like the standard C aligned_alloc(), except has an additional
+ handle parameter for implementing stateful allocators without static data.
+*/
+typedef void* ZIX_ALLOCATED (*ZixAlignedAllocFunc)( //
+ ZixAllocator* ZIX_NULLABLE allocator,
+ size_t alignment,
+ size_t size);
+
+/**
+ General aligned memory deallocation function.
+
+ This works like the standard C free(), but must be used to free memory
+ allocated with the aligned_alloc() method of the allocator. This allows
+ portability to systems (like Windows) that can not use the same free function
+ in these cases.
+*/
+typedef void (*ZixAlignedFreeFunc)( //
+ ZixAllocator* ZIX_NULLABLE allocator,
+ void* ZIX_NULLABLE ptr);
+
+/// Definition of ZixAllocator
+struct ZixAllocatorImpl {
+ ZixMallocFunc ZIX_NONNULL malloc;
+ ZixCallocFunc ZIX_NONNULL calloc;
+ ZixReallocFunc ZIX_NONNULL realloc;
+ ZixFreeFunc ZIX_NONNULL free;
+ ZixAlignedAllocFunc ZIX_NONNULL aligned_alloc;
+ ZixAlignedFreeFunc ZIX_NONNULL aligned_free;
+};
+
+/// Return the default allocator which simply uses the system allocator
+ZIX_CONST_API
+ZixAllocator* ZIX_NONNULL
+zix_default_allocator(void);
+
+/// Convenience wrapper that defers to malloc() if allocator is null
+static inline void* ZIX_ALLOCATED
+zix_malloc(ZixAllocator* const ZIX_NULLABLE allocator, const size_t size)
+{
+ ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
+
+ return actual->malloc(actual, size);
+}
+
+/// Convenience wrapper that defers to calloc() if allocator is null
+static inline void* ZIX_ALLOCATED
+zix_calloc(ZixAllocator* const ZIX_NULLABLE allocator,
+ const size_t nmemb,
+ const size_t size)
+{
+ ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
+
+ return actual->calloc(actual, nmemb, size);
+}
+
+/// Convenience wrapper that defers to realloc() if allocator is null
+static inline void* ZIX_ALLOCATED
+zix_realloc(ZixAllocator* const ZIX_NULLABLE allocator,
+ void* const ZIX_NULLABLE ptr,
+ const size_t size)
+{
+ ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
+
+ return actual->realloc(actual, ptr, size);
+}
+
+/// Convenience wrapper that defers to free() if allocator is null
+static inline void
+zix_free(ZixAllocator* const ZIX_NULLABLE allocator,
+ void* const ZIX_NULLABLE ptr)
+{
+ ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
+
+ actual->free(actual, ptr);
+}
+
+/// Convenience wrapper that defers to the system allocator if allocator is null
+static inline void* ZIX_ALLOCATED
+zix_aligned_alloc(ZixAllocator* const ZIX_NULLABLE allocator,
+ const size_t alignment,
+ const size_t size)
+{
+ ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
+
+ return actual->aligned_alloc(actual, alignment, size);
+}
+
+/// Convenience wrapper that defers to the system allocator if allocator is null
+static inline void
+zix_aligned_free(ZixAllocator* const ZIX_NULLABLE allocator,
+ void* const ZIX_NULLABLE ptr)
+{
+ ZixAllocator* const actual = allocator ? allocator : zix_default_allocator();
+
+ actual->aligned_free(actual, ptr);
+}
+
+/**
+ @}
+ @}
+*/
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ZIX_ALLOCATOR_H */