1/**************************************************************************/
2/* typedefs.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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 first in case the platform needs to pre-define/include some things.
41#include "platform_config.h"
42
43// Should be available everywhere.
44#include "core/error/error_list.h"
45#include <cstdint>
46
47// Turn argument to string constant:
48// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing
49#ifndef _STR
50#define _STR(m_x) #m_x
51#define _MKSTR(m_x) _STR(m_x)
52#endif
53
54// Should always inline no matter what.
55#ifndef _ALWAYS_INLINE_
56#if defined(__GNUC__)
57#define _ALWAYS_INLINE_ __attribute__((always_inline)) inline
58#elif defined(_MSC_VER)
59#define _ALWAYS_INLINE_ __forceinline
60#else
61#define _ALWAYS_INLINE_ inline
62#endif
63#endif
64
65// Should always inline, except in dev builds because it makes debugging harder.
66#ifndef _FORCE_INLINE_
67#ifdef DEV_ENABLED
68#define _FORCE_INLINE_ inline
69#else
70#define _FORCE_INLINE_ _ALWAYS_INLINE_
71#endif
72#endif
73
74// No discard allows the compiler to flag warnings if we don't use the return value of functions / classes
75#ifndef _NO_DISCARD_
76#define _NO_DISCARD_ [[nodiscard]]
77#endif
78
79// In some cases _NO_DISCARD_ will get false positives,
80// we can prevent the warning in specific cases by preceding the call with a cast.
81#ifndef _ALLOW_DISCARD_
82#define _ALLOW_DISCARD_ (void)
83#endif
84
85// Windows badly defines a lot of stuff we'll never use. Undefine it.
86#ifdef _WIN32
87#undef min // override standard definition
88#undef max // override standard definition
89#undef ERROR // override (really stupid) wingdi.h standard definition
90#undef DELETE // override (another really stupid) winnt.h standard definition
91#undef MessageBox // override winuser.h standard definition
92#undef Error
93#undef OK
94#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
95#endif
96
97// Make room for our constexpr's below by overriding potential system-specific macros.
98#undef ABS
99#undef SIGN
100#undef MIN
101#undef MAX
102#undef CLAMP
103
104// Generic ABS function, for math uses please use Math::abs.
105template <typename T>
106constexpr T ABS(T m_v) {
107 return m_v < 0 ? -m_v : m_v;
108}
109
110template <typename T>
111constexpr const T SIGN(const T m_v) {
112 return m_v > 0 ? +1.0f : (m_v < 0 ? -1.0f : 0.0f);
113}
114
115template <typename T, typename T2>
116constexpr auto MIN(const T m_a, const T2 m_b) {
117 return m_a < m_b ? m_a : m_b;
118}
119
120template <typename T, typename T2>
121constexpr auto MAX(const T m_a, const T2 m_b) {
122 return m_a > m_b ? m_a : m_b;
123}
124
125template <typename T, typename T2, typename T3>
126constexpr auto CLAMP(const T m_a, const T2 m_min, const T3 m_max) {
127 return m_a < m_min ? m_min : (m_a > m_max ? m_max : m_a);
128}
129
130// Generic swap template.
131#ifndef SWAP
132#define SWAP(m_x, m_y) __swap_tmpl((m_x), (m_y))
133template <class T>
134inline void __swap_tmpl(T &x, T &y) {
135 T aux = x;
136 x = y;
137 y = aux;
138}
139#endif // SWAP
140
141/* Functions to handle powers of 2 and shifting. */
142
143// Function to find the next power of 2 to an integer.
144static _FORCE_INLINE_ unsigned int next_power_of_2(unsigned int x) {
145 if (x == 0) {
146 return 0;
147 }
148
149 --x;
150 x |= x >> 1;
151 x |= x >> 2;
152 x |= x >> 4;
153 x |= x >> 8;
154 x |= x >> 16;
155
156 return ++x;
157}
158
159// Function to find the previous power of 2 to an integer.
160static _FORCE_INLINE_ unsigned int previous_power_of_2(unsigned int x) {
161 x |= x >> 1;
162 x |= x >> 2;
163 x |= x >> 4;
164 x |= x >> 8;
165 x |= x >> 16;
166 return x - (x >> 1);
167}
168
169// Function to find the closest power of 2 to an integer.
170static _FORCE_INLINE_ unsigned int closest_power_of_2(unsigned int x) {
171 unsigned int nx = next_power_of_2(x);
172 unsigned int px = previous_power_of_2(x);
173 return (nx - x) > (x - px) ? px : nx;
174}
175
176// Get a shift value from a power of 2.
177static inline int get_shift_from_power_of_2(unsigned int p_bits) {
178 for (unsigned int i = 0; i < 32; i++) {
179 if (p_bits == (unsigned int)(1 << i)) {
180 return i;
181 }
182 }
183
184 return -1;
185}
186
187template <class T>
188static _FORCE_INLINE_ T nearest_power_of_2_templated(T x) {
189 --x;
190
191 // The number of operations on x is the base two logarithm
192 // of the number of bits in the type. Add three to account
193 // for sizeof(T) being in bytes.
194 size_t num = get_shift_from_power_of_2(sizeof(T)) + 3;
195
196 // If the compiler is smart, it unrolls this loop.
197 // If it's dumb, this is a bit slow.
198 for (size_t i = 0; i < num; i++) {
199 x |= x >> (1 << i);
200 }
201
202 return ++x;
203}
204
205// Function to find the nearest (bigger) power of 2 to an integer.
206static inline unsigned int nearest_shift(unsigned int p_number) {
207 for (int i = 30; i >= 0; i--) {
208 if (p_number & (1 << i)) {
209 return i + 1;
210 }
211 }
212
213 return 0;
214}
215
216// constexpr function to find the floored log2 of a number
217template <typename T>
218constexpr T floor_log2(T x) {
219 return x < 2 ? x : 1 + floor_log2(x >> 1);
220}
221
222// Get the number of bits needed to represent the number.
223// IE, if you pass in 8, you will get 4.
224// If you want to know how many bits are needed to store 8 values however, pass in (8 - 1).
225template <typename T>
226constexpr T get_num_bits(T x) {
227 return floor_log2(x);
228}
229
230// Swap 16, 32 and 64 bits value for endianness.
231#if defined(__GNUC__)
232#define BSWAP16(x) __builtin_bswap16(x)
233#define BSWAP32(x) __builtin_bswap32(x)
234#define BSWAP64(x) __builtin_bswap64(x)
235#else
236static inline uint16_t BSWAP16(uint16_t x) {
237 return (x >> 8) | (x << 8);
238}
239
240static inline uint32_t BSWAP32(uint32_t x) {
241 return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
242}
243
244static inline uint64_t BSWAP64(uint64_t x) {
245 x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
246 x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
247 x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
248 return x;
249}
250#endif
251
252// Generic comparator used in Map, List, etc.
253template <class T>
254struct Comparator {
255 _ALWAYS_INLINE_ bool operator()(const T &p_a, const T &p_b) const { return (p_a < p_b); }
256};
257
258// Global lock macro, relies on the static Mutex::_global_mutex.
259void _global_lock();
260void _global_unlock();
261
262struct _GlobalLock {
263 _GlobalLock() { _global_lock(); }
264 ~_GlobalLock() { _global_unlock(); }
265};
266
267#define GLOBAL_LOCK_FUNCTION _GlobalLock _global_lock_;
268
269#if defined(__GNUC__)
270#define likely(x) __builtin_expect(!!(x), 1)
271#define unlikely(x) __builtin_expect(!!(x), 0)
272#else
273#define likely(x) x
274#define unlikely(x) x
275#endif
276
277#if defined(__GNUC__)
278#define _PRINTF_FORMAT_ATTRIBUTE_2_0 __attribute__((format(printf, 2, 0)))
279#define _PRINTF_FORMAT_ATTRIBUTE_2_3 __attribute__((format(printf, 2, 3)))
280#else
281#define _PRINTF_FORMAT_ATTRIBUTE_2_0
282#define _PRINTF_FORMAT_ATTRIBUTE_2_3
283#endif
284
285// This is needed due to a strange OpenGL API that expects a pointer
286// type for an argument that is actually an offset.
287#define CAST_INT_TO_UCHAR_PTR(ptr) ((uint8_t *)(uintptr_t)(ptr))
288
289// Home-made index sequence trick, so it can be used everywhere without the costly include of std::tuple.
290// https://stackoverflow.com/questions/15014096/c-index-of-type-during-variadic-template-expansion
291template <size_t... Is>
292struct IndexSequence {};
293
294template <size_t N, size_t... Is>
295struct BuildIndexSequence : BuildIndexSequence<N - 1, N - 1, Is...> {};
296
297template <size_t... Is>
298struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {};
299
300// Limit the depth of recursive algorithms when dealing with Array/Dictionary
301#define MAX_RECURSION 100
302
303#ifdef DEBUG_ENABLED
304#define DEBUG_METHODS_ENABLED
305#endif
306
307// Macro GD_IS_DEFINED() allows to check if a macro is defined. It needs to be defined to anything (say 1) to work.
308#define __GDARG_PLACEHOLDER_1 false,
309#define __gd_take_second_arg(__ignored, val, ...) val
310#define ____gd_is_defined(arg1_or_junk) __gd_take_second_arg(arg1_or_junk true, false)
311#define ___gd_is_defined(val) ____gd_is_defined(__GDARG_PLACEHOLDER_##val)
312#define GD_IS_DEFINED(x) ___gd_is_defined(x)
313
314#endif // TYPEDEFS_H
315