Sun, 03 Oct 2021 13:07:48 +0200
add __alloc_size__ attribute
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28 /**
29 * \file allocator.h
30 * Interface for custom allocators.
31 */
33 #ifndef UCX_ALLOCATOR_H
34 #define UCX_ALLOCATOR_H
36 #include <stdlib.h>
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
42 /**
43 * The class definition for an allocator.
44 */
45 typedef struct {
46 /**
47 * Allocate \p n bytes of memory.
48 *
49 * @param data the allocator's data
50 * @param n the number of bytes
51 * @return a pointer to the allocated memory
52 */
53 void *(*malloc)(void *data, size_t n);
55 /**
56 * Re-allocate the previously allocated block in \p mem, making the new block \p n bytes long.
57 * This function may return the same pointer that was passed to it, if moving the memory
58 * was not necessary.
59 *
60 * \note Re-allocating a block allocated by a different allocator is undefined.
61 *
62 * @param data the allocator's data
63 * @param mem pointer to the previously allocated block
64 * @param n the new size in bytes
65 * @return a pointer to the re-allocated memory
66 */
67 void *(*realloc)(void *data, void *mem, size_t n)
68 __attribute__((__warn_unused_result__));
70 /**
71 * Allocate \p nelem elements of \p n bytes each, all initialized to zero.
72 *
73 * @param data the allocator's data
74 * @param nelem the number of elements
75 * @param n the size of each element in bytes
76 * @return a pointer to the allocated memory
77 */
78 void *(*calloc)(void *data, size_t nelem, size_t n);
80 /**
81 * Free a block allocated by this allocator.
82 *
83 * \note Freeing a block of a different allocator is undefined.
84 *
85 * @param data the allocator's data
86 * @param mem a pointer to the block to free
87 */
88 void (*free)(void *data, void *mem)
89 __attribute__((__nonnull__));
90 } cx_allocator_class;
92 /**
93 * Structure holding the data for an allocator.
94 */
95 struct cx_allocator_s {
96 /**
97 * A pointer to the instance of the allocator class.
98 */
99 cx_allocator_class *cl;
100 /**
101 * A pointer to the data this allocator uses.
102 */
103 void *data;
104 };
106 /**
107 * High-Level type alias for the allocator type.
108 */
109 typedef struct cx_allocator_s *CxAllocator;
111 /**
112 * A default allocator using standard library malloc() etc.
113 */
114 extern CxAllocator cxDefaultAllocator;
116 /**
117 * Allocate \p n bytes of memory.
118 *
119 * @param allocator the allocator
120 * @param n the number of bytes
121 * @return a pointer to the allocated memory
122 */
123 void *cxMalloc(CxAllocator allocator, size_t n)
124 __attribute__((__malloc__, __alloc_size__(2)));
126 /**
127 * Re-allocate the previously allocated block in \p mem, making the new block \p n bytes long.
128 * This function may return the same pointer that was passed to it, if moving the memory
129 * was not necessary.
130 *
131 * \note Re-allocating a block allocated by a different allocator is undefined.
132 *
133 * @param allocator the allocator
134 * @param mem pointer to the previously allocated block
135 * @param n the new size in bytes
136 * @return a pointer to the re-allocated memory
137 */
138 void *cxRealloc(CxAllocator allocator, void *mem, size_t n)
139 __attribute__((__warn_unused_result__, __alloc_size__(3)));
141 /**
142 * Re-allocate a previously allocated block and changes the pointer in-place, if necessary.
143 * This function acts like cxRealloc() using the pointer pointed to by \p mem.
144 * On success, the pointer is changed to the new location (in case the
145 *
146 * \note Re-allocating a block allocated by a different allocator is undefined.
147 *
148 * \par Error handling
149 * \c errno will be set, if the underlying realloc function does so.
150 *
151 * @param allocator the allocator
152 * @param mem pointer to the pointer to allocated block
153 * @param n the new size in bytes
154 * @return zero on success, non-zero on failure
155 */
156 int cxReallocate(CxAllocator allocator, void **mem, size_t n)
157 __attribute__((__nonnull__));
159 /**
160 * Allocate \p nelem elements of \p n bytes each, all initialized to zero.
161 *
162 * @param allocator the allocator
163 * @param nelem the number of elements
164 * @param n the size of each element in bytes
165 * @return a pointer to the allocated memory
166 */
167 void *cxCalloc(CxAllocator allocator, size_t nelem, size_t n)
168 __attribute__((__malloc__, __alloc_size__(2, 3)));
170 /**
171 * Free a block allocated by this allocator.
172 *
173 * \note Freeing a block of a different allocator is undefined.
174 *
175 * @param allocator the allocator
176 * @param mem a pointer to the block to free
177 */
178 void cxFree(CxAllocator allocator, void *mem)
179 __attribute__((__nonnull__));
181 #ifdef __cplusplus
182 } /* extern "C" */
183 #endif
185 #endif /* UCX_ALLOCATOR_H */