100 typedef struct cx_allocator_s CxAllocator; |
98 typedef struct cx_allocator_s CxAllocator; |
101 |
99 |
102 /** |
100 /** |
103 * A default allocator using standard library malloc() etc. |
101 * A default allocator using standard library malloc() etc. |
104 */ |
102 */ |
105 extern CxAllocator *cxDefaultAllocator; |
103 cx_attr_export |
|
104 extern const CxAllocator * const cxDefaultAllocator; |
106 |
105 |
107 /** |
106 /** |
108 * Function pointer type for destructor functions. |
107 * Function pointer type for destructor functions. |
109 * |
108 * |
110 * A destructor function deallocates possible contents and MAY free the memory |
109 * A destructor function deallocates possible contents and MAY free the memory |
111 * pointed to by \p memory. Read the documentation of the respective function |
110 * pointed to by @p memory. Read the documentation of the respective function |
112 * pointer to learn if a destructor SHALL, MAY, or MUST NOT free the memory in that |
111 * pointer to learn if a destructor SHALL, MAY, or MUST NOT free the memory in |
113 * particular implementation. |
112 * that particular implementation. |
114 * |
113 * |
115 * @param memory a pointer to the object to destruct |
114 * @param memory a pointer to the object to destruct |
116 */ |
115 */ |
117 typedef void (*cx_destructor_func)(void *memory) __attribute__((__nonnull__)); |
116 typedef void (*cx_destructor_func)(void *memory); |
118 |
117 |
119 /** |
118 /** |
120 * Function pointer type for destructor functions. |
119 * Function pointer type for destructor functions. |
121 * |
120 * |
122 * A destructor function deallocates possible contents and MAY free the memory |
121 * A destructor function deallocates possible contents and MAY free the memory |
123 * pointed to by \p memory. Read the documentation of the respective function |
122 * pointed to by @p memory. Read the documentation of the respective function |
124 * pointer to learn if a destructor SHALL, MAY, or MUST NOT free the memory in that |
123 * pointer to learn if a destructor SHALL, MAY, or MUST NOT free the memory in |
125 * particular implementation. |
124 * that particular implementation. |
126 * |
125 * |
127 * @param data an optional pointer to custom data |
126 * @param data an optional pointer to custom data |
128 * @param memory a pointer to the object to destruct |
127 * @param memory a pointer to the object to destruct |
129 */ |
128 */ |
130 typedef void (*cx_destructor_func2)( |
129 typedef void (*cx_destructor_func2)( |
131 void *data, |
130 void *data, |
132 void *memory |
131 void *memory |
133 ) __attribute__((__nonnull__(2))); |
132 ); |
134 |
133 |
135 /** |
134 /** |
136 * Re-allocate a previously allocated block and changes the pointer in-place, if necessary. |
135 * Reallocate a previously allocated block and changes the pointer in-place, |
137 * |
136 * if necessary. |
138 * \par Error handling |
137 * |
139 * \c errno will be set by realloc() on failure. |
138 * @par Error handling |
|
139 * @c errno will be set by realloc() on failure. |
140 * |
140 * |
141 * @param mem pointer to the pointer to allocated block |
141 * @param mem pointer to the pointer to allocated block |
142 * @param n the new size in bytes |
142 * @param n the new size in bytes |
143 * @return zero on success, non-zero on failure |
143 * @retval zero success |
144 */ |
144 * @retval non-zero failure |
145 int cx_reallocate( |
145 * @see cx_reallocatearray() |
|
146 */ |
|
147 cx_attr_nonnull |
|
148 cx_attr_nodiscard |
|
149 cx_attr_export |
|
150 int cx_reallocate_( |
146 void **mem, |
151 void **mem, |
147 size_t n |
152 size_t n |
148 ) |
153 ); |
149 __attribute__((__nonnull__)); |
154 |
150 |
155 /** |
151 /** |
156 * Reallocate a previously allocated block and changes the pointer in-place, |
152 * Allocate \p n bytes of memory. |
157 * if necessary. |
|
158 * |
|
159 * The size is calculated by multiplying @p nemb and @p size. |
|
160 * |
|
161 * @par Error handling |
|
162 * @c errno will be set by realloc() on failure or when the multiplication of |
|
163 * @p nmemb and @p size overflows. |
|
164 * |
|
165 * @param mem pointer to the pointer to allocated block |
|
166 * @param nmemb the number of elements |
|
167 * @param size the size of each element |
|
168 * @retval zero success |
|
169 * @retval non-zero failure |
|
170 * @see cx_reallocate() |
|
171 */ |
|
172 cx_attr_nonnull |
|
173 cx_attr_nodiscard |
|
174 cx_attr_export |
|
175 int cx_reallocatearray_( |
|
176 void **mem, |
|
177 size_t nmemb, |
|
178 size_t size |
|
179 ); |
|
180 |
|
181 /** |
|
182 * Reallocate a previously allocated block and changes the pointer in-place, |
|
183 * if necessary. |
|
184 * |
|
185 * @par Error handling |
|
186 * @c errno will be set by realloc() on failure. |
|
187 * |
|
188 * @param mem (@c void**) pointer to the pointer to allocated block |
|
189 * @param n (@c size_t) the new size in bytes |
|
190 * @retval zero success |
|
191 * @retval non-zero failure |
|
192 * @see cx_reallocatearray() |
|
193 */ |
|
194 #define cx_reallocate(mem, n) cx_reallocate_((void**)(mem), n) |
|
195 |
|
196 /** |
|
197 * Reallocate a previously allocated block and changes the pointer in-place, |
|
198 * if necessary. |
|
199 * |
|
200 * The size is calculated by multiplying @p nemb and @p size. |
|
201 * |
|
202 * @par Error handling |
|
203 * @c errno will be set by realloc() on failure or when the multiplication of |
|
204 * @p nmemb and @p size overflows. |
|
205 * |
|
206 * @param mem (@c void**) pointer to the pointer to allocated block |
|
207 * @param nmemb (@c size_t) the number of elements |
|
208 * @param size (@c size_t) the size of each element |
|
209 * @retval zero success |
|
210 * @retval non-zero failure |
|
211 */ |
|
212 #define cx_reallocatearray(mem, nmemb, size) \ |
|
213 cx_reallocatearray_((void**)(mem), nmemb, size) |
|
214 |
|
215 /** |
|
216 * Free a block allocated by this allocator. |
|
217 * |
|
218 * @note Freeing a block of a different allocator is undefined. |
|
219 * |
|
220 * @param allocator the allocator |
|
221 * @param mem a pointer to the block to free |
|
222 */ |
|
223 cx_attr_nonnull_arg(1) |
|
224 cx_attr_export |
|
225 void cxFree( |
|
226 const CxAllocator *allocator, |
|
227 void *mem |
|
228 ); |
|
229 |
|
230 /** |
|
231 * Allocate @p n bytes of memory. |
153 * |
232 * |
154 * @param allocator the allocator |
233 * @param allocator the allocator |
155 * @param n the number of bytes |
234 * @param n the number of bytes |
156 * @return a pointer to the allocated memory |
235 * @return a pointer to the allocated memory |
157 */ |
236 */ |
|
237 cx_attr_nodiscard |
|
238 cx_attr_nonnull |
|
239 cx_attr_malloc |
|
240 cx_attr_dealloc_ucx |
|
241 cx_attr_allocsize(2) |
|
242 cx_attr_export |
158 void *cxMalloc( |
243 void *cxMalloc( |
159 CxAllocator const *allocator, |
244 const CxAllocator *allocator, |
160 size_t n |
245 size_t n |
161 ) |
246 ); |
162 __attribute__((__malloc__)) |
247 |
163 __attribute__((__alloc_size__(2))); |
248 /** |
164 |
249 * Reallocate the previously allocated block in @p mem, making the new block |
165 /** |
250 * @p n bytes long. |
166 * Re-allocate the previously allocated block in \p mem, making the new block \p n bytes long. |
251 * This function may return the same pointer that was passed to it, if moving |
167 * This function may return the same pointer that was passed to it, if moving the memory |
252 * the memory was not necessary. |
168 * was not necessary. |
253 * |
169 * |
254 * @note Re-allocating a block allocated by a different allocator is undefined. |
170 * \note Re-allocating a block allocated by a different allocator is undefined. |
|
171 * |
255 * |
172 * @param allocator the allocator |
256 * @param allocator the allocator |
173 * @param mem pointer to the previously allocated block |
257 * @param mem pointer to the previously allocated block |
174 * @param n the new size in bytes |
258 * @param n the new size in bytes |
175 * @return a pointer to the re-allocated memory |
259 * @return a pointer to the reallocated memory |
176 */ |
260 */ |
|
261 cx_attr_nodiscard |
|
262 cx_attr_nonnull_arg(1) |
|
263 cx_attr_dealloc_ucx |
|
264 cx_attr_allocsize(3) |
|
265 cx_attr_export |
177 void *cxRealloc( |
266 void *cxRealloc( |
178 CxAllocator const *allocator, |
267 const CxAllocator *allocator, |
179 void *mem, |
268 void *mem, |
180 size_t n |
269 size_t n |
181 ) |
270 ); |
182 __attribute__((__warn_unused_result__)) |
271 |
183 __attribute__((__alloc_size__(3))); |
272 /** |
184 |
273 * Reallocate the previously allocated block in @p mem, making the new block |
185 /** |
274 * @p n bytes long. |
186 * Re-allocate a previously allocated block and changes the pointer in-place, if necessary. |
275 * This function may return the same pointer that was passed to it, if moving |
187 * This function acts like cxRealloc() using the pointer pointed to by \p mem. |
276 * the memory was not necessary. |
188 * |
277 * |
189 * \note Re-allocating a block allocated by a different allocator is undefined. |
278 * The size is calculated by multiplying @p nemb and @p size. |
190 * |
279 * If that multiplication overflows, this function returns @c NULL and @c errno |
191 * \par Error handling |
280 * will be set. |
192 * \c errno will be set, if the underlying realloc function does so. |
281 * |
|
282 * @note Re-allocating a block allocated by a different allocator is undefined. |
|
283 * |
|
284 * @param allocator the allocator |
|
285 * @param mem pointer to the previously allocated block |
|
286 * @param nmemb the number of elements |
|
287 * @param size the size of each element |
|
288 * @return a pointer to the reallocated memory |
|
289 */ |
|
290 cx_attr_nodiscard |
|
291 cx_attr_nonnull_arg(1) |
|
292 cx_attr_dealloc_ucx |
|
293 cx_attr_allocsize(3, 4) |
|
294 cx_attr_export |
|
295 void *cxReallocArray( |
|
296 const CxAllocator *allocator, |
|
297 void *mem, |
|
298 size_t nmemb, |
|
299 size_t size |
|
300 ); |
|
301 |
|
302 /** |
|
303 * Reallocate a previously allocated block and changes the pointer in-place, |
|
304 * if necessary. |
|
305 * This function acts like cxRealloc() using the pointer pointed to by @p mem. |
|
306 * |
|
307 * @note Re-allocating a block allocated by a different allocator is undefined. |
|
308 * |
|
309 * @par Error handling |
|
310 * @c errno will be set, if the underlying realloc function does so. |
193 * |
311 * |
194 * @param allocator the allocator |
312 * @param allocator the allocator |
195 * @param mem pointer to the pointer to allocated block |
313 * @param mem pointer to the pointer to allocated block |
196 * @param n the new size in bytes |
314 * @param n the new size in bytes |
197 * @return zero on success, non-zero on failure |
315 * @retval zero success |
198 */ |
316 * @retval non-zero failure |
199 int cxReallocate( |
317 */ |
200 CxAllocator const *allocator, |
318 cx_attr_nodiscard |
|
319 cx_attr_nonnull |
|
320 cx_attr_export |
|
321 int cxReallocate_( |
|
322 const CxAllocator *allocator, |
201 void **mem, |
323 void **mem, |
202 size_t n |
324 size_t n |
203 ) |
325 ); |
204 __attribute__((__nonnull__)); |
326 |
205 |
327 /** |
206 /** |
328 * Reallocate a previously allocated block and changes the pointer in-place, |
207 * Allocate \p nelem elements of \p n bytes each, all initialized to zero. |
329 * if necessary. |
208 * |
330 * This function acts like cxRealloc() using the pointer pointed to by @p mem. |
209 * @param allocator the allocator |
331 * |
210 * @param nelem the number of elements |
332 * @note Re-allocating a block allocated by a different allocator is undefined. |
211 * @param n the size of each element in bytes |
333 * |
|
334 * @par Error handling |
|
335 * @c errno will be set, if the underlying realloc function does so. |
|
336 * |
|
337 * @param allocator (@c CxAllocator*) the allocator |
|
338 * @param mem (@c void**) pointer to the pointer to allocated block |
|
339 * @param n (@c size_t) the new size in bytes |
|
340 * @retval zero success |
|
341 * @retval non-zero failure |
|
342 */ |
|
343 #define cxReallocate(allocator, mem, n) \ |
|
344 cxReallocate_(allocator, (void**)(mem), n) |
|
345 |
|
346 /** |
|
347 * Reallocate a previously allocated block and changes the pointer in-place, |
|
348 * if necessary. |
|
349 * This function acts like cxReallocArray() using the pointer pointed to |
|
350 * by @p mem. |
|
351 * |
|
352 * @note Re-allocating a block allocated by a different allocator is undefined. |
|
353 * |
|
354 * @par Error handling |
|
355 * @c errno will be set, if the underlying realloc function does so or the |
|
356 * multiplication of @p nmemb and @p size overflows. |
|
357 * |
|
358 * @param allocator the allocator |
|
359 * @param mem pointer to the pointer to allocated block |
|
360 * @param nmemb the number of elements |
|
361 * @param size the size of each element |
|
362 * @retval zero success |
|
363 * @retval non-zero on failure |
|
364 */ |
|
365 cx_attr_nodiscard |
|
366 cx_attr_nonnull |
|
367 cx_attr_export |
|
368 int cxReallocateArray_( |
|
369 const CxAllocator *allocator, |
|
370 void **mem, |
|
371 size_t nmemb, |
|
372 size_t size |
|
373 ); |
|
374 |
|
375 /** |
|
376 * Reallocate a previously allocated block and changes the pointer in-place, |
|
377 * if necessary. |
|
378 * This function acts like cxReallocArray() using the pointer pointed to |
|
379 * by @p mem. |
|
380 * |
|
381 * @note Re-allocating a block allocated by a different allocator is undefined. |
|
382 * |
|
383 * @par Error handling |
|
384 * @c errno will be set, if the underlying realloc function does so or the |
|
385 * multiplication of @p nmemb and @p size overflows. |
|
386 * |
|
387 * @param allocator (@c CxAllocator*) the allocator |
|
388 * @param mem (@c void**) pointer to the pointer to allocated block |
|
389 * @param nmemb (@c size_t) the number of elements |
|
390 * @param size (@c size_t) the size of each element |
|
391 * @retval zero success |
|
392 * @retval non-zero failure |
|
393 */ |
|
394 #define cxReallocateArray(allocator, mem, nmemb, size) \ |
|
395 cxReallocateArray_(allocator, (void**) (mem), nmemb, size) |
|
396 |
|
397 /** |
|
398 * Allocate @p nmemb elements of @p n bytes each, all initialized to zero. |
|
399 * |
|
400 * @param allocator the allocator |
|
401 * @param nmemb the number of elements |
|
402 * @param size the size of each element in bytes |
212 * @return a pointer to the allocated memory |
403 * @return a pointer to the allocated memory |
213 */ |
404 */ |
|
405 cx_attr_nonnull_arg(1) |
|
406 cx_attr_nodiscard |
|
407 cx_attr_malloc |
|
408 cx_attr_dealloc_ucx |
|
409 cx_attr_allocsize(2, 3) |
|
410 cx_attr_export |
214 void *cxCalloc( |
411 void *cxCalloc( |
215 CxAllocator const *allocator, |
412 const CxAllocator *allocator, |
216 size_t nelem, |
413 size_t nmemb, |
217 size_t n |
414 size_t size |
218 ) |
415 ); |
219 __attribute__((__malloc__)) |
|
220 __attribute__((__alloc_size__(2, 3))); |
|
221 |
|
222 /** |
|
223 * Free a block allocated by this allocator. |
|
224 * |
|
225 * \note Freeing a block of a different allocator is undefined. |
|
226 * |
|
227 * @param allocator the allocator |
|
228 * @param mem a pointer to the block to free |
|
229 */ |
|
230 void cxFree( |
|
231 CxAllocator const *allocator, |
|
232 void *mem |
|
233 ) |
|
234 __attribute__((__nonnull__)); |
|
235 |
416 |
236 #ifdef __cplusplus |
417 #ifdef __cplusplus |
237 } // extern "C" |
418 } // extern "C" |
238 #endif |
419 #endif |
239 |
420 |