UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
rrCore.h
Go to the documentation of this file.
1// Copyright Epic Games Tools, LLC. All Rights Reserved. Global types header file
2
3#if !defined(__RADRR_CORE2H__)
4#define __RADRR_CORE2H__
5
6#ifdef USING_EGT
7#include "egttypes.h"
8#else
9#include "radtypes.h"
10#endif
11
12#include <stddef.h>
13
14#ifdef __RADFINAL__
15 #define RADTODO(str) { char __str[0]=str; }
16#else
17 #define RADTODO(str)
18#endif
19
20#if defined __RADMAC__ || defined __RADIPHONE__
21 #define __RADBSD__
22#endif
23
24#if defined __RADBSD__ || defined __RADLINUX__ || defined __RADQNX__
25 #define __RADPOSIX__
26#endif
27
28#ifdef __RAD64__
29 #define RAD_PTRBITS 64
30 #define RAD_PTRBYTES 8
31 #define RAD_TWOPTRBYTES 16
32#else
33 #define RAD_PTRBITS 32
34 #define RAD_PTRBYTES 4
35 #define RAD_TWOPTRBYTES 8
36#endif
37
38#if defined(__RADMAC__)
39 #ifndef __RADINDLL__ // only non-DLL pc platforms get auto-TLS
40 #define RAD_TLS(type,var) __thread type var
41 #endif
42 #define RR_BREAK() __builtin_trap()
43 #ifdef __RADARM__
44 #define RR_CACHE_LINE_SIZE 32
45 #else
46 #define RR_CACHE_LINE_SIZE 64
47 #endif
48 #define RAD_GUARANTEED_SSE3 // always sse3 on mac
49 #define RAD_USES_SSE3 // don't need any special markup for sse3 on mac
50 #define RAD_USES_SSSE3 // don't need any special markup for ssse3 on mac
51#endif
52#if defined(__RADIPHONE__)
53 #define RR_BREAK() __builtin_trap()
54 #define RR_CACHE_LINE_SIZE 32
55 #define RAD_GUARANTEED_SSE3 // simulator has sse3
56 #define RAD_USES_SSE3 // don't need any special markup for sse3 on sim
57#endif
58#if defined(__RADANDROID__)
59 #define RR_BREAK() __builtin_trap()
60 #ifdef __RADARM__
61 #define RR_CACHE_LINE_SIZE 32
62 #elif defined(__RADX86__)
63 #ifndef RR_CACHE_LINE_SIZE
64 #define RR_CACHE_LINE_SIZE 64
65 #endif
66 #endif
67#endif
68
69#if defined(__RADLINUX__)
70 #ifndef __RADINDLL__ // only non-DLL pc platforms get auto-TLS
71 #define RAD_TLS(type,var) __thread type var
72 #endif
73 #define RR_BREAK() __builtin_trap()
74 #ifdef __RADARM__
75 #define RR_CACHE_LINE_SIZE 32
76 #else
77 #define RR_CACHE_LINE_SIZE 64
78 #endif
79#endif
80#if defined(__RADQNX__)
81 #define RR_BREAK() __builtin_trap()
82 #ifdef __RADARM__
83 #define RR_CACHE_LINE_SIZE 32
84 #else
85 #define RR_CACHE_LINE_SIZE 64
86 #endif
87#endif
88#if defined(__RADWINRT__)
89 #ifdef __RAD64__
90 #define __RAD64REGS__
91 #endif
92 #ifdef __RADARM__
93 #define RR_CACHE_LINE_SIZE 32
94 #else
95 #define RR_CACHE_LINE_SIZE 64
96 #endif
97 #define RR_BREAK __debugbreak
98#endif
99#if defined(__RADNT__)
100 #define RADASMLINK __cdecl
101 #ifndef __RADINDLL__ // only non-DLL pc platforms get auto-TLS
102 #define RAD_TLS(type,var) __declspec(thread) type var
103 #endif
104 #ifdef __RAD64__
105 #define __RAD64REGS__
106 #endif
107 #ifdef __RADARM__
108 #define RR_CACHE_LINE_SIZE 32
109 #else
110 #define RR_CACHE_LINE_SIZE 64
111 #endif
112 #if defined(_MSC_VER) && _MSC_VER >= 1300
113 #define RR_BREAK __debugbreak
114 #else
115 #define RR_BREAK() RAD_STATEMENT_WRAPPER( __asm {int 3} )
116 #endif
117#endif
118
119#if defined(__RADEMSCRIPTEN__)
120 #define RR_BREAK() __builtin_trap()
121 #define RR_CACHE_LINE_SIZE 64
122#endif
123
124#if !defined(RR_BREAK)
125 #error "No rr_break defined!"
126#endif
127
128
129#ifdef __RAD64REGS__
130 #define RAD_UINTr RAD_U64
131 #define RAD_SINTr RAD_S64
132#else
133 #define RAD_UINTr RAD_U32
134 #define RAD_SINTr RAD_S32
135#endif
136
137
138#ifdef __RADNTBUILDLINUX__
139 #undef RADLINK
140 #undef RADEXPLINK
141 #undef RADDLLEXPORTDLL
142 #undef RADDLLIMPORTDLL
143
144 #define RADLINK
145 #define RADEXPLINK
146 #define RADDLLEXPORTDLL
147 #define RADDLLIMPORTDLL
148#endif
149
150// make sure your symbols are unique with these next macros!
151// if you have a duplicate symbol and they are different sizes,
152// then you will get a warning. Same size, though? MERGED!! Careful!
153// Use RRSTRIPPABLE on private vars
154// Use RRSTRIPPABLEPUB on public vars
155#ifdef _MSC_VER
156#define RRSTRIPPABLE __declspec(selectany)
157#define RRSTRIPPABLEPUB __declspec(selectany)
158#else
159#define RRSTRIPPABLE static
160#define RRSTRIPPABLEPUB
161#endif
162
163//===========================================================================
164// RADASSUME(expr) tells the compiler that expr is always true
165// RADUNREACHABLE must never be reachable - even in event of error
166// eg. it's okay for compiler to generate completely invalid code after RADUNREACHABLE
167// RADFORCEINLINE and RADNOINLINE are what you would expect
168#ifdef _MSC_VER
169 #if (_MSC_VER >= 1300)
170 #define RAD_ALIGN(type,var,num) type __declspec(align(num)) var
171 #define RADNOINLINE __declspec(noinline)
172 #else
173 #define RADNOINLINE
174 #endif
175
176 #ifndef RAD_USES_SSE3
177 #define RAD_USES_SSE3 // vs2008+ can compile SSE3 with no special markup
178 #endif
179 #ifndef RAD_USES_SSSE3
180 #define RAD_USES_SSSE3 // vs2008+ can compile SSSE3 with no special markup
181 #endif
182
183 #define RADFORCEINLINE __forceinline
184 #define RADUNREACHABLE __assume(0)
185 #define RADASSUME(exp) __assume(exp)
186 #ifndef __RADINDLL__
187 #define RAD_TLS(type,var) __declspec(thread) type var
188 #endif
189 #define RAD_EXPECT(expr,cond) (expr)
190
191#elif defined(__clang__) //================================
192
193 #define RAD_ALIGN(type,var,num) type __attribute__ ((aligned (num))) var
194 #ifdef _DEBUG
195 #define RADFORCEINLINE inline
196 #else
197 #define RADFORCEINLINE inline __attribute((always_inline))
198 #endif
199
200 #ifndef RAD_USES_SSE3
201 #define RAD_USES_SSE3 __attribute__((target("sse3")))
202 #endif
203 #if !defined(RAD_USES_SSSE3) && !defined(__RADIPHONE__) // if it isn't already defined, define SSSE3 macro for all platforms except iphone sim!
204 #define RAD_USES_SSSE3 __attribute__((target("ssse3")))
205 #endif
206
207 #define RADNOINLINE __attribute__((noinline))
208 #define RADUNREACHABLE __builtin_unreachable()
209 #if __has_builtin(__builtin_assume)
210 #define RADASSUME(exp) __builtin_assume(exp)
211 #else
212 #define RADASSUME(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) __builtin_unreachable(); )
213 #endif
214 #define RAD_EXPECT(expr,cond) __builtin_expect(expr,cond)
215
216#elif (defined(__GCC__) || defined(__GNUC__)) || defined(ANDROID) //================================
217
218 #define RAD_ALIGN(type,var,num) type __attribute__ ((aligned (num))) var
219 #ifdef _DEBUG
220 #define RADFORCEINLINE inline
221 #else
222 #define RADFORCEINLINE inline __attribute((always_inline))
223 #endif
224 #define RADNOINLINE __attribute__((noinline))
225
226 #define __RAD_GCC_VERSION__ (__GNUC__ * 10000 \
227 + __GNUC_MINOR__ * 100 \
228 + __GNUC_PATCHLEVEL__)
229
230 #if __RAD_GCC_VERSION__ >= 40500
231 #define RADUNREACHABLE __builtin_unreachable()
232 #define RADASSUME(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) __builtin_unreachable(); )
233 #else
234 #define RADUNREACHABLE RAD_INFINITE_LOOP( RR_BREAK(); )
235 #define RADASSUME(exp)
236 #endif
237
238 #if __RAD_GCC_VERSION__ >= 40600
239 #ifndef RAD_USES_SSE3
240 #define RAD_USES_SSE3 __attribute__((target("sse3")))
241 #endif
242 #ifndef RAD_USES_SSSE3
243 #define RAD_USES_SSSE3 __attribute__((target("ssse3")))
244 #endif
245 #else
246 // on ancient GCC, turn off SSSE3
247 #ifdef RAD_USES_SSSE3
248 #undef RAD_USES_SSSE3
249 #endif
250 #endif
251
252 #define RAD_EXPECT(expr,cond) __builtin_expect(expr,cond)
253/*
254#elif defined(__CWCC__)
255 #define RADFORCEINLINE inline
256 #define RADNOINLINE __attribute__((never_inline))
257 #define RADUNREACHABLE
258 #define RADASSUME(x) (void)0
259*/
260#elif defined(__SNC__)
261 #ifndef RAD_ALIGN
262 #define RAD_ALIGN(type,var,num) type __attribute__ ((aligned (num))) var
263 #define RADFORCEINLINE inline __attribute((always_inline))
264 #define RADNOINLINE __attribute__((noinline))
265 #define RADASSUME(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) RADUNREACHABLE; )
266 #define RAD_EXPECT(expr,cond) __builtin_expect(expr,cond)
267 #endif
268 #define RADUNREACHABLE
269#else
270 #define RAD_EXPECT(exp,cond) !! no RAD_EXPECT defined !!
271 #define RADASSUME(exp) !! no RADASSUME defined !!
272 #define RADUNREACHABLE !! no RADUNREACHABLE defined !!
273 #define RADFORCEINLINE !! no RADFORCEINLINE defined !!
274 #define RADNOINLINE !! no RADNOINLINE defined !!
275#endif
276
277
278//===========================================================================
279// helpers for doing an if ( ) with expect :
280// if ( RAD_LIKELY(expr) ) { ... }
281#define RAD_LIKELY(expr) RAD_EXPECT(expr,1)
282#define RAD_UNLIKELY(expr) RAD_EXPECT(expr,0)
283
284
285//===========================================================================
286// __RADX86ASM__ means you can use __asm {} style inline assembly
287#if defined(__RADX86__) && !defined(__RADX64__) && defined(_MSC_VER)
288 #define __RADX86ASM__
289#endif
290
291
292//===========================================================================
293// RAD_STATEMENT_START AND RAD_STATEMENT_END_FALSE and END_TRUE
294// are used for "do{}while(0) or do{}while(1) loops without
295// warnings hopefully.
296// RAD_STATEMENT_WRAPPER(code) is for doing the tart/end_false all at once
297// RAD_INFINITE_LOOP(code) is for doing the tart/end_true all at once
298#ifdef _MSC_VER
299 // microsoft compilers
300 #if _MSC_VER >= 1400
301 #define RAD_STATEMENT_START \
302 do {
303
304 #define RAD_STATEMENT_END_FALSE \
305 __pragma(warning(push)) \
306 __pragma(warning(disable:4127)) \
307 } while(0) \
308 __pragma(warning(pop))
309
310 #define RAD_STATEMENT_END_TRUE \
311 __pragma(warning(push)) \
312 __pragma(warning(disable:4127)) \
313 } while(1) \
314 __pragma(warning(pop))
315
316 #else
317 #define RAD_USE_STANDARD_LOOP_CONSTRUCT
318 #endif
319#else
320 #define RAD_USE_STANDARD_LOOP_CONSTRUCT
321#endif
322
323#ifdef RAD_USE_STANDARD_LOOP_CONSTRUCT
324 #define RAD_STATEMENT_START \
325 do {
326
327 #define RAD_STATEMENT_END_FALSE \
328 } while ( (void)0,0 )
329
330 #define RAD_STATEMENT_END_TRUE \
331 } while ( (void)1,1 )
332#endif
333
334#define RAD_STATEMENT_WRAPPER( code ) \
335 RAD_STATEMENT_START \
336 code \
337 RAD_STATEMENT_END_FALSE
338
339#define RAD_INFINITE_LOOP( code ) \
340 RAD_STATEMENT_START \
341 code \
342 RAD_STATEMENT_END_TRUE
343
344
345//===========================================================================
346// to kill unused var warnings.
347// Must be placed after variable declarations for code compiled as .c
348#if defined(_MSC_VER) && _MSC_VER >= 1600 // in 2010 aka 10.0 and later
349 #define RR_UNUSED_VARIABLE(x) (void) (x)
350#else
351 #define RR_UNUSED_VARIABLE(x) (void)(sizeof(x))
352#endif
353
354//===========================================================================
355// RR_LINESTRING is the current line number as a string
356#define RR_STRINGIZE( L ) #L
357#define RR_DO_MACRO( M, X ) M(X)
358#define RR_STRINGIZE_DELAY( X ) RR_DO_MACRO( RR_STRINGIZE, X )
359#define RR_LINESTRING RR_STRINGIZE_DELAY( __LINE__ )
360
361#define RR_CAT(X,Y) X ## Y
362
363#define RR_STRING_JOIN3(arg1, arg2, arg3) RR_STRING_JOIN_DELAY3(arg1, arg2, arg3)
364#define RR_STRING_JOIN_DELAY3(arg1, arg2, arg3) RR_STRING_JOIN_IMMEDIATE3(arg1, arg2, arg3)
365#define RR_STRING_JOIN_IMMEDIATE3(arg1, arg2, arg3) arg1 ## arg2 ## arg3
366
367//===========================================================================
368// Range macros
369
370#ifndef RR_MIN
371 #define RR_MIN(a,b) ( (a) < (b) ? (a) : (b) )
372#endif
373
374#ifndef RR_MAX
375 #define RR_MAX(a,b) ( (a) > (b) ? (a) : (b) )
376#endif
377
378#ifndef RR_ABS
379 #define RR_ABS(a) ( ((a) < 0) ? -(a) : (a) )
380#endif
381
382#ifndef RR_CLAMP
383 #define RR_CLAMP(val,lo,hi) RR_MAX( RR_MIN(val,hi), lo )
384#endif
385
386//===========================================================================
387// Data layout macros
388
389#define RR_ARRAY_SIZE(array) ( sizeof(array)/sizeof(array[0]) )
390
391// MEMBER_OFFSET tells you the offset of a member in a type
392#define RR_MEMBER_OFFSET(type,member) offsetof(type, member)
393
394// MEMBER_SIZE tells you the size of a member in a type
395#define RR_MEMBER_SIZE(type,member) ( sizeof( ((type *) 0)->member) )
396
397// just to make gcc shut up about derefing null :
398#define RR_MEMBER_OFFSET_PTR(type,member,ptr) ( (SINTa) &(((type *)(ptr))->member) - (SINTa)(ptr) )
399#define RR_MEMBER_SIZE_PTR(type,member,ptr) ( sizeof( ((type *) (ptr))->member) )
400
401// MEMBER_TO_OWNER takes a pointer to a member and gives you back the base of the object
402// you should then RR_ASSERT( &(ret->member) == ptr );
403#define RR_MEMBER_TO_OWNER(type,member,ptr) (type *)( ((char *)(ptr)) - RR_MEMBER_OFFSET_PTR(type,member,ptr) )
404
405
406//===========================================================================
407// Cache / prefetch macros :
408// RR_PREFETCH for various platforms :
409//
410// RR_PREFETCH_SEQUENTIAL : prefetch memory for reading in a sequential scan
411// platforms that automatically prefetch sequential (eg. PC) should be a no-op here
412// RR_PREFETCH_WRITE_INVALIDATE : prefetch memory for writing - contents of memory are undefined
413// (may be a no-op, may be a normal prefetch, may zero memory)
414// warning : RR_PREFETCH_WRITE_INVALIDATE may write memory so don't do it past the end of buffers
415
416#ifdef __RADX86__
417 #define RR_PREFETCH_SEQUENTIAL(ptr,offset) // nop
418 #define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop
419#elif defined(__RADANDROID__)
420 #define RR_PREFETCH_SEQUENTIAL(ptr,offset) // intentional NOP for now
421 #define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop
422#elif defined(__RADWINRT__)
423 #define RR_PREFETCH_SEQUENTIAL(ptr,offset) __prefetch((char *)(ptr) + (int)(offset))
424 #define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop
425#elif defined(__RADARM__)
426 #define RR_PREFETCH_SEQUENTIAL(ptr,offset) // intentional NOP for now
427 #define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop
428#else
429 // other platforms - intentionally produce a compile error
430 #ifndef RR_PREFETCH_SEQUENTIAL
431 #define RR_PREFETCH_SEQUENTIAL(ptr,offset) !! NO PREFETCH DEFINED !!
432 #endif
433 #ifndef RR_PREFETCH_WRITE_INVALIDATE
434 #define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) !! NO PREFETCH DEFINED !!
435 #endif
436#endif
437
438//===========================================================================
439// LIGHTWEIGHT ASSERTS without rrAssert.h
440
441//===========================================================================
442#if (defined(_DEBUG) && !defined(NDEBUG)) || defined(ASSERT_IN_RELEASE)
443 #define RR_DO_ASSERTS
444#endif
445
446/*
447RR_ASSERT(exp) - the normal assert thing, toggled with RR_DO_ASSERTS
448RR_ASSERT_ALWAYS(exp) - assert that you want to test even in ALL builds (including final!)
449RR_ASSERT_RELEASE(exp) - assert that you want to test even in release builds (not for final!)
450RR_ASSERT_LITE(exp) - normal assert is not safe from threads or inside malloc; use this instead
451RR_DURING_ASSERT(exp) - wrap operations that compute stuff for assert in here
452RR_DO_ASSERTS - toggle tells you if asserts are enabled or not
453
454RR_BREAK() - generate a debug break - always !
455RR_ASSERT_BREAK() - RR_BREAK for asserts ; disable with RAD_NO_BREAK
456
457RR_ASSERT_FAILURE(str) - just break with a messsage; like assert with no condition
458RR_ASSERT_FAILURE_ALWAYS(str) - RR_ASSERT_FAILURE in release builds too
459RR_CANT_GET_HERE() - put in spots execution should never go
460RR_COMPILER_ASSERT(exp) - checks constant conditions at compile time
461
462RADTODO - note to search for nonfinal stuff
463RR_PRAGMA_MESSAGE - message dealy, use with #pragma in MSVC
464
465*************/
466
467//-----------------------------------------------------------
468
469
470//-----------------------------------------------------------
471
472// RAD_NO_BREAK : option if you don't like your assert to break
473// CB : RR_BREAK is *always* a break ; RR_ASSERT_BREAK is optional
474#ifdef RAD_NO_BREAK
475 #define RR_ASSERT_BREAK() (void)0
476#else
477 #define RR_ASSERT_BREAK() RR_BREAK()
478#endif
479
480// assert_always is on FINAL !
481#ifndef RR_ASSERT_ALWAYS
482 #define RR_ASSERT_ALWAYS(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) { RR_ASSERT_BREAK(); } )
483#endif
484// RR_ASSERT_FAILURE is like an assert without a condition - if you hit it, you're bad
485#ifndef RR_ASSERT_FAILURE_ALWAYS
486 #define RR_ASSERT_FAILURE_ALWAYS(str) RAD_STATEMENT_WRAPPER( RR_ASSERT_BREAK(); )
487#endif
488#ifndef RR_ASSERT_LITE_ALWAYS
489 #define RR_ASSERT_LITE_ALWAYS(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) { RR_ASSERT_BREAK(); } )
490#endif
491
492//-----------------------------------
493#ifdef RR_DO_ASSERTS
494 #define RR_ASSERT(exp) RR_ASSERT_ALWAYS(exp)
495 #define RR_ASSERT_LITE(exp) RR_ASSERT_LITE_ALWAYS(exp)
496 #define RR_ASSERT_NO_ASSUME(exp) RR_ASSERT_ALWAYS(exp)
497 // RR_DURING_ASSERT is to set up expressions or declare variables that are only used in asserts
498 #define RR_DURING_ASSERT(exp) exp
499 #define RR_ASSERT_FAILURE(str) RR_ASSERT_FAILURE_ALWAYS(str)
500 // RR_CANT_GET_HERE is for like defaults in switches that should never be hit
501 #define RR_CANT_GET_HERE() RAD_STATEMENT_WRAPPER( RR_ASSERT_FAILURE("can't get here"); RADUNREACHABLE; )
502#else // RR_DO_ASSERTS //-----------------------------------
503 #define RR_ASSERT(exp) (void)0
504 #define RR_ASSERT_LITE(exp) (void)0
505 #define RR_ASSERT_NO_ASSUME(exp) (void)0
506 #define RR_DURING_ASSERT(exp) (void)0
507 #define RR_ASSERT_FAILURE(str) (void)0
508 #define RR_CANT_GET_HERE() RADUNREACHABLE
509#endif // RR_DO_ASSERTS //-----------------------------------
510
511//=================================================================
512// RR_ASSERT_RELEASE is on in release build, but not final
513
514#ifndef __RADFINAL__
515 #define RR_ASSERT_RELEASE(exp) RR_ASSERT_ALWAYS(exp)
516 #define RR_ASSERT_LITE_RELEASE(exp) RR_ASSERT_LITE_ALWAYS(exp)
517#else
518 #define RR_ASSERT_RELEASE(exp) (void)0
519 #define RR_ASSERT_LITE_RELEASE(exp) (void)0
520#endif
521
522// check a pointer for natural alignment :
523#define RR_ASSERT_ALIGNED(ptr) RR_ASSERT( (((UINTa)(ptr)) & (sizeof(*(ptr))-1)) == 0 )
524
525//=================================================================
526// This never gets compiled away except for __RADFINAL__
527#define RR_ASSERT_ALWAYS_NO_SHIP RR_ASSERT_RELEASE
528
529#define rrAssert RR_ASSERT
530#define rrassert RR_ASSERT
531
532#ifdef _MSC_VER
533 // without this, our assert errors...
534 #if _MSC_VER >= 1300
535 #pragma warning( disable : 4127) // conditional expression is constant
536 #endif
537#endif
538
539//=================================================================
540// Get/Put from memory in little or big endian :
541//
542// val = RR_GET32_BE(ptr)
543// RR_PUT32_BE(ptr,val)
544//
545// available here :
546// RR_[GET/PUT][16/32]_[BE/LE][_UNALIGNED][_OFFSET]
547//
548// if you don't specify _UNALIGNED , then ptr & offset shoud both be aligned to type size
549// _OFFSET is in *bytes* !
550
551// you can #define RR_GET_RESTRICT to make all RR_GETs be RESTRICT
552// if you set nothing they are not
553
554#ifdef RR_GET_RESTRICT
555 #define RR_GET_PTR_POST RADRESTRICT
556#endif
557#ifndef RR_GET_PTR_POST
558 #define RR_GET_PTR_POST
559#endif
560
561// native version of get/put is always trivial :
562
563#define RR_GET16_NATIVE(ptr) *((const U16 * RR_GET_PTR_POST)(ptr))
564#define RR_PUT16_NATIVE(ptr,val) *((U16 * RR_GET_PTR_POST)(ptr)) = (U16)(val)
565
566// offset is in bytes
567#define RR_U16_PTR_OFFSET(ptr,offset) ((U16 * RR_GET_PTR_POST)((char *)(ptr) + (offset)))
568#define RR_GET16_NATIVE_OFFSET(ptr,offset) *( RR_U16_PTR_OFFSET((ptr),offset) )
569#define RR_PUT16_NATIVE_OFFSET(ptr,val,offset) *( RR_U16_PTR_OFFSET((ptr),offset)) = (val)
570
571#define RR_GET32_NATIVE(ptr) *((const U32 * RR_GET_PTR_POST)(ptr))
572#define RR_PUT32_NATIVE(ptr,val) *((U32 * RR_GET_PTR_POST)(ptr)) = (val)
573
574// offset is in bytes
575#define RR_U32_PTR_OFFSET(ptr,offset) ((U32 * RR_GET_PTR_POST)((char *)(ptr) + (offset)))
576#define RR_GET32_NATIVE_OFFSET(ptr,offset) *( RR_U32_PTR_OFFSET((ptr),offset) )
577#define RR_PUT32_NATIVE_OFFSET(ptr,val,offset) *( RR_U32_PTR_OFFSET((ptr),offset)) = (val)
578
579#define RR_GET64_NATIVE(ptr) *((const U64 * RR_GET_PTR_POST)(ptr))
580#define RR_PUT64_NATIVE(ptr,val) *((U64 * RR_GET_PTR_POST)(ptr)) = (val)
581
582// offset is in bytes
583#define RR_U64_PTR_OFFSET(ptr,offset) ((U64 * RR_GET_PTR_POST)((char *)(ptr) + (offset)))
584#define RR_GET64_NATIVE_OFFSET(ptr,offset) *( RR_U64_PTR_OFFSET((ptr),offset) )
585#define RR_PUT64_NATIVE_OFFSET(ptr,val,offset) *( RR_U64_PTR_OFFSET((ptr),offset)) = (val)
586
587//---------------------------------------------------
588
589#ifdef __RADLITTLEENDIAN__
590 #define RR_GET16_LE RR_GET16_NATIVE
591 #define RR_PUT16_LE RR_PUT16_NATIVE
592 #define RR_GET16_LE_OFFSET RR_GET16_NATIVE_OFFSET
593 #define RR_PUT16_LE_OFFSET RR_PUT16_NATIVE_OFFSET
594
595 #define RR_GET32_LE RR_GET32_NATIVE
596 #define RR_PUT32_LE RR_PUT32_NATIVE
597 #define RR_GET32_LE_OFFSET RR_GET32_NATIVE_OFFSET
598 #define RR_PUT32_LE_OFFSET RR_PUT32_NATIVE_OFFSET
599
600 #define RR_GET64_LE RR_GET64_NATIVE
601 #define RR_PUT64_LE RR_PUT64_NATIVE
602 #define RR_GET64_LE_OFFSET RR_GET64_NATIVE_OFFSET
603 #define RR_PUT64_LE_OFFSET RR_PUT64_NATIVE_OFFSET
604#else
605 #define RR_GET16_BE RR_GET16_NATIVE
606 #define RR_PUT16_BE RR_PUT16_NATIVE
607 #define RR_GET16_BE_OFFSET RR_GET16_NATIVE_OFFSET
608 #define RR_PUT16_BE_OFFSET RR_PUT16_NATIVE_OFFSET
609
610 #define RR_GET32_BE RR_GET32_NATIVE
611 #define RR_PUT32_BE RR_PUT32_NATIVE
612 #define RR_GET32_BE_OFFSET RR_GET32_NATIVE_OFFSET
613 #define RR_PUT32_BE_OFFSET RR_PUT32_NATIVE_OFFSET
614
615 #define RR_GET64_BE RR_GET64_NATIVE
616 #define RR_PUT64_BE RR_PUT64_NATIVE
617 #define RR_GET64_BE_OFFSET RR_GET64_NATIVE_OFFSET
618 #define RR_PUT64_BE_OFFSET RR_PUT64_NATIVE_OFFSET
619#endif
620
621//-------------------------
622// non-native Get/Put implementations go here :
623
624#if defined(__RADX86__)
625 // good implementation for X86 :
626 #if (_MSC_VER >= 1300)
627 RADDEFFUNC unsigned short __cdecl _byteswap_ushort (unsigned short _Short);
628 RADDEFFUNC unsigned long __cdecl _byteswap_ulong (unsigned long _Long);
629 #pragma intrinsic(_byteswap_ushort, _byteswap_ulong)
630
631 #define RR_BSWAP16 _byteswap_ushort
632 #define RR_BSWAP32 _byteswap_ulong
633
634 RADDEFFUNC unsigned __int64 __cdecl _byteswap_uint64 (unsigned __int64 val);
635 #pragma intrinsic(_byteswap_uint64)
636 #define RR_BSWAP64 _byteswap_uint64
637 #elif defined(_MSC_VER) // VC6
638 RADDEFFUNC RADFORCEINLINE unsigned long RR_BSWAP16 (unsigned long _Long)
639 {
640 __asm {
641 mov eax, [_Long]
642 rol ax, 8
643 mov [_Long], eax;
644 }
645 return _Long;
646 }
647
648 RADDEFFUNC RADFORCEINLINE unsigned long RR_BSWAP32 (unsigned long _Long)
649 {
650 __asm {
651 mov eax, [_Long]
652 bswap eax
653 mov [_Long], eax
654 }
655 return _Long;
656 }
657
659 {
660 __asm {
661 mov eax, DWORD PTR _Long
662 mov edx, DWORD PTR _Long+4
663 bswap eax
664 bswap edx
665 mov DWORD PTR _Long, edx
666 mov DWORD PTR _Long+4, eax
667 }
668 return _Long;
669 }
670 #elif defined(__GNUC__) || defined(__clang__)
671 // GCC has __builtin_bswap16, but Clang only seems to have added it recently.
672 // We use __builtin_bswap32/64 but 16 just uses the macro version. (No big
673 // deal if that turns into shifts anyway)
674 #define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) )
675 #define RR_BSWAP32 __builtin_bswap32
676 #define RR_BSWAP64 __builtin_bswap64
677 #endif
678
679 #define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr)))
680 #define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = (U16) RR_BSWAP16(val)
681 #define RR_GET16_BE_OFFSET(ptr,offset) RR_BSWAP16(*RR_U16_PTR_OFFSET(ptr,offset))
682 #define RR_PUT16_BE_OFFSET(ptr,val,offset) *RR_U16_PTR_OFFSET(ptr,offset) = RR_BSWAP16(val)
683
684 #define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr)))
685 #define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val)
686 #define RR_GET32_BE_OFFSET(ptr,offset) RR_BSWAP32(*RR_U32_PTR_OFFSET(ptr,offset))
687 #define RR_PUT32_BE_OFFSET(ptr,val,offset) *RR_U32_PTR_OFFSET(ptr,offset) = RR_BSWAP32(val)
688
689 #define RR_GET64_BE(ptr) RR_BSWAP64(*((U64 *)(ptr)))
690 #define RR_PUT64_BE(ptr,val) *((U64 *)(ptr)) = RR_BSWAP64(val)
691 #define RR_GET64_BE_OFFSET(ptr,offset) RR_BSWAP64(*RR_U64_PTR_OFFSET(ptr,offset))
692 #define RR_PUT64_BE_OFFSET(ptr,val,offset) *RR_U64_PTR_OFFSET(ptr,offset) = RR_BSWAP64(val)
693 // end _MSC_VER
694#elif defined(__RADIPHONE__) || defined(__RADANDROID__)
695 // iPhone/Android does not seem to have intrinsics for this, so use generic fallback!
696
697 // Bswap is just here for use of implementing get/put
698 // caller should use Get/Put , not bswap
699 #define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) )
700 #define RR_BSWAP32(u32) ( (U32) ( ((u32) >> 24) | (((u32)<<8) & 0x00FF0000) | (((u32)>>8) & 0x0000FF00) | ((u32) << 24) ) )
701 #define RR_BSWAP64(u64) ( (U64) ( RR_BSWAP32((u64)>>32) | ((U64)RR_BSWAP32((U32)(u64))<<32) ) )
702
703 #define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr)))
704 #define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val)
705
706 #define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr)))
707 #define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val)
708
709 #define RR_GET64_BE(ptr) RR_BSWAP64(*((U64 *)(ptr)))
710 #define RR_PUT64_BE(ptr,val) *((U64 *)(ptr)) = RR_BSWAP64(val)
711#elif defined(__RADWINRTAPI__) && defined(__RADARM__)
712 #include <intrin.h>
713
714 RADDEFFUNC unsigned short __cdecl _byteswap_ushort (unsigned short _Short);
715 RADDEFFUNC unsigned long __cdecl _byteswap_ulong (unsigned long _Long);
716 RADDEFFUNC unsigned __int64 __cdecl _byteswap_uint64 (unsigned __int64 val);
717 #pragma intrinsic(_byteswap_ushort, _byteswap_ulong)
718 #pragma intrinsic(_byteswap_uint64)
719
720 #define RR_GET16_BE(ptr) _byteswap_ushort(*((U16 *)(ptr)))
721 #define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = _byteswap_ushort(val)
722
723 #define RR_GET32_BE(ptr) _byteswap_ulong(*((U32 *)(ptr)))
724 #define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = _byteswap_ulong(val)
725
726 #define RR_GET64_BE(ptr) _byteswap_uint64(*((U64 *)(ptr)))
727 #define RR_PUT64_BE(ptr,val) *((U64 *)(ptr)) = _byteswap_uint64(val)
728
729#elif defined(__clang__) && defined(__RADARM64__)
730 #define RR_BSWAP16 __builtin_bswap16
731 #define RR_BSWAP32 __builtin_bswap32
732 #define RR_BSWAP64 __builtin_bswap64
733
734 #define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr)))
735 #define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val)
736
737 #define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr)))
738 #define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val)
739
740 #define RR_GET64_BE(ptr) RR_BSWAP64(*((U64 *)(ptr)))
741 #define RR_PUT64_BE(ptr,val) *((U64 *)(ptr)) = RR_BSWAP64(val)
742#else
743 // other platforms - don't define and error
744#endif
745
746//===================================================================
747// @@ TEMP : Aliases for old names : remove me when possible :
748//#define RR_GET32_OFFSET_LE RR_GET32_LE_OFFSET
749//#define RR_GET32_OFFSET_BE RR_GET32_BE_OFFSET
750//#define RR_PUT32_OFFSET_LE RR_PUT32_LE_OFFSET
751//#define RR_PUT32_OFFSET_BE RR_PUT32_BE_OFFSET
752//#define RR_GET16_OFFSET_LE RR_GET16_LE_OFFSET
753//#define RR_GET16_OFFSET_BE RR_GET16_BE_OFFSET
754//#define RR_PUT16_OFFSET_LE RR_PUT16_LE_OFFSET
755//#define RR_PUT16_OFFSET_BE RR_PUT16_BE_OFFSET
756
757
758//===================================================================
759// UNALIGNED VERSIONS :
760
761#if defined(__RADX86__) || defined(__RADPPC__) // platforms where unaligned is fast :
762 #define RR_GET64_BE_UNALIGNED(ptr) RR_GET64_BE(ptr)
763 #define RR_GET64_BE_UNALIGNED_OFFSET(ptr,offset) RR_GET64_BE_OFFSET(ptr,offset)
764 #define RR_GET32_BE_UNALIGNED(ptr) RR_GET32_BE(ptr)
765 #define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) RR_GET32_BE_OFFSET(ptr,offset)
766 #define RR_GET16_BE_UNALIGNED(ptr) RR_GET16_BE(ptr)
767 #define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) RR_GET16_BE_OFFSET(ptr,offset)
768
769 #define RR_GET64_LE_UNALIGNED(ptr) RR_GET64_LE(ptr)
770 #define RR_GET64_LE_UNALIGNED_OFFSET(ptr,offset) RR_GET64_LE_OFFSET(ptr,offset)
771 #define RR_GET32_LE_UNALIGNED(ptr) RR_GET32_LE(ptr)
772 #define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) RR_GET32_LE_OFFSET(ptr,offset)
773 #define RR_GET16_LE_UNALIGNED(ptr) RR_GET16_LE(ptr)
774 #define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) RR_GET16_LE_OFFSET(ptr,offset)
775#else
776 // Unaligned via bytes :
777 #define RR_GET32_BE_UNALIGNED(ptr) ( \
778 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 24 ) | \
779 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 16 ) | \
780 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[2] << 8 ) | \
781 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[3] << 0 ) )
782
783 #define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) ( \
784 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 24 ) | \
785 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 16 ) | \
786 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[2] << 8 ) | \
787 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[3] << 0 ) )
788
789 #define RR_GET16_BE_UNALIGNED(ptr) ( \
790 ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 8 ) | \
791 ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 0 ) )
792
793 #define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) ( \
794 ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 8 ) | \
795 ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 0 ) )
796
797 #define RR_GET32_LE_UNALIGNED(ptr) ( \
798 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[3] << 24 ) | \
799 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[2] << 16 ) | \
800 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 8 ) | \
801 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 0 ) )
802
803 #define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) ( \
804 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[3] << 24 ) | \
805 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[2] << 16 ) | \
806 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 8 ) | \
807 ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 0 ) )
808
809 #define RR_GET16_LE_UNALIGNED(ptr) ( \
810 ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 8 ) | \
811 ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 0 ) )
812
813 #define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) ( \
814 ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 8 ) | \
815 ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 0 ) )
816
817#endif
818
819//===================================================================
820// RR_ROTL32 : 32-bit rotate
821//
822
823#ifndef RR_ROTL32
824 #ifdef _MSC_VER
825 RADDEFFUNC unsigned long __cdecl _lrotl(unsigned long, int);
826 #pragma intrinsic(_lrotl)
827 #define RR_ROTL32(x,k) _lrotl((unsigned long)(x),(int)(k))
828 #else
829 // NOTE(fg): Barring evidence to the contrary, let's just assume that
830 // compilers are smart enough to turn this into rotates (where supported)
831 // by now.
832 #define RR_ROTL32(u32v,num) ( ( (u32v) << (num) ) | ( (u32v) >> (32 - (num))) )
833 #endif
834#endif
835
836//===================================================================
837// RR_ROTL64 : 64-bit rotate
838
839#ifndef RR_ROTL64
840 #if ( defined(_MSC_VER) && _MSC_VER >= 1300)
841 RADDEFFUNC unsigned __int64 __cdecl _rotl64(unsigned __int64 _Val, int _Shift);
842 #pragma intrinsic(_rotl64)
843 #define RR_ROTL64(x,k) _rotl64((unsigned __int64)(x),(int)(k))
844 #else
845 // NOTE(fg): Barring evidence to the contrary, let's just assume that
846 // compilers are smart enough to turn this into rotates (where supported)
847 // by now.
848 #define RR_ROTL64(u64v,num) ( ( (u64v) << (num) ) | ( (u64v) >> (64 - (num))) )
849 #endif
850#endif
851
852//===================================================================
853
854//===================================================================
855// some error checks :
856
861
862// aliases :
863#ifndef UINTn
864 #define UINTn UINTa
865#endif
866#ifndef UINTn
867 #define SINTn SINTa
868#endif
869
870#ifdef __cplusplus
871 #define RADDEFINEDATA extern "C"
872 #define RADDECLAREDATA extern "C"
873
874 #define RR_NAMESPACE rr
875 #define RR_NAMESPACE_START namespace RR_NAMESPACE {
876 #define RR_NAMESPACE_END };
877 #define RR_NAMESPACE_USE using namespace RR_NAMESPACE;
878#else
879 #define RADDEFINEDATA
880 #define RADDECLAREDATA extern
881
882 #define RR_NAMESPACE
883 #define RR_NAMESPACE_START
884 #define RR_NAMESPACE_END
885 #define RR_NAMESPACE_USE
886#endif
887
888//===================================================================
889
890#endif // __RADRR_CORE2H__
891
892
#define RAD_UINTa
Definition egttypes.h:452
#define RR_STRING_JOIN(arg1, arg2)
Definition egttypes.h:78
#define RR_COMPILER_ASSERT(exp)
Definition egttypes.h:411
S32 rrbool
Definition egttypes.h:536
#define RADDEFFUNC
Definition egttypes.h:66
#define RADFORCEINLINE
Definition rrCore.h:159
#define RAD_PTRBITS
Definition rrCore.h:14
#define RAD_TWOPTRBYTES
Definition rrCore.h:16
#define RAD_PTRBYTES
Definition rrCore.h:15
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
unsigned long DWORD
Definition MinimalWindowsApi.h:67