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