1 /*************************************************************************/
2 /* typedefs.h */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30
31 #ifndef TYPEDEFS_H
32 #define TYPEDEFS_H
33
34 #include <stddef.h>
35
36 /**
37 * Basic definitions and simple functions to be used everywhere.
38 */
39
40 #include "platform_config.h"
41
42 #ifndef _STR
43 #define _STR(m_x) #m_x
44 #define _MKSTR(m_x) _STR(m_x)
45 #endif
46
47 //should always inline no matter what
48 #ifndef _ALWAYS_INLINE_
49
50 #if defined(__GNUC__) && (__GNUC__ >= 4)
51 #define _ALWAYS_INLINE_ __attribute__((always_inline)) inline
52 #elif defined(__llvm__)
53 #define _ALWAYS_INLINE_ __attribute__((always_inline)) inline
54 #elif defined(_MSC_VER)
55 #define _ALWAYS_INLINE_ __forceinline
56 #else
57 #define _ALWAYS_INLINE_ inline
58 #endif
59
60 #endif
61
62 //should always inline, except in some cases because it makes debugging harder
63 #ifndef _FORCE_INLINE_
64
65 #ifdef DISABLE_FORCED_INLINE
66 #define _FORCE_INLINE_ inline
67 #else
68 #define _FORCE_INLINE_ _ALWAYS_INLINE_
69 #endif
70
71 #endif
72
73 //custom, gcc-safe offsetof, because gcc complains a lot.
74 template <class T>
_nullptr()75 T *_nullptr() {
76 T *t = NULL;
77 return t;
78 }
79
80 #define OFFSET_OF(st, m) \
81 ((size_t)((char *)&(_nullptr<st>()->m) - (char *)0))
82 /**
83 * Some platforms (devices) don't define NULL
84 */
85
86 #ifndef NULL
87 #define NULL 0
88 #endif
89
90 /**
91 * Windows badly defines a lot of stuff we'll never use. Undefine it.
92 */
93
94 #ifdef _WIN32
95 #undef min // override standard definition
96 #undef max // override standard definition
97 #undef ERROR // override (really stupid) wingdi.h standard definition
98 #undef DELETE // override (another really stupid) winnt.h standard definition
99 #undef MessageBox // override winuser.h standard definition
100 #undef MIN // override standard definition
101 #undef MAX // override standard definition
102 #undef CLAMP // override standard definition
103 #undef Error
104 #undef OK
105 #undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
106 #endif
107
108 #include "core/int_types.h"
109
110 #include "core/error_list.h"
111
112 /** Generic ABS function, for math uses please use Math::abs */
113
114 #ifndef ABS
115 #define ABS(m_v) (((m_v) < 0) ? (-(m_v)) : (m_v))
116 #endif
117
118 #define ABSDIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
119
120 #ifndef SGN
121 #define SGN(m_v) (((m_v) < 0) ? (-1.0) : (+1.0))
122 #endif
123
124 #ifndef MIN
125 #define MIN(m_a, m_b) (((m_a) < (m_b)) ? (m_a) : (m_b))
126 #endif
127
128 #ifndef MAX
129 #define MAX(m_a, m_b) (((m_a) > (m_b)) ? (m_a) : (m_b))
130 #endif
131
132 #ifndef CLAMP
133 #define CLAMP(m_a, m_min, m_max) (((m_a) < (m_min)) ? (m_min) : (((m_a) > (m_max)) ? m_max : m_a))
134 #endif
135
136 /** Generic swap template */
137 #ifndef SWAP
138
139 #define SWAP(m_x, m_y) __swap_tmpl((m_x), (m_y))
140 template <class T>
__swap_tmpl(T & x,T & y)141 inline void __swap_tmpl(T &x, T &y) {
142
143 T aux = x;
144 x = y;
145 y = aux;
146 }
147
148 #endif //swap
149
150 /* clang-format off */
151 #define HEX2CHR(m_hex) \
152 ((m_hex >= '0' && m_hex <= '9') ? (m_hex - '0') : \
153 ((m_hex >= 'A' && m_hex <= 'F') ? (10 + m_hex - 'A') : \
154 ((m_hex >= 'a' && m_hex <= 'f') ? (10 + m_hex - 'a') : 0)))
155 /* clang-format on */
156
157 // Macro to check whether we are compiled by clang
158 // and we have a specific builtin
159 #if defined(__llvm__) && defined(__has_builtin)
160 #define _llvm_has_builtin(x) __has_builtin(x)
161 #else
162 #define _llvm_has_builtin(x) 0
163 #endif
164
165 #if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_mul_overflow)
166 #define _mul_overflow __builtin_mul_overflow
167 #endif
168
169 #if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_add_overflow)
170 #define _add_overflow __builtin_add_overflow
171 #endif
172
173 /** Function to find the next power of 2 to an integer */
174
next_power_of_2(unsigned int x)175 static _FORCE_INLINE_ unsigned int next_power_of_2(unsigned int x) {
176
177 if (x == 0)
178 return 0;
179
180 --x;
181 x |= x >> 1;
182 x |= x >> 2;
183 x |= x >> 4;
184 x |= x >> 8;
185 x |= x >> 16;
186
187 return ++x;
188 }
189
previous_power_of_2(unsigned int x)190 static _FORCE_INLINE_ unsigned int previous_power_of_2(unsigned int x) {
191
192 x |= x >> 1;
193 x |= x >> 2;
194 x |= x >> 4;
195 x |= x >> 8;
196 x |= x >> 16;
197 return x - (x >> 1);
198 }
199
closest_power_of_2(unsigned int x)200 static _FORCE_INLINE_ unsigned int closest_power_of_2(unsigned int x) {
201
202 unsigned int nx = next_power_of_2(x);
203 unsigned int px = previous_power_of_2(x);
204 return (nx - x) > (x - px) ? px : nx;
205 }
206
207 // We need this definition inside the function below.
208 static inline int get_shift_from_power_of_2(unsigned int p_pixel);
209
210 template <class T>
nearest_power_of_2_templated(T x)211 static _FORCE_INLINE_ T nearest_power_of_2_templated(T x) {
212
213 --x;
214
215 // The number of operations on x is the base two logarithm
216 // of the p_number of bits in the type. Add three to account
217 // for sizeof(T) being in bytes.
218 size_t num = get_shift_from_power_of_2(sizeof(T)) + 3;
219
220 // If the compiler is smart, it unrolls this loop
221 // If its dumb, this is a bit slow.
222 for (size_t i = 0; i < num; i++)
223 x |= x >> (1 << i);
224
225 return ++x;
226 }
227
228 /** Function to find the nearest (bigger) power of 2 to an integer */
229
nearest_shift(unsigned int p_number)230 static inline unsigned int nearest_shift(unsigned int p_number) {
231
232 for (int i = 30; i >= 0; i--) {
233
234 if (p_number & (1 << i))
235 return i + 1;
236 }
237
238 return 0;
239 }
240
241 /** get a shift value from a power of 2 */
get_shift_from_power_of_2(unsigned int p_pixel)242 static inline int get_shift_from_power_of_2(unsigned int p_pixel) {
243 // return a GL_TEXTURE_SIZE_ENUM
244
245 for (unsigned int i = 0; i < 32; i++) {
246
247 if (p_pixel == (unsigned int)(1 << i))
248 return i;
249 }
250
251 return -1;
252 }
253
254 /** Swap 16 bits value for endianness */
255 #if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap16)
256 #define BSWAP16(x) __builtin_bswap16(x)
257 #else
BSWAP16(uint16_t x)258 static inline uint16_t BSWAP16(uint16_t x) {
259 return (x >> 8) | (x << 8);
260 }
261 #endif
262
263 /** Swap 32 bits value for endianness */
264 #if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap32)
265 #define BSWAP32(x) __builtin_bswap32(x)
266 #else
BSWAP32(uint32_t x)267 static inline uint32_t BSWAP32(uint32_t x) {
268 return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
269 }
270 #endif
271
272 /** Swap 64 bits value for endianness */
273 #if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap64)
274 #define BSWAP64(x) __builtin_bswap64(x)
275 #else
BSWAP64(uint64_t x)276 static inline uint64_t BSWAP64(uint64_t x) {
277 x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
278 x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
279 x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
280 return x;
281 }
282 #endif
283
284 /** When compiling with RTTI, we can add an "extra"
285 * layer of safeness in many operations, so dynamic_cast
286 * is used besides casting by enum.
287 */
288
289 template <class T>
290 struct Comparator {
291
operatorComparator292 _ALWAYS_INLINE_ bool operator()(const T &p_a, const T &p_b) const { return (p_a < p_b); }
293 };
294
295 void _global_lock();
296 void _global_unlock();
297
298 struct _GlobalLock {
299
_GlobalLock_GlobalLock300 _GlobalLock() { _global_lock(); }
~_GlobalLock_GlobalLock301 ~_GlobalLock() { _global_unlock(); }
302 };
303
304 #define GLOBAL_LOCK_FUNCTION _GlobalLock _global_lock_;
305
306 #ifdef NO_SAFE_CAST
307 #define SAFE_CAST static_cast
308 #else
309 #define SAFE_CAST dynamic_cast
310 #endif
311
312 #define MT_SAFE
313
314 #define __STRX(m_index) #m_index
315 #define __STR(m_index) __STRX(m_index)
316
317 #ifdef __GNUC__
318 #define likely(x) __builtin_expect(!!(x), 1)
319 #define unlikely(x) __builtin_expect(!!(x), 0)
320 #else
321 #define likely(x) x
322 #define unlikely(x) x
323 #endif
324
325 #if defined(__GNUC__)
326 #define _PRINTF_FORMAT_ATTRIBUTE_2_0 __attribute__((format(printf, 2, 0)))
327 #define _PRINTF_FORMAT_ATTRIBUTE_2_3 __attribute__((format(printf, 2, 3)))
328 #else
329 #define _PRINTF_FORMAT_ATTRIBUTE_2_0
330 #define _PRINTF_FORMAT_ATTRIBUTE_2_3
331 #endif
332
333 /** This is needed due to a strange OpenGL API that expects a pointer
334 * type for an argument that is actually an offset.
335 */
336 #define CAST_INT_TO_UCHAR_PTR(ptr) ((uint8_t *)(uintptr_t)(ptr))
337
338 /** Hint for compilers that this fallthrough in a switch is intentional.
339 * Can be replaced by [[fallthrough]] annotation if we move to C++17.
340 * Including conditional support for it for people who set -std=c++17
341 * themselves.
342 * Requires a trailing semicolon when used.
343 */
344 #if __cplusplus >= 201703L
345 #define FALLTHROUGH [[fallthrough]]
346 #elif defined(__GNUC__) && __GNUC__ >= 7
347 #define FALLTHROUGH __attribute__((fallthrough))
348 #elif defined(__llvm__) && __cplusplus >= 201103L && defined(__has_feature)
349 #if __has_feature(cxx_attributes) && defined(__has_warning)
350 #if __has_warning("-Wimplicit-fallthrough")
351 #define FALLTHROUGH [[clang::fallthrough]]
352 #endif
353 #endif
354 #endif
355
356 #ifndef FALLTHROUGH
357 #define FALLTHROUGH
358 #endif
359
360 #endif // TYPEDEFS_H
361