32
32
33
33
#include < cstddef>
34
34
#include < cstdint>
35
- #include < cstring >
35
+ #include < utility >
36
36
37
37
namespace godot {
38
38
@@ -64,30 +64,216 @@ namespace godot {
64
64
#endif
65
65
#endif
66
66
67
- // Should always inline, except in debug builds because it makes debugging harder.
67
+ // Should always inline, except in dev builds because it makes debugging harder,
68
+ // or `size_enabled` builds where inlining is actively avoided.
68
69
#ifndef _FORCE_INLINE_
69
- #ifdef DISABLE_FORCED_INLINE
70
+ #if defined(DEV_ENABLED) || defined(SIZE_EXTRA)
70
71
#define _FORCE_INLINE_ inline
71
72
#else
72
73
#define _FORCE_INLINE_ _ALWAYS_INLINE_
73
74
#endif
74
75
#endif
75
76
77
+ // Should never inline.
78
+ #ifndef _NO_INLINE_
79
+ #if defined(__GNUC__)
80
+ #define _NO_INLINE_ __attribute__ ((noinline))
81
+ #elif defined(_MSC_VER)
82
+ #define _NO_INLINE_ __declspec (noinline)
83
+ #else
84
+ #define _NO_INLINE_
85
+ #endif
86
+ #endif
87
+
88
+ // In some cases [[nodiscard]] will get false positives,
89
+ // we can prevent the warning in specific cases by preceding the call with a cast.
90
+ #ifndef _ALLOW_DISCARD_
91
+ #define _ALLOW_DISCARD_ (void )
92
+ #endif
93
+
76
94
// Windows badly defines a lot of stuff we'll never use. Undefine it.
77
95
#ifdef _WIN32
78
96
#undef min // override standard definition
79
97
#undef max // override standard definition
80
98
#undef ERROR // override (really stupid) wingdi.h standard definition
81
99
#undef DELETE // override (another really stupid) winnt.h standard definition
82
100
#undef MessageBox // override winuser.h standard definition
83
- #undef MIN // override standard definition
84
- #undef MAX // override standard definition
85
- #undef CLAMP // override standard definition
86
101
#undef Error
87
102
#undef OK
88
103
#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
104
+ #undef MemoryBarrier
105
+ #undef MONO_FONT
106
+ #endif
107
+
108
+ // Make room for our constexpr's below by overriding potential system-specific macros.
109
+ #undef SIGN
110
+ #undef MIN
111
+ #undef MAX
112
+ #undef CLAMP
113
+
114
+ template <typename T>
115
+ constexpr const T SIGN (const T m_v) {
116
+ return m_v > 0 ? +1 .0f : (m_v < 0 ? -1 .0f : 0 .0f );
117
+ }
118
+
119
+ template <typename T, typename T2>
120
+ constexpr auto MIN (const T m_a, const T2 m_b) {
121
+ return m_a < m_b ? m_a : m_b;
122
+ }
123
+
124
+ template <typename T, typename T2>
125
+ constexpr auto MAX (const T m_a, const T2 m_b) {
126
+ return m_a > m_b ? m_a : m_b;
127
+ }
128
+
129
+ template <typename T, typename T2, typename T3>
130
+ constexpr auto CLAMP (const T m_a, const T2 m_min, const T3 m_max) {
131
+ return m_a < m_min ? m_min : (m_a > m_max ? m_max : m_a);
132
+ }
133
+
134
+ // Generic swap template.
135
+ #ifndef SWAP
136
+ #define SWAP (m_x, m_y ) std::swap((m_x), (m_y))
137
+ #endif // SWAP
138
+
139
+ /* Functions to handle powers of 2 and shifting. */
140
+
141
+ // Returns `true` if a positive integer is a power of 2, `false` otherwise.
142
+ template <typename T>
143
+ inline bool is_power_of_2 (const T x) {
144
+ return x && ((x & (x - 1 )) == 0 );
145
+ }
146
+
147
+ // Function to find the next power of 2 to an integer.
148
+ static _FORCE_INLINE_ unsigned int next_power_of_2 (unsigned int x) {
149
+ if (x == 0 ) {
150
+ return 0 ;
151
+ }
152
+
153
+ --x;
154
+ x |= x >> 1 ;
155
+ x |= x >> 2 ;
156
+ x |= x >> 4 ;
157
+ x |= x >> 8 ;
158
+ x |= x >> 16 ;
159
+
160
+ return ++x;
161
+ }
162
+
163
+ // Function to find the previous power of 2 to an integer.
164
+ static _FORCE_INLINE_ unsigned int previous_power_of_2 (unsigned int x) {
165
+ x |= x >> 1 ;
166
+ x |= x >> 2 ;
167
+ x |= x >> 4 ;
168
+ x |= x >> 8 ;
169
+ x |= x >> 16 ;
170
+ return x - (x >> 1 );
171
+ }
172
+
173
+ // Function to find the closest power of 2 to an integer.
174
+ static _FORCE_INLINE_ unsigned int closest_power_of_2 (unsigned int x) {
175
+ unsigned int nx = next_power_of_2 (x);
176
+ unsigned int px = previous_power_of_2 (x);
177
+ return (nx - x) > (x - px) ? px : nx;
178
+ }
179
+
180
+ // Get a shift value from a power of 2.
181
+ static inline int get_shift_from_power_of_2 (unsigned int p_bits) {
182
+ for (unsigned int i = 0 ; i < 32 ; i++) {
183
+ if (p_bits == (unsigned int )(1 << i)) {
184
+ return i;
185
+ }
186
+ }
187
+
188
+ return -1 ;
189
+ }
190
+
191
+ template <typename T>
192
+ static _FORCE_INLINE_ T nearest_power_of_2_templated (T x) {
193
+ --x;
194
+
195
+ // The number of operations on x is the base two logarithm
196
+ // of the number of bits in the type. Add three to account
197
+ // for sizeof(T) being in bytes.
198
+ size_t num = get_shift_from_power_of_2 (sizeof (T)) + 3 ;
199
+
200
+ // If the compiler is smart, it unrolls this loop.
201
+ // If it's dumb, this is a bit slow.
202
+ for (size_t i = 0 ; i < num; i++) {
203
+ x |= x >> (1 << i);
204
+ }
205
+
206
+ return ++x;
207
+ }
208
+
209
+ // Function to find the nearest (bigger) power of 2 to an integer.
210
+ static inline unsigned int nearest_shift (unsigned int p_number) {
211
+ for (int i = 30 ; i >= 0 ; i--) {
212
+ if (p_number & (1 << i)) {
213
+ return i + 1 ;
214
+ }
215
+ }
216
+
217
+ return 0 ;
218
+ }
219
+
220
+ // constexpr function to find the floored log2 of a number
221
+ template <typename T>
222
+ constexpr T floor_log2 (T x) {
223
+ return x < 2 ? x : 1 + floor_log2 (x >> 1 );
224
+ }
225
+
226
+ // Get the number of bits needed to represent the number.
227
+ // IE, if you pass in 8, you will get 4.
228
+ // If you want to know how many bits are needed to store 8 values however, pass in (8 - 1).
229
+ template <typename T>
230
+ constexpr T get_num_bits (T x) {
231
+ return floor_log2 (x);
232
+ }
233
+
234
+ // Swap 16, 32 and 64 bits value for endianness.
235
+ #if defined(__GNUC__)
236
+ #define BSWAP16 (x ) __builtin_bswap16(x)
237
+ #define BSWAP32 (x ) __builtin_bswap32(x)
238
+ #define BSWAP64 (x ) __builtin_bswap64(x)
239
+ #elif defined(_MSC_VER)
240
+ #define BSWAP16 (x ) _byteswap_ushort(x)
241
+ #define BSWAP32 (x ) _byteswap_ulong(x)
242
+ #define BSWAP64 (x ) _byteswap_uint64(x)
243
+ #else
244
+ static inline uint16_t BSWAP16 (uint16_t x) {
245
+ return (x >> 8 ) | (x << 8 );
246
+ }
247
+
248
+ static inline uint32_t BSWAP32 (uint32_t x) {
249
+ return ((x << 24 ) | ((x << 8 ) & 0x00FF0000 ) | ((x >> 8 ) & 0x0000FF00 ) | (x >> 24 ));
250
+ }
251
+
252
+ static inline uint64_t BSWAP64 (uint64_t x) {
253
+ x = (x & 0x00000000FFFFFFFF ) << 32 | (x & 0xFFFFFFFF00000000 ) >> 32 ;
254
+ x = (x & 0x0000FFFF0000FFFF ) << 16 | (x & 0xFFFF0000FFFF0000 ) >> 16 ;
255
+ x = (x & 0x00FF00FF00FF00FF ) << 8 | (x & 0xFF00FF00FF00FF00 ) >> 8 ;
256
+ return x;
257
+ }
89
258
#endif
90
259
260
+ // Generic comparator used in Map, List, etc.
261
+ template <typename T>
262
+ struct Comparator {
263
+ _ALWAYS_INLINE_ bool operator ()(const T &p_a, const T &p_b) const { return (p_a < p_b); }
264
+ };
265
+
266
+ // Global lock macro, relies on the static Mutex::_global_mutex.
267
+ void _global_lock ();
268
+ void _global_unlock ();
269
+
270
+ struct _GlobalLock {
271
+ _GlobalLock () { _global_lock (); }
272
+ ~_GlobalLock () { _global_unlock (); }
273
+ };
274
+
275
+ #define GLOBAL_LOCK_FUNCTION _GlobalLock _global_lock_;
276
+
91
277
#if defined(__GNUC__)
92
278
#define likely (x ) __builtin_expect(!!(x), 1 )
93
279
#define unlikely (x ) __builtin_expect(!!(x), 0 )
@@ -96,22 +282,17 @@ namespace godot {
96
282
#define unlikely (x ) x
97
283
#endif
98
284
99
- #ifdef REAL_T_IS_DOUBLE
100
- typedef double real_t ;
285
+ #if defined(__GNUC__)
286
+ #define _PRINTF_FORMAT_ATTRIBUTE_2_0 __attribute__ ((format(printf, 2 , 0 )))
287
+ #define _PRINTF_FORMAT_ATTRIBUTE_2_3 __attribute__ ((format(printf, 2 , 3 )))
101
288
#else
102
- typedef float real_t ;
289
+ #define _PRINTF_FORMAT_ATTRIBUTE_2_0
290
+ #define _PRINTF_FORMAT_ATTRIBUTE_2_3
103
291
#endif
104
292
105
- // Generic swap template.
106
- #ifndef SWAP
107
- #define SWAP (m_x, m_y ) __swap_tmpl((m_x), (m_y))
108
- template <typename T>
109
- inline void __swap_tmpl (T &x, T &y) {
110
- T aux = x;
111
- x = y;
112
- y = aux;
113
- }
114
- #endif // SWAP
293
+ // This is needed due to a strange OpenGL API that expects a pointer
294
+ // type for an argument that is actually an offset.
295
+ #define CAST_INT_TO_UCHAR_PTR (ptr ) ((uint8_t *)(uintptr_t )(ptr))
115
296
116
297
// Home-made index sequence trick, so it can be used everywhere without the costly include of std::tuple.
117
298
// https://stackoverflow.com/questions/15014096/c-index-of-type-during-variadic-template-expansion
@@ -124,8 +305,36 @@ struct BuildIndexSequence : BuildIndexSequence<N - 1, N - 1, Is...> {};
124
305
template <size_t ... Is>
125
306
struct BuildIndexSequence <0 , Is...> : IndexSequence<Is...> {};
126
307
127
- } // namespace godot
308
+ // Limit the depth of recursive algorithms when dealing with Array/Dictionary
309
+ #define MAX_RECURSION 100
310
+
311
+ #ifdef DEBUG_ENABLED
312
+ #define DEBUG_METHODS_ENABLED
313
+ #endif
314
+
315
+ // Macro GD_IS_DEFINED() allows to check if a macro is defined. It needs to be defined to anything (say 1) to work.
316
+ #define __GDARG_PLACEHOLDER_1 false ,
317
+ #define __gd_take_second_arg (__ignored, val, ...) val
318
+ #define ____gd_is_defined (arg1_or_junk ) __gd_take_second_arg(arg1_or_junk true , false )
319
+ #define ___gd_is_defined (val ) ____gd_is_defined(__GDARG_PLACEHOLDER_##val)
320
+ #define GD_IS_DEFINED (x ) ___gd_is_defined(x)
128
321
129
- // To maintain compatibility an alias is defined outside the namespace.
130
- // Consider it deprecated.
131
- using real_t = godot::real_t ;
322
+ // Whether the default value of a type is just all-0 bytes.
323
+ // This can most commonly be exploited by using memset for these types instead of loop-construct.
324
+ // Trivially constructible types are also zero-constructible.
325
+ template <typename T>
326
+ struct is_zero_constructible : std::is_trivially_constructible<T> {};
327
+
328
+ template <typename T>
329
+ struct is_zero_constructible <const T> : is_zero_constructible<T> {};
330
+
331
+ template <typename T>
332
+ struct is_zero_constructible <volatile T> : is_zero_constructible<T> {};
333
+
334
+ template <typename T>
335
+ struct is_zero_constructible <const volatile T> : is_zero_constructible<T> {};
336
+
337
+ template <typename T>
338
+ inline constexpr bool is_zero_constructible_v = is_zero_constructible<T>::value;
339
+
340
+ } // namespace godot
0 commit comments