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
16 extern "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  */
88 static inline void *
89 u_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