Monado OpenXR Runtime
u_misc.h
Go to the documentation of this file.
1// Copyright 2019-2023, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Very small misc utils.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup aux_util
8 */
9
10#pragma once
11
12#include <stdlib.h> // for calloc
13#include <string.h> // for memset // IWYU pragma: keep
14
15#ifdef __cplusplus
16extern "C" {
17#endif
18
19
20/*!
21 * Allocate and zero the give size and casts the memory into a pointer of the
22 * given type.
23 *
24 * Use instead of a bare calloc, but only when U_TYPED_CALLOC and
25 * U_TYPED_ARRAY_CALLOC do not meet your needs.
26 *
27 * - If you are using `U_CALLOC_WITH_CAST(struct MyStruct, sizeof(MyStruct))` to
28 * allocate a single structure of fixed size, you should actually use
29 * `U_TYPED_CALLOC(struct MyStruct)`.
30 *
31 * - If you are using `U_CALLOC_WITH_CAST(struct MyStruct, sizeof(MyStruct) *
32 * n)` to allocate an array, you should actually use
33 * `U_TYPED_ARRAY_CALLOC(struct MyStruct, n)`.
34 *
35 * @ingroup aux_util
36 */
37#define U_CALLOC_WITH_CAST(TYPE, SIZE) ((TYPE *)calloc(1, SIZE))
38
39/*!
40 * Allocate and zero the space required for some type, and cast the return type
41 * appropriately.
42 *
43 * Use instead of a bare calloc when allocating a single structure.
44 *
45 * @ingroup aux_util
46 */
47#define U_TYPED_CALLOC(TYPE) ((TYPE *)calloc(1, sizeof(TYPE)))
48
49/*!
50 * Allocate and zero the space required for some type, and cast the return type
51 * appropriately.
52 *
53 * Use instead of a bare calloc when allocating an array of a type.
54 * This includes allocating C strings: pass char as the type.
55 *
56 * @ingroup aux_util
57 */
58#define U_TYPED_ARRAY_CALLOC(TYPE, COUNT) ((TYPE *)calloc((COUNT), sizeof(TYPE)))
59
60/*!
61 * Zeroes the correct amount of memory based on the type pointed-to by the
62 * argument.
63 *
64 * Use instead of memset(..., 0, ...) on a structure or pointer to structure.
65 *
66 * @ingroup aux_util
67 */
68#define U_ZERO(PTR) memset((PTR), 0, sizeof(*(PTR)))
69
70/*!
71 * Zeroes the correct amount of memory based on the type and size of the static
72 * array named in the argument.
73 *
74 * Use instead of memset(..., 0, ...) on an array.
75 *
76 * @ingroup aux_util
77 */
78#define U_ZERO_ARRAY(ARRAY) memset((ARRAY), 0, sizeof(ARRAY))
79
80/*!
81 * Reallocates or frees dynamically-allocated memory.
82 *
83 * Wraps realloc with a return value check, freeing the provided memory if
84 * it is NULL, to avoid leaks. Use U_ARRAY_REALLOC_OR_FREE() instead.
85 *
86 * @ingroup aux_util
87 */
88static inline void *
89u_realloc_or_free(void *ptr, size_t new_size)
90{
91 void *ret = realloc(ptr, new_size);
92 if (ret == NULL && new_size != 0) {
93 /*
94 * We only need to call free if the new size isn't zero, and
95 * that realloc failed to allocate a new array.
96 */
97 free(ptr);
98 }
99 return ret;
100}
101
102/*!
103 * Re-allocate the space required for some type, and update the pointer -
104 * freeing the allocation instead if it can't be resized.
105 *
106 * Use instead of a bare realloc when allocating an array of a type.
107 * This includes reallocating C strings: pass char as the type.
108 *
109 * Be sure not to parenthesize the type! It will cause an error like "expression
110 * expected".
111 *
112 * On the other hand, if you get an incompatible types error in assignment,
113 * that's a type mismatch, a real bug.
114 *
115 * @ingroup aux_util
116 */
117#define U_ARRAY_REALLOC_OR_FREE(VAR, TYPE, COUNT) (VAR) = ((TYPE *)u_realloc_or_free((VAR), sizeof(TYPE) * (COUNT)))
118
119#ifdef __cplusplus
120}
121#endif
static void * u_realloc_or_free(void *ptr, size_t new_size)
Reallocates or frees dynamically-allocated memory.
Definition: u_misc.h:89