summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/zix/allocator.h152
-rw-r--r--include/zix/btree.h5
-rw-r--r--include/zix/hash.h8
-rw-r--r--include/zix/ring.h3
-rw-r--r--include/zix/tree.h12
5 files changed, 170 insertions, 10 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 */
diff --git a/include/zix/btree.h b/include/zix/btree.h
index 3979084..9c67dda 100644
--- a/include/zix/btree.h
+++ b/include/zix/btree.h
@@ -17,6 +17,7 @@
#ifndef ZIX_BTREE_H
#define ZIX_BTREE_H
+#include "zix/allocator.h"
#include "zix/attributes.h"
#include "zix/common.h"
@@ -88,7 +89,9 @@ static const ZixBTreeIter zix_btree_end_iter = {
*/
ZIX_API
ZixBTree* ZIX_ALLOCATED
-zix_btree_new(ZixComparator ZIX_NONNULL cmp, const void* ZIX_NULLABLE cmp_data);
+zix_btree_new(const ZixAllocator* ZIX_NULLABLE allocator,
+ ZixComparator ZIX_NONNULL cmp,
+ const void* ZIX_NULLABLE cmp_data);
/**
Free `t` and all the nodes it contains.
diff --git a/include/zix/hash.h b/include/zix/hash.h
index 8be8941..cc56d0e 100644
--- a/include/zix/hash.h
+++ b/include/zix/hash.h
@@ -17,6 +17,7 @@
#ifndef ZIX_HASH_H
#define ZIX_HASH_H
+#include "zix/allocator.h"
#include "zix/attributes.h"
#include "zix/common.h"
@@ -133,9 +134,10 @@ typedef struct {
*/
ZIX_API
ZixHash* ZIX_ALLOCATED
-zix_hash_new(ZixKeyFunc ZIX_NONNULL key_func,
- ZixHashFunc ZIX_NONNULL hash_func,
- ZixKeyEqualFunc ZIX_NONNULL equal_func);
+zix_hash_new(const ZixAllocator* ZIX_NULLABLE allocator,
+ ZixKeyFunc ZIX_NONNULL key_func,
+ ZixHashFunc ZIX_NONNULL hash_func,
+ ZixKeyEqualFunc ZIX_NONNULL equal_func);
/// Free `hash`
ZIX_API
diff --git a/include/zix/ring.h b/include/zix/ring.h
index b323e70..af98ecf 100644
--- a/include/zix/ring.h
+++ b/include/zix/ring.h
@@ -17,6 +17,7 @@
#ifndef ZIX_RING_H
#define ZIX_RING_H
+#include "zix/allocator.h"
#include "zix/attributes.h"
#include <stdint.h>
@@ -48,7 +49,7 @@ typedef struct ZixRingImpl ZixRing;
*/
ZIX_MALLOC_API
ZixRing* ZIX_ALLOCATED
-zix_ring_new(uint32_t size);
+zix_ring_new(const ZixAllocator* ZIX_NULLABLE allocator, uint32_t size);
/// Destroy a ring
ZIX_API
diff --git a/include/zix/tree.h b/include/zix/tree.h
index 2ce7490..c3b9262 100644
--- a/include/zix/tree.h
+++ b/include/zix/tree.h
@@ -17,6 +17,7 @@
#ifndef ZIX_TREE_H
#define ZIX_TREE_H
+#include "zix/allocator.h"
#include "zix/attributes.h"
#include "zix/common.h"
@@ -43,11 +44,12 @@ typedef struct ZixTreeNodeImpl ZixTreeIter;
/// Create a new (empty) tree
ZIX_API
ZixTree* ZIX_ALLOCATED
-zix_tree_new(bool allow_duplicates,
- ZixComparator ZIX_NONNULL cmp,
- void* ZIX_NULLABLE cmp_data,
- ZixDestroyFunc ZIX_NULLABLE destroy,
- const void* ZIX_NULLABLE destroy_user_data);
+zix_tree_new(const ZixAllocator* ZIX_NULLABLE allocator,
+ bool allow_duplicates,
+ ZixComparator ZIX_NONNULL cmp,
+ void* ZIX_NULLABLE cmp_data,
+ ZixDestroyFunc ZIX_NULLABLE destroy,
+ const void* ZIX_NULLABLE destroy_user_data);
/// Free `t`
ZIX_API