Monado OpenXR Runtime
u_misc.h
Go to the documentation of this file.
1 // Copyright 2019, 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
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  * @ingroup aux_util
28  */
29 #define U_CALLOC_WITH_CAST(TYPE, SIZE) ((TYPE *)calloc(1, SIZE))
30 
31 /*!
32  * Allocate and zero the space required for some type, and cast the return type
33  * appropriately.
34  *
35  * Use instead of a bare calloc when allocating a single structure.
36  *
37  * @ingroup aux_util
38  */
39 #define U_TYPED_CALLOC(TYPE) ((TYPE *)calloc(1, sizeof(TYPE)))
40 
41 /*!
42  * Allocate and zero the space required for some type, and cast the return type
43  * appropriately.
44  *
45  * Use instead of a bare calloc when allocating an array of a type.
46  * This includes allocating C strings: pass char as the type.
47  *
48  * @ingroup aux_util
49  */
50 #define U_TYPED_ARRAY_CALLOC(TYPE, COUNT) \
51  ((TYPE *)calloc((COUNT), sizeof(TYPE)))
52 
53 /*!
54  * Zeroes the correct amount of memory based on the type pointed-to by the
55  * argument.
56  *
57  * Use instead of memset(..., 0, ...) on a structure or pointer to structure.
58  *
59  * @ingroup aux_util
60  */
61 #define U_ZERO(PTR) memset((PTR), 0, sizeof(*(PTR)))
62 
63 /*!
64  * Zeroes the correct amount of memory based on the type and size of the static
65  * array named in the argument.
66  *
67  * Use instead of memset(..., 0, ...) on an array.
68  *
69  * @ingroup aux_util
70  */
71 #define U_ZERO_ARRAY(ARRAY) memset((ARRAY), 0, sizeof(ARRAY))
72 
73 /*!
74  * Reallocates or frees dynamically-allocated memory.
75  *
76  * Just wraps realloc with a return value check, freeing the provided memory if
77  * it is NULL, to avoid leaks. Use U_ARRAY_REALLOC_OR_FREE() instead.
78  *
79  * @ingroup aux_util
80  */
81 static inline void *
82 u_realloc_or_free(void *ptr, size_t new_size)
83 {
84  void *ret = realloc(ptr, new_size);
85  if (ret == NULL) {
86  free(ptr);
87  }
88  return ret;
89 }
90 
91 /*!
92  * Re-allocate the space required for some type, and update the pointer -
93  * freeing the allocation instead if it can't be resized.
94  *
95  * Use instead of a bare realloc when allocating an array of a type.
96  * This includes reallocating C strings: pass char as the type.
97  *
98  * Be sure not to parenthesize the type! It will cause an error like "expression
99  * expected".
100  *
101  * On the other hand, if you get an incompatible types error in assignment,
102  * that's a type mismatch, a real bug.
103  *
104  * @ingroup aux_util
105  */
106 #define U_ARRAY_REALLOC_OR_FREE(VAR, TYPE, COUNT) \
107  (VAR) = ((TYPE *)u_realloc_or_free((VAR), sizeof(TYPE) * (COUNT)))
108 
109 #ifdef __cplusplus
110 }
111 #endif