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