UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MemoryLayout.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
9#include "HAL/UnrealMemory.h"
11#include "Templates/EnableIf.h"
14#include "Templates/Models.h"
16
17class FCbFieldView;
18class FCbWriter;
19class FHashedName;
21class FSHA1;
25class ITargetPlatform;
26struct FTypeLayoutDesc;
28
29/*#define UE_STATIC_ONLY(T) \
30 T() = delete; \
31 ~T() = delete; \
32 UE_NONCOPYABLE(T)*/
33#define UE_STATIC_ONLY(T)
34
40#if PLATFORM_ANDROID || PLATFORM_MAC || PLATFORM_IOS || PLATFORM_TVOS
41#define UE_DECLARE_INTERNAL_LINK_BASE(T) template<int Counter, typename Dummy=void> struct T
42#define UE_DECLARE_INTERNAL_LINK_SPECIALIZATION(T, Counter) template<typename Dummy> struct T<Counter, Dummy>
43#else
44#define UE_DECLARE_INTERNAL_LINK_BASE(T) template<int Counter> struct T
45#define UE_DECLARE_INTERNAL_LINK_SPECIALIZATION(T, Counter) template<> struct T<Counter>
46#endif
47
48template<typename T> const FTypeLayoutDesc& StaticGetTypeLayoutDesc();
49
63
65{
72
73 inline bool HasVTable(Type InType) { return InType != NonVirtual; }
74}
75
91
106
108{
109 typedef void (FDestroyFunc)(void* Object, const FTypeLayoutDesc& TypeDesc, const FPointerTableBase* PtrTable, bool bIsFrozen);
111 typedef uint32 (FUnfrozenCopyFunc)(const FMemoryUnfreezeContent& Context, const void* Object, const FTypeLayoutDesc& TypeDesc, void* OutDst);
112 typedef uint32 (FAppendHashFunc)(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher);
113 typedef uint32 (FGetTargetAlignmentFunc)(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams);
114 typedef void (FToStringFunc)(const void* Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext);
115 typedef const void* (FGetDefaultFunc)();
116
118
119 static CORE_API void Initialize(FTypeLayoutDesc& TypeDesc);
120 static CORE_API void Register(FTypeLayoutDesc& TypeDesc);
122
125
127 const TCHAR* Name;
136
137 uint64 NameHash; // from FHashedName(Name)
146
147 friend inline bool operator==(const FTypeLayoutDesc& Lhs, const FTypeLayoutDesc& Rhs) { return &Lhs == &Rhs; }
148 friend inline bool operator!=(const FTypeLayoutDesc& Lhs, const FTypeLayoutDesc& Rhs) { return &Lhs != &Rhs; }
149};
150
156
157template<typename T, typename Base>
159{
160 alignas(T) char Dummy[sizeof(T)];
161 T* Derived = reinterpret_cast<T*>(Dummy);
162 return (uint32)((uint64)static_cast<Base*>(Derived) - (uint64)Derived);
163}
164
171{
172 template<typename T>
173 auto Requires(const T&) -> decltype(T::StaticClass()->GetDefaultObject());
174};
175
176template<typename T>
177const T* GetDefault();
178
179template<typename T>
184
185template<typename T>
187{
189 {
190 return GetDefault<T>();
191 }
192 else
193 {
194 static const T Default;
195 return &Default;
196 }
197}
198
199template<typename T, ETypeLayoutInterface::Type InterfaceType>
201{
203 static const void* Do() { return nullptr; }
204};
205
206template<typename T>
208{
210 static const void* Do() { return reinterpret_cast<const void*>(InternalGetDefaultObject<T>()); }
211};
212
213
214template<typename T, ETypeLayoutInterface::Type InterfaceType>
216
217template<typename T> struct TValidateInterfaceHelper<T, ETypeLayoutInterface::NonVirtual>
218{
220 static constexpr bool Value = !TIsPolymorphic<T>::Value;
221};
222
228
229template<typename T> struct TValidateInterfaceHelper<T, ETypeLayoutInterface::Abstract>
230{
232 static constexpr bool Value = true;
233};
234
235namespace Freeze
236{
237 CORE_API void DefaultWriteMemoryImageField(FMemoryImageWriter& Writer, const void* Object, const void* FieldObject, const FTypeLayoutDesc& TypeDesc, const FTypeLayoutDesc& DerivedTypeDesc);
240 CORE_API uint32 DefaultAppendHash(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher);
242 CORE_API void DefaultToString(const void* Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext);
246
247 // Override for types that need access to a PointerTable in order to destroy frozen data
248 // WARNING! Frozen data may have deduplicated portions, so it's possible that a given object may have multiple references
249 // Any attempt to cleanup/destroy frozen data must take care to safely allow DestroyObject to be called multiple times on the same frozen object
250 // Generally speaking, it's *NOT* safe to invoke the built-in destructor multiple times
251 template<typename T>
252 inline void DestroyObject(T* Object, const FPointerTableBase* PtrTable, bool bIsFrozen)
253 {
254 // Only call destructor for non-frozen objects
255 if (!bIsFrozen)
256 {
257 Object->~T();
258 }
259 // Wipe destroyed memory to a common pattern
260 FMemory::Memset(Object, 0xfe, sizeof(T));
261 }
262
263 template<typename T>
265 {
266 IntrinsicWriteMemoryImage(Writer, &Object, sizeof(T));
267 }
268
269 template<typename T>
271 {
272 new(OutDst) T(Object);
273 return sizeof(T);
274 }
275
276 template<typename T>
278 {
279 return DefaultAppendHash(TypeDesc, LayoutParams, Hasher);
280 }
281
282 template<typename T>
284 {
285 return TypeDesc.Alignment;
286 }
287
288 template<typename T>
290 {
291 DefaultToString(&Object, TypeDesc, LayoutParams, OutContext);
292 }
293
294 CORE_API uint32 IntrinsicAppendHash(void* const* DummyObject, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher);
296
303 CORE_API void IntrinsicToString(unsigned char Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext);
304 CORE_API void IntrinsicToString(unsigned short Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext);
306 CORE_API void IntrinsicToString(unsigned long Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext);
307 CORE_API void IntrinsicToString(unsigned long long Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext);
313
314 // helper functions
318
319 CORE_API uint32 AppendHash(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher);
323 CORE_API FSHAHash HashLayout(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams);
324}
325
326template<typename T>
331
337
338template <typename T, bool bProvidesStaticStruct=TModels_V<CStaticStructProvider, T>>
343
344template<typename T, typename BaseType>
345static void InternalInitializeBaseHelper(FTypeLayoutDesc& TypeDesc)
346{
347 alignas(FFieldLayoutDesc) static uint8 FieldBuffer[sizeof(FFieldLayoutDesc)] = { 0 };
349 FieldDesc.Name = TEXT("BASE");
350 FieldDesc.UFieldNameLength = 4;
352 FieldDesc.WriteFrozenMemoryImageFunc = TGetFreezeImageFieldHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::Do();
354 FieldDesc.NumArray = 1u;
355 FieldDesc.Next = TypeDesc.Fields;
356 TypeDesc.Fields = &FieldDesc;
357 ++TypeDesc.NumBases;
358 if (ETypeLayoutInterface::HasVTable(FieldDesc.Type->Interface)) ++TypeDesc.NumVirtualBases;
359}
360
361template<typename T>
362static UE_FORCEINLINE_HINT void InternalInitializeBasesHelper(FTypeLayoutDesc& TypeDesc) {}
363
364template<typename T, typename BaseType, typename ...RemainingBaseTypes>
365static void InternalInitializeBasesHelper(FTypeLayoutDesc& TypeDesc)
366{
367 InternalInitializeBasesHelper<T, RemainingBaseTypes...>(TypeDesc);
369}
370
371template<typename T>
373{
375 template<typename InternalType> static typename InternalType::DerivedType Test(const typename InternalType::DerivedType*);
376 template<typename InternalType> static void Test(...);
377
378 using Type = decltype(Test<T>(nullptr));
379};
380
381template<typename T, typename BaseType>
387
388template<typename T>
394
395namespace Freeze
396{
397 // Finds the length of the field name, omitting any _DEPRECATED suffix
399}
400
401#define INTERNAL_LAYOUT_FIELD(T, InName, InOffset, InFlags, InNumArray, InBitFieldSize, Counter) \
402 PRAGMA_DISABLE_DEPRECATION_WARNINGS \
403 UE_DECLARE_INTERNAL_LINK_SPECIALIZATION(InternalLinkType, Counter - CounterBase) { \
404 UE_STATIC_ONLY(InternalLinkType); \
405 static void Initialize(FTypeLayoutDesc& TypeDesc) { \
406 InternalLinkType<Counter - CounterBase + 1>::Initialize(TypeDesc); \
407 alignas(FFieldLayoutDesc) static uint8 FieldBuffer[sizeof(FFieldLayoutDesc)] = { 0 }; \
408 FFieldLayoutDesc& FieldDesc = *(FFieldLayoutDesc*)FieldBuffer; \
409 FieldDesc.Name = TEXT(#InName); \
410 FieldDesc.UFieldNameLength = Freeze::FindFieldNameLength(FieldDesc.Name); \
411 FieldDesc.Type = &StaticGetTypeLayoutDesc<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>(); \
412 FieldDesc.WriteFrozenMemoryImageFunc = TGetFreezeImageFieldHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::Do(); \
413 FieldDesc.Offset = InOffset; \
414 FieldDesc.NumArray = InNumArray; \
415 FieldDesc.Flags = InFlags; \
416 FieldDesc.BitFieldSize = InBitFieldSize; \
417 FieldDesc.Next = TypeDesc.Fields; \
418 TypeDesc.Fields = &FieldDesc; \
419 } \
420 }; \
421 PRAGMA_ENABLE_DEPRECATION_WARNINGS
422
423#define INTERNAL_LAYOUT_FIELD_WITH_WRITER(T, InName, InFunc, Counter) \
424 PRAGMA_DISABLE_DEPRECATION_WARNINGS \
425 UE_DECLARE_INTERNAL_LINK_SPECIALIZATION(InternalLinkType, Counter - CounterBase) { \
426 UE_STATIC_ONLY(InternalLinkType); \
427 static void CallWriteFrozenField(FMemoryImageWriter& Writer, const void* Object, const void* FieldObject, const FTypeLayoutDesc& TypeDesc, const FTypeLayoutDesc& DerivedTypeDesc) { \
428 static_cast<const DerivedType*>(Object)->InFunc(Writer, *(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)*)FieldObject); \
429 } \
430 static void Initialize(FTypeLayoutDesc& TypeDesc) { \
431 InternalLinkType<Counter - CounterBase + 1>::Initialize(TypeDesc); \
432 alignas(FFieldLayoutDesc) static uint8 FieldBuffer[sizeof(FFieldLayoutDesc)] = { 0 }; \
433 FFieldLayoutDesc& FieldDesc = *(FFieldLayoutDesc*)FieldBuffer; \
434 FieldDesc.Name = TEXT(#InName); \
435 FieldDesc.UFieldNameLength = Freeze::FindFieldNameLength(FieldDesc.Name); \
436 FieldDesc.Type = &StaticGetTypeLayoutDesc<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>(); \
437 FieldDesc.WriteFrozenMemoryImageFunc = &CallWriteFrozenField; \
438 FieldDesc.Offset = STRUCT_OFFSET(DerivedType, InName); \
439 FieldDesc.NumArray = 1u; \
440 FieldDesc.Flags = EFieldLayoutFlags::None; \
441 FieldDesc.Next = TypeDesc.Fields; \
442 TypeDesc.Fields = &FieldDesc; \
443 } \
444 }; \
445PRAGMA_ENABLE_DEPRECATION_WARNINGS
446
447#define INTERNAL_LAYOUT_WRITE_MEMORY_IMAGE(Func, Counter) \
448 UE_DECLARE_INTERNAL_LINK_SPECIALIZATION(InternalLinkType, Counter - CounterBase) { \
449 UE_STATIC_ONLY(InternalLinkType); \
450 static void CallWriteMemoryImage(FMemoryImageWriter& Writer, const void* Object, const FTypeLayoutDesc& TypeDesc, const FTypeLayoutDesc& DerivedTypeDesc) { \
451 static_cast<const DerivedType*>(Object)->Func(Writer, TypeDesc); \
452 } \
453 static void Initialize(FTypeLayoutDesc& TypeDesc) { \
454 InternalLinkType<Counter - CounterBase + 1>::Initialize(TypeDesc); \
455 TypeDesc.WriteFrozenMemoryImageFunc = &CallWriteMemoryImage; \
456 } \
457 };
458
459#define INTERNAL_LAYOUT_TOSTRING(Func, Counter) \
460 UE_DECLARE_INTERNAL_LINK_SPECIALIZATION(InternalLinkType, Counter - CounterBase) { \
461 UE_STATIC_ONLY(InternalLinkType); \
462 static void CallToString(const void* Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext) { \
463 static_cast<const DerivedType*>(Object)->Func(OutContext); \
464 } \
465 static void Initialize(FTypeLayoutDesc& TypeDesc) { \
466 InternalLinkType<Counter - CounterBase + 1>::Initialize(TypeDesc); \
467 TypeDesc.ToStringFunc = &CallToString; \
468 } \
469 };
470
471#define LAYOUT_FIELD(T, Name, ...) PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name; INTERNAL_LAYOUT_FIELD(T, Name, STRUCT_OFFSET(DerivedType, Name), EFieldLayoutFlags::MakeFlags(__VA_ARGS__), 1u, 0u, __COUNTER__)
472#define LAYOUT_MUTABLE_FIELD(T, Name, ...) mutable PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name; INTERNAL_LAYOUT_FIELD(T, Name, STRUCT_OFFSET(DerivedType, Name), EFieldLayoutFlags::MakeFlags(__VA_ARGS__), 1u, 0u, __COUNTER__)
473#define LAYOUT_FIELD_INITIALIZED(T, Name, Value, ...) PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name = Value; INTERNAL_LAYOUT_FIELD(T, Name, STRUCT_OFFSET(DerivedType, Name), EFieldLayoutFlags::MakeFlags(__VA_ARGS__), 1u, 0u, __COUNTER__)
474#define LAYOUT_MUTABLE_FIELD_INITIALIZED(T, Name, Value, ...) mutable PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name = Value; INTERNAL_LAYOUT_FIELD(T, Name, STRUCT_OFFSET(DerivedType, Name), EFieldLayoutFlags::MakeFlags(__VA_ARGS__), 1u, 0u, __COUNTER__)
475#define LAYOUT_ARRAY(T, Name, NumArray, ...) PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name[NumArray]; INTERNAL_LAYOUT_FIELD(T, Name, STRUCT_OFFSET(DerivedType, Name), EFieldLayoutFlags::MakeFlags(__VA_ARGS__), NumArray, 0u, __COUNTER__)
476#define LAYOUT_MUTABLE_BITFIELD(T, Name, BitFieldSize, ...) mutable PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name : BitFieldSize; INTERNAL_LAYOUT_FIELD(T, Name, ~0u, EFieldLayoutFlags::MakeFlags(__VA_ARGS__), 1u, BitFieldSize, __COUNTER__)
477#define LAYOUT_BITFIELD(T, Name, BitFieldSize, ...) PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name : BitFieldSize; INTERNAL_LAYOUT_FIELD(T, Name, ~0u, EFieldLayoutFlags::MakeFlags(__VA_ARGS__), 1u, BitFieldSize, __COUNTER__)
478#define LAYOUT_FIELD_WITH_WRITER(T, Name, Func) PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name; INTERNAL_LAYOUT_FIELD_WITH_WRITER(T, Name, Func, __COUNTER__)
479#define LAYOUT_MUTABLE_FIELD_WITH_WRITER(T, Name, Func) mutable PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name; INTERNAL_LAYOUT_FIELD_WITH_WRITER(T, Name, Func, __COUNTER__)
480#define LAYOUT_WRITE_MEMORY_IMAGE(Func) INTERNAL_LAYOUT_WRITE_MEMORY_IMAGE(Func, __COUNTER__)
481#define LAYOUT_TOSTRING(Func) INTERNAL_LAYOUT_TOSTRING(Func, __COUNTER__)
482
483#if WITH_EDITORONLY_DATA
484#define LAYOUT_FIELD_EDITORONLY(T, Name, ...) PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name; INTERNAL_LAYOUT_FIELD(T, Name, STRUCT_OFFSET(DerivedType, Name), EFieldLayoutFlags::MakeFlagsEditorOnly(__VA_ARGS__), 1u, 0u, __COUNTER__)
485#define LAYOUT_ARRAY_EDITORONLY(T, Name, NumArray, ...) PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name[NumArray]; INTERNAL_LAYOUT_FIELD(T, Name, STRUCT_OFFSET(DerivedType, Name), EFieldLayoutFlags::MakeFlagsEditorOnly(__VA_ARGS__), NumArray, 0u, __COUNTER__)
486#define LAYOUT_BITFIELD_EDITORONLY(T, Name, BitFieldSize, ...) PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) Name : BitFieldSize; INTERNAL_LAYOUT_FIELD(T, Name, ~0u, EFieldLayoutFlags::MakeFlagsEditorOnly(__VA_ARGS__), 1u, BitFieldSize, __COUNTER__)
487#else
488#define LAYOUT_FIELD_EDITORONLY(T, Name, ...)
489#define LAYOUT_ARRAY_EDITORONLY(T, Name, NumArray, ...)
490#define LAYOUT_BITFIELD_EDITORONLY(T, Name, BitFieldSize, ...)
491#endif
492
493#define INTERNAL_LAYOUT_INTERFACE_PREFIX_NonVirtual(...) __VA_ARGS__
494#define INTERNAL_LAYOUT_INTERFACE_PREFIX_Virtual(...) __VA_ARGS__ virtual
495#define INTERNAL_LAYOUT_INTERFACE_PREFIX_Abstract(...) virtual
496#define INTERNAL_LAYOUT_INTERFACE_PREFIX(Type) PREPROCESSOR_JOIN(INTERNAL_LAYOUT_INTERFACE_PREFIX_, Type)
497
498#define INTERNAL_LAYOUT_INTERFACE_SUFFIX_NonVirtual ;
499#define INTERNAL_LAYOUT_INTERFACE_SUFFIX_Virtual ;
500#define INTERNAL_LAYOUT_INTERFACE_SUFFIX_Abstract { return FTypeLayoutDesc::GetInvalidTypeLayout(); }
501#define INTERNAL_LAYOUT_INTERFACE_SUFFIX(Type) PREPROCESSOR_JOIN(INTERNAL_LAYOUT_INTERFACE_SUFFIX_, Type)
502
503#define INTERNAL_LAYOUT_INTERFACE_INLINE_IMPL_NonVirtual { return StaticGetTypeLayout(); }
504#define INTERNAL_LAYOUT_INTERFACE_INLINE_IMPL_Virtual { return StaticGetTypeLayout(); }
505#define INTERNAL_LAYOUT_INTERFACE_INLINE_IMPL_Abstract { return FTypeLayoutDesc::GetInvalidTypeLayout(); }
506#define INTERNAL_LAYOUT_INTERFACE_INLINE_IMPL(Type) PREPROCESSOR_JOIN(INTERNAL_LAYOUT_INTERFACE_INLINE_IMPL_, Type)
507
508#define INTERNAL_DECLARE_TYPE_LAYOUT_COMMON(T, InInterface) \
509 static constexpr int CounterBase = __COUNTER__; \
510 public: using DerivedType = PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T); \
511 static constexpr ETypeLayoutInterface::Type InterfaceType = ETypeLayoutInterface::InInterface; \
512 UE_DECLARE_INTERNAL_LINK_BASE(InternalLinkType) { UE_STATIC_ONLY(InternalLinkType); static UE_FORCEINLINE_HINT void Initialize(FTypeLayoutDesc& TypeDesc) {} }
513
514#define INTERNAL_DECLARE_INLINE_TYPE_LAYOUT(T, InInterface) \
515 private: static void InternalDestroy(void* Object, const FTypeLayoutDesc&, const FPointerTableBase* PtrTable, bool bIsFrozen) { \
516 Freeze::DestroyObject(static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)*>(Object), PtrTable, bIsFrozen); \
517 } \
518 public: static FTypeLayoutDesc& StaticGetTypeLayout() { \
519 static_assert(TValidateInterfaceHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T), ETypeLayoutInterface::InInterface>::Value, #InInterface " is invalid interface for " #T); \
520 alignas(FTypeLayoutDesc) static uint8 TypeBuffer[sizeof(FTypeLayoutDesc)] = { 0 }; \
521 FTypeLayoutDesc& TypeDesc = *(FTypeLayoutDesc*)TypeBuffer; \
522 if (!TypeDesc.IsInitialized) { \
523 TypeDesc.IsInitialized = true; \
524 TypeDesc.Name = TEXT(#T); \
525 TypeDesc.WriteFrozenMemoryImageFunc = TGetFreezeImageHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::Do(); \
526 TypeDesc.UnfrozenCopyFunc = &Freeze::DefaultUnfrozenCopy; \
527 TypeDesc.AppendHashFunc = &Freeze::DefaultAppendHash; \
528 TypeDesc.GetTargetAlignmentFunc = &Freeze::DefaultGetTargetAlignment; \
529 TypeDesc.ToStringFunc = &Freeze::DefaultToString; \
530 TypeDesc.DestroyFunc = &InternalDestroy; \
531 TypeDesc.Size = sizeof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
532 TypeDesc.Alignment = alignof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
533 TypeDesc.Interface = ETypeLayoutInterface::InInterface; \
534 TypeDesc.SizeFromFields = ~0u; \
535 TypeDesc.GetDefaultObjectFunc = &TGetDefaultObjectHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T), ETypeLayoutInterface::InInterface>::Do; \
536 InternalLinkType<1>::Initialize(TypeDesc); \
537 InternalInitializeBases<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>(TypeDesc); \
538 FTypeLayoutDesc::Initialize(TypeDesc); \
539 } \
540 return TypeDesc; } \
541 public: INTERNAL_LAYOUT_INTERFACE_PREFIX(InInterface)(PREPROCESSOR_NOTHING) const FTypeLayoutDesc& GetTypeLayout() const INTERNAL_LAYOUT_INTERFACE_INLINE_IMPL(InInterface) \
542 INTERNAL_DECLARE_TYPE_LAYOUT_COMMON(T, InInterface)
543
544#define INTERNAL_DECLARE_TYPE_LAYOUT(T, InInterface, RequiredAPI) \
545 private: static void InternalDestroy(void* Object, const FTypeLayoutDesc&, const FPointerTableBase* PtrTable, bool bIsFrozen); \
546 public: RequiredAPI static FTypeLayoutDesc& StaticGetTypeLayout(); \
547 public: INTERNAL_LAYOUT_INTERFACE_PREFIX(InInterface)(RequiredAPI) const FTypeLayoutDesc& GetTypeLayout() const INTERNAL_LAYOUT_INTERFACE_SUFFIX(InInterface) \
548 INTERNAL_DECLARE_TYPE_LAYOUT_COMMON(T, InInterface)
549
550#define INTERNAL_DECLARE_LAYOUT_BASE(T) \
551 private: using InternalBaseType = typename TGetBaseTypeHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::Type; \
552 template<typename InternalType> static void InternalInitializeBases(FTypeLayoutDesc& TypeDesc) { TInitializeBaseHelper<InternalType, InternalBaseType>::Initialize(TypeDesc); }
553
554#define INTERNAL_DECLARE_LAYOUT_EXPLICIT_BASES(T, ...) \
555 template<typename InternalType> static void InternalInitializeBases(FTypeLayoutDesc& TypeDesc) { InternalInitializeBasesHelper<InternalType, __VA_ARGS__>(TypeDesc); }
556
557#define DECLARE_TYPE_LAYOUT(T, Interface) INTERNAL_DECLARE_LAYOUT_BASE(T); INTERNAL_DECLARE_TYPE_LAYOUT(T, Interface, PREPROCESSOR_NOTHING)
558#define DECLARE_INLINE_TYPE_LAYOUT(T, Interface) INTERNAL_DECLARE_LAYOUT_BASE(T); INTERNAL_DECLARE_INLINE_TYPE_LAYOUT(T, Interface)
559#define DECLARE_EXPORTED_TYPE_LAYOUT(T, RequiredAPI, Interface) INTERNAL_DECLARE_LAYOUT_BASE(T); INTERNAL_DECLARE_TYPE_LAYOUT(T, Interface, RequiredAPI)
560
561#define DECLARE_TYPE_LAYOUT_EXPLICIT_BASES(T, Interface, ...) INTERNAL_DECLARE_LAYOUT_EXPLICIT_BASES(T, __VA_ARGS__); INTERNAL_DECLARE_TYPE_LAYOUT(T, Interface, PREPROCESSOR_NOTHING)
562#define DECLARE_INLINE_TYPE_LAYOUT_EXPLICIT_BASES(T, Interface, ...) INTERNAL_DECLARE_LAYOUT_EXPLICIT_BASES(T, __VA_ARGS__); INTERNAL_DECLARE_INLINE_TYPE_LAYOUT(T, Interface)
563#define DECLARE_EXPORTED_TYPE_LAYOUT_EXPLICIT_BASES(T, RequiredAPI, Interface, ...) INTERNAL_DECLARE_LAYOUT_EXPLICIT_BASES(T, __VA_ARGS__); INTERNAL_DECLARE_TYPE_LAYOUT(T, Interface, RequiredAPI)
564
565#define INTERNAL_IMPLEMENT_TYPE_LAYOUT_COMMON(TemplatePrefix, T) \
566 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) void PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)::InternalDestroy(void* Object, const FTypeLayoutDesc&, const FPointerTableBase* PtrTable, bool bIsFrozen) { \
567 Freeze::DestroyObject(static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)*>(Object), PtrTable, bIsFrozen); \
568 } \
569 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) FTypeLayoutDesc& PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)::StaticGetTypeLayout() { \
570 static_assert(TValidateInterfaceHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T), InterfaceType>::Value, "Invalid interface for " #T); \
571 alignas(FTypeLayoutDesc) static uint8 TypeBuffer[sizeof(FTypeLayoutDesc)] = { 0 }; \
572 FTypeLayoutDesc& TypeDesc = *(FTypeLayoutDesc*)TypeBuffer; \
573 if (!TypeDesc.IsInitialized) { \
574 TypeDesc.IsInitialized = true; \
575 TypeDesc.Name = TEXT(#T); \
576 TypeDesc.WriteFrozenMemoryImageFunc = TGetFreezeImageHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::Do(); \
577 TypeDesc.UnfrozenCopyFunc = &Freeze::DefaultUnfrozenCopy; \
578 TypeDesc.AppendHashFunc = &Freeze::DefaultAppendHash; \
579 TypeDesc.GetTargetAlignmentFunc = &Freeze::DefaultGetTargetAlignment; \
580 TypeDesc.ToStringFunc = &Freeze::DefaultToString; \
581 TypeDesc.DestroyFunc = &InternalDestroy; \
582 TypeDesc.Size = sizeof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
583 TypeDesc.Alignment = alignof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
584 TypeDesc.Interface = InterfaceType; \
585 TypeDesc.SizeFromFields = ~0u; \
586 TypeDesc.GetDefaultObjectFunc = &TGetDefaultObjectHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T), InterfaceType>::Do; \
587 InternalLinkType<1>::Initialize(TypeDesc); \
588 InternalInitializeBases<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>(TypeDesc); \
589 FTypeLayoutDesc::Initialize(TypeDesc); \
590 } \
591 return TypeDesc; }
592
593//#define INTERNAL_REGISTER_TYPE_LAYOUT(T) static const FRegisterTypeLayoutDesc ANONYMOUS_VARIABLE(RegisterTypeLayoutDesc)(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)::StaticGetTypeLayout())
594#define INTERNAL_REGISTER_TYPE_LAYOUT(T) static const FDelayedAutoRegisterHelper ANONYMOUS_VARIABLE(DelayedAutoRegisterHelper)(EDelayedRegisterRunPhase::ShaderTypesReady, []{ FTypeLayoutDesc::Register(T::StaticGetTypeLayout()); });
595
596#define IMPLEMENT_UNREGISTERED_TEMPLATE_TYPE_LAYOUT(TemplatePrefix, T) \
597 INTERNAL_IMPLEMENT_TYPE_LAYOUT_COMMON(TemplatePrefix, T); \
598 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) const FTypeLayoutDesc& PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)::GetTypeLayout() const { return StaticGetTypeLayout(); }
599
600#define IMPLEMENT_TEMPLATE_TYPE_LAYOUT(TemplatePrefix, T) \
601 IMPLEMENT_UNREGISTERED_TEMPLATE_TYPE_LAYOUT(TemplatePrefix, T); \
602 INTERNAL_REGISTER_TYPE_LAYOUT(T)
603
604#define IMPLEMENT_TYPE_LAYOUT(T) IMPLEMENT_TEMPLATE_TYPE_LAYOUT(, T)
605
606#define IMPLEMENT_ABSTRACT_TYPE_LAYOUT(T) \
607 INTERNAL_IMPLEMENT_TYPE_LAYOUT_COMMON(, T); \
608 INTERNAL_REGISTER_TYPE_LAYOUT(T)
609
610#define REGISTER_INLINE_TYPE_LAYOUT(T) \
611 static const FDelayedAutoRegisterHelper ANONYMOUS_VARIABLE(DelayedAutoRegisterHelper)(EDelayedRegisterRunPhase::ShaderTypesReady, [] \
612 { \
613 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)::StaticGetTypeLayout().Name = TEXT(#T); \
614 FTypeLayoutDesc::Register(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)::StaticGetTypeLayout()); \
615 } \
616 );
617
619{
620 template<typename T>
621 auto Requires(const T&) -> decltype(T::StaticGetTypeLayout());
622};
623
624template<typename T>
630
631template<typename T>
633{
635 static const FTypeLayoutDesc& Do() { return T::StaticGetTypeLayout(); }
636};
637
638template<typename T>
640{
642 static const FTypeLayoutDesc& Do(const T& Object) { return Object.GetTypeLayout(); }
643};
644
645template<typename T>
647
648template<typename T>
650
651CORE_API extern void InternalDeleteObjectFromLayout(void* Object, const FTypeLayoutDesc& TypeDesc, const FPointerTableBase* PtrTable, bool bIsFrozen);
652
653template<typename T>
654inline void DeleteObjectFromLayout(T* Object, const FPointerTableBase* PtrTable = nullptr, bool bIsFrozen = false)
655{
656 check(Object);
658 InternalDeleteObjectFromLayout(Object, TypeDesc, PtrTable, bIsFrozen);
659}
660
661#define DECLARE_TEMPLATE_INTRINSIC_TYPE_LAYOUT(TemplatePrefix, T) \
662 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) struct THasTypeLayout<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)> { UE_STATIC_ONLY(THasTypeLayout); static const bool Value = true; }; \
663 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) struct TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)> { \
664 UE_STATIC_ONLY(TStaticGetTypeLayoutHelper); \
665 static void CallWriteMemoryImage(FMemoryImageWriter& Writer, const void* Object, const FTypeLayoutDesc& TypeDesc, const FTypeLayoutDesc& DerivedTypeDesc) { \
666 Freeze::IntrinsicWriteMemoryImage(Writer, *static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(Object), TypeDesc); \
667 } \
668 static uint32 CallUnfrozenCopy(const FMemoryUnfreezeContent& Context, const void* Object, const FTypeLayoutDesc& TypeDesc, void* OutDst) { \
669 return Freeze::IntrinsicUnfrozenCopy(Context, *static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(Object), OutDst); \
670 } \
671 static uint32 CallAppendHash(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher) { \
672 return Freeze::IntrinsicAppendHash(static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(nullptr), TypeDesc, LayoutParams, Hasher); \
673 } \
674 static uint32 CallGetTargetAlignment(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams) { \
675 return Freeze::IntrinsicGetTargetAlignment(static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(nullptr), TypeDesc, LayoutParams); \
676 } \
677 static void CallToString(const void* Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext) { \
678 return Freeze::IntrinsicToString(*static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(Object), TypeDesc, LayoutParams, OutContext); \
679 } \
680 static void CallDestroy(void* Object, const FTypeLayoutDesc&, const FPointerTableBase* PtrTable, bool bIsFrozen) { \
681 Freeze::DestroyObject(static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)*>(Object), PtrTable, bIsFrozen); \
682 } \
683 static const FTypeLayoutDesc& Do() { \
684 alignas(FTypeLayoutDesc) static uint8 TypeBuffer[sizeof(FTypeLayoutDesc)] = { 0 }; \
685 FTypeLayoutDesc& TypeDesc = *(FTypeLayoutDesc*)TypeBuffer; \
686 if (!TypeDesc.IsInitialized) { \
687 TypeDesc.IsInitialized = true; \
688 TypeDesc.IsIntrinsic = true; \
689 TypeDesc.Name = TEXT(#T); \
690 TypeDesc.WriteFrozenMemoryImageFunc = &CallWriteMemoryImage; \
691 TypeDesc.UnfrozenCopyFunc = &CallUnfrozenCopy; \
692 TypeDesc.AppendHashFunc = &CallAppendHash; \
693 TypeDesc.GetTargetAlignmentFunc = &CallGetTargetAlignment; \
694 TypeDesc.ToStringFunc = &CallToString; \
695 TypeDesc.DestroyFunc = &CallDestroy; \
696 TypeDesc.Size = sizeof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
697 TypeDesc.Alignment = alignof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
698 TypeDesc.Interface = ETypeLayoutInterface::NonVirtual; \
699 TypeDesc.SizeFromFields = sizeof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
700 } \
701 return TypeDesc; } }; \
702 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) struct TGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)> { \
703 UE_STATIC_ONLY(TGetTypeLayoutHelper); \
704 static const FTypeLayoutDesc& Do(const PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)&) { return TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::Do(); }}
705
706#define DECLARE_EXPORTED_TEMPLATE_INTRINSIC_TYPE_LAYOUT(TemplatePrefix, T, RequiredAPI) \
707 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) struct THasTypeLayout<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)> { UE_STATIC_ONLY(THasTypeLayout); static const bool Value = true; }; \
708 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) struct TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)> { \
709 UE_STATIC_ONLY(TStaticGetTypeLayoutHelper); \
710 static void CallWriteMemoryImage(FMemoryImageWriter& Writer, const void* Object, const FTypeLayoutDesc& TypeDesc, const FTypeLayoutDesc& DerivedTypeDesc); \
711 static uint32 CallUnfrozenCopy(const FMemoryUnfreezeContent& Context, const void* Object, const FTypeLayoutDesc& TypeDesc, void* OutDst); \
712 static uint32 CallAppendHash(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher); \
713 static uint32 CallGetTargetAlignment(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams); \
714 static void CallToString(const void* Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext); \
715 static void CallDestroy(void* Object, const FTypeLayoutDesc&, const FPointerTableBase* PtrTable, bool bIsFrozen); \
716 RequiredAPI static const FTypeLayoutDesc& Do(); }; \
717 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) struct TGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)> { \
718 UE_STATIC_ONLY(TGetTypeLayoutHelper); \
719 static const FTypeLayoutDesc& Do(const PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)&) { return TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::Do(); }}
720
721#define IMPLEMENT_EXPORTED_INTRINSIC_TYPE_LAYOUT(T) \
722 void TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::CallWriteMemoryImage(FMemoryImageWriter& Writer, const void* Object, const FTypeLayoutDesc& TypeDesc, const FTypeLayoutDesc& DerivedTypeDesc) { \
723 Freeze::IntrinsicWriteMemoryImage(Writer, *static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(Object), TypeDesc); \
724 } \
725 uint32 TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::CallUnfrozenCopy(const FMemoryUnfreezeContent& Context, const void* Object, const FTypeLayoutDesc& TypeDesc, void* OutDst) { \
726 return Freeze::IntrinsicUnfrozenCopy(Context, *static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(Object), OutDst); \
727 } \
728 uint32 TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::CallAppendHash(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FSHA1& Hasher) { \
729 return Freeze::IntrinsicAppendHash(static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(nullptr), TypeDesc, LayoutParams, Hasher); \
730 } \
731 uint32 TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::CallGetTargetAlignment(const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams) { \
732 return Freeze::IntrinsicGetTargetAlignment(static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(nullptr), TypeDesc, LayoutParams); \
733 } \
734 void TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::CallToString(const void* Object, const FTypeLayoutDesc& TypeDesc, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext) { \
735 return Freeze::IntrinsicToString(*static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T) const*>(Object), TypeDesc, LayoutParams, OutContext); \
736 } \
737 void TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::CallDestroy(void* Object, const FTypeLayoutDesc&, const FPointerTableBase* PtrTable, bool bIsFrozen) { \
738 Freeze::DestroyObject(static_cast<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)*>(Object), PtrTable, bIsFrozen); \
739 } \
740 const FTypeLayoutDesc& TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)>::Do() { \
741 alignas(FTypeLayoutDesc) static uint8 TypeBuffer[sizeof(FTypeLayoutDesc)] = { 0 }; \
742 FTypeLayoutDesc& TypeDesc = *(FTypeLayoutDesc*)TypeBuffer; \
743 if (!TypeDesc.IsInitialized) { \
744 TypeDesc.IsInitialized = true; \
745 TypeDesc.IsIntrinsic = true; \
746 TypeDesc.Name = TEXT(#T); \
747 TypeDesc.WriteFrozenMemoryImageFunc = &CallWriteMemoryImage; \
748 TypeDesc.UnfrozenCopyFunc = &CallUnfrozenCopy; \
749 TypeDesc.AppendHashFunc = &CallAppendHash; \
750 TypeDesc.GetTargetAlignmentFunc = &CallGetTargetAlignment; \
751 TypeDesc.ToStringFunc = &CallToString; \
752 TypeDesc.DestroyFunc = &CallDestroy; \
753 TypeDesc.Size = sizeof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
754 TypeDesc.Alignment = alignof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
755 TypeDesc.Interface = ETypeLayoutInterface::NonVirtual; \
756 TypeDesc.SizeFromFields = sizeof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)); \
757 } \
758 return TypeDesc; }
759
760#define DECLARE_INTRINSIC_TYPE_LAYOUT(T) DECLARE_TEMPLATE_INTRINSIC_TYPE_LAYOUT(template<>, T)
761
762#define ALIAS_TEMPLATE_TYPE_LAYOUT(TemplatePrefix, T, Alias) \
763 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) struct TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)> : public TStaticGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(Alias)> { UE_STATIC_ONLY(TStaticGetTypeLayoutHelper); }; \
764 PREPROCESSOR_REMOVE_OPTIONAL_PARENS(TemplatePrefix) struct TGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(T)> : public TGetTypeLayoutHelper<PREPROCESSOR_REMOVE_OPTIONAL_PARENS(Alias)> { UE_STATIC_ONLY(TGetTypeLayoutHelper); }
765
766#define ALIAS_TYPE_LAYOUT(Type, Alias) \
767 static_assert(sizeof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(Type)) == sizeof(PREPROCESSOR_REMOVE_OPTIONAL_PARENS(Alias)), "Using a type alias but the sizes don't match!"); \
768 ALIAS_TEMPLATE_TYPE_LAYOUT(template<>, Type, Alias)
769
788
791
792// Map 'const' types to non-const type
794
795// All raw pointer types map to void*, since they're all handled the same way
797
799{
801
802 enum Flags
803 {
805 Flag_Is32Bit = (1 << 1),
806 Flag_AlignBases = (1 << 2),
808 };
809
812
813 inline bool IsInitialized() const { return (Flags & Flag_Initialized) != 0u; }
814 inline bool Is32Bit() const { return (Flags & Flag_Is32Bit) != 0u; }
815 inline bool HasAlignBases() const { return (Flags & Flag_AlignBases) != 0u; }
816 inline bool WithEditorOnly() const { return (Flags & Flag_WithEditorOnly) != 0u; }
817
818 // May need dedicated flag for this, if we need to support case-preserving names in non-editor builds
819 inline bool WithCasePreservingFName() const { return WithEditorOnly(); }
820
821 inline uint32 GetRawPointerSize() const { return Is32Bit() ? sizeof(uint32) : sizeof(uint64); }
822
824 {
825 return Ref.Serialize(Ar);
826 }
827
829 {
830 return Lhs.Flags == Rhs.Flags && Lhs.MaxFieldAlignment == Rhs.MaxFieldAlignment;
831 }
832
834 {
835 return !operator==(Lhs, Rhs);
836 }
837
838 CORE_API bool IsCurrentPlatform() const;
840
842 CORE_API void InitializeForPlatform(const ITargetPlatform* TargetPlatform);
843
844 CORE_API void InitializeForPlatform(const FString& PlatformName, bool bHasEditorOnlyData);
848
853
859 CORE_API void AppendKeyString(FString& KeyString) const;
860 CORE_API void Append(FShaderKeyGenerator& KeyGen) const;
861
862private:
863 // Hidden friend for FShaderKeyGenerator Append function
865 {
866 Value.Append(KeyGen);
867 }
868#if WITH_EDITOR
869 // Compact binary API with hidden friend operator<<
870 CORE_API void Save(FCbWriter& Writer) const;
871 bool TryLoad(FCbFieldView Field);
873 {
874 Value.Save(Writer);
875 return Writer;
876 }
878#endif
879};
880
881#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_5
883#endif
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define check(expr)
Definition AssertionMacros.h:314
bool LoadFromCompactBinary(FCbFieldView Field, FAssetDependency &Dependency)
Definition AssetRegistry.cpp:10420
FPlatformTypes::int8 int8
An 8-bit signed integer.
Definition Platform.h:1121
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define DECLARE_TEMPLATE_INTRINSIC_TYPE_LAYOUT(TemplatePrefix, T)
Definition MemoryLayout.h:661
const FTypeLayoutDesc & StaticGetTypeLayoutDesc()
Definition MemoryLayout.h:646
const T * GetDefault()
Definition UObjectGlobals.h:2155
void DeleteObjectFromLayout(T *Object, const FPointerTableBase *PtrTable=nullptr, bool bIsFrozen=false)
Definition MemoryLayout.h:654
uint32 GetBaseOffset()
Definition MemoryLayout.h:158
const T * InternalGetDefaultObject()
Definition MemoryLayout.h:186
const FTypeLayoutDesc & GetTypeLayoutDesc(const FPointerTableBase *, const T &Object)
Definition MemoryLayout.h:649
CORE_API void InternalDeleteObjectFromLayout(void *Object, const FTypeLayoutDesc &TypeDesc, const FPointerTableBase *PtrTable, bool bIsFrozen)
Definition MemoryImage.cpp:330
#define ALIAS_TEMPLATE_TYPE_LAYOUT(TemplatePrefix, T, Alias)
Definition MemoryLayout.h:762
#define DECLARE_INTRINSIC_TYPE_LAYOUT(T)
Definition MemoryLayout.h:760
#define PREPROCESSOR_REMOVE_OPTIONAL_PARENS(...)
Definition PreprocessorHelpers.h:112
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition CompactBinary.h:610
Definition CompactBinaryWriter.h:68
Definition MemoryImage.h:858
Definition MemoryImageWriter.h:14
Definition MemoryImageWriter.h:78
Definition MemoryImage.h:49
Definition SecureHash.h:314
Definition SecureHash.h:226
Definition ShaderKeyGenerator.h:29
Definition ThreadSafeCounter.h:14
Definition Array.h:670
Definition EnumAsByte.h:22
Definition MemoryLayout.h:77
UE_FORCEINLINE_HINT Type MakeFlagsRayTracing(uint32 Flags=None)
Definition MemoryLayout.h:89
UE_FORCEINLINE_HINT Type MakeFlagsEditorOnly(uint32 Flags=None)
Definition MemoryLayout.h:88
Type
Definition MemoryLayout.h:79
@ WithRayTracing
Definition MemoryLayout.h:82
@ Transient
Definition MemoryLayout.h:83
@ None
Definition MemoryLayout.h:80
@ WithEditorOnly
Definition MemoryLayout.h:81
@ UseInstanceWithNoProperty
Definition MemoryLayout.h:84
UE_FORCEINLINE_HINT Type MakeFlags(uint32 Flags=None)
Definition MemoryLayout.h:87
Definition MemoryLayout.h:65
bool HasVTable(Type InType)
Definition MemoryLayout.h:73
Type
Definition MemoryLayout.h:67
@ Virtual
Definition MemoryLayout.h:69
@ Abstract
Definition MemoryLayout.h:70
@ NonVirtual
Definition MemoryLayout.h:68
Definition FieldSystemNoiseAlgo.cpp:6
Definition Array.h:3955
CORE_API void ExtractBitFieldValue(const void *Value, uint32 SrcBitOffset, uint32 DestBitOffset, uint32 NumBits, uint64 &InOutValue)
Definition MemoryImage.cpp:383
CORE_API void DefaultWriteMemoryImageField(FMemoryImageWriter &Writer, const void *Object, const void *FieldObject, const FTypeLayoutDesc &TypeDesc, const FTypeLayoutDesc &DerivedTypeDesc)
Definition MemoryImage.cpp:413
void DestroyObject(T *Object, const FPointerTableBase *PtrTable, bool bIsFrozen)
Definition MemoryLayout.h:252
CORE_API uint32 DefaultGetTargetAlignment(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams)
Definition MemoryImage.cpp:687
CORE_API uint32 AppendHashForNameAndSize(const TCHAR *Name, uint32 Size, FSHA1 &Hasher)
Definition MemoryImage.cpp:568
UE_NODEBUG void IntrinsicWriteMemoryImage(FMemoryImageWriter &Writer, const TArray< T, AllocatorType > &Object, const FTypeLayoutDesc &)
Definition Array.h:3957
CORE_API uint32 DefaultUnfrozenCopy(const FMemoryUnfreezeContent &Context, const void *Object, const FTypeLayoutDesc &TypeDesc, void *OutDst)
Definition MemoryImage.cpp:909
CORE_API uint32 AppendHashPair(const FTypeLayoutDesc &KeyTypeDesc, const FTypeLayoutDesc &ValueTypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition MemoryImage.cpp:869
CORE_API bool IncludeField(const FFieldLayoutDesc *FieldDesc, const FPlatformTypeLayoutParameters &LayoutParams)
Definition MemoryImage.cpp:396
CORE_API uint32 DefaultAppendHash(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition MemoryImage.cpp:575
CORE_API uint32 AppendHash(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition MemoryImage.cpp:864
UE_NODEBUG uint32 IntrinsicUnfrozenCopy(const FMemoryUnfreezeContent &Context, const TArray< T, AllocatorType > &Object, void *OutDst)
Definition Array.h:3963
CORE_API uint32 HashLayouts(const TArray< const FTypeLayoutDesc * > &TypeLayouts, const FPlatformTypeLayoutParameters &LayoutParams, FSHAHash &OutHash)
Definition MemoryImage.cpp:895
CORE_API void DefaultToString(const void *Object, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FMemoryToStringContext &OutContext)
Definition MemoryImage.cpp:741
UE_NODEBUG void IntrinsicToString(const TArray< T, AllocatorType > &Object, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FMemoryToStringContext &OutContext)
Definition Array.h:3983
CORE_API uint32 HashLayout(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHAHash &OutHash)
Definition MemoryImage.cpp:878
CORE_API void DefaultWriteMemoryImage(FMemoryImageWriter &Writer, const void *Object, const FTypeLayoutDesc &TypeDesc, const FTypeLayoutDesc &DerivedTypeDesc)
Definition MemoryImage.cpp:418
CORE_API uint8 FindFieldNameLength(const TCHAR *Name)
Definition MemoryImage.cpp:2198
UE_NODEBUG uint32 IntrinsicGetTargetAlignment(const TArray< T, AllocatorType > *DummyObject, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams)
Definition Array.h:3976
CORE_API uint32 GetTargetAlignment(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams)
Definition MemoryImage.cpp:408
UE_NODEBUG uint32 IntrinsicAppendHash(const TArray< T, AllocatorType > *DummyObject, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition Array.h:3970
Definition MemoryLayout.h:171
auto Requires(const T &) -> decltype(T::StaticClass() ->GetDefaultObject())
Definition MemoryLayout.h:619
auto Requires(const T &) -> decltype(T::StaticGetTypeLayout())
Definition MemoryLayout.h:93
const FFieldLayoutDesc * Next
Definition MemoryLayout.h:98
uint32 Offset
Definition MemoryLayout.h:100
uint8 BitFieldSize
Definition MemoryLayout.h:103
uint32 NumArray
Definition MemoryLayout.h:101
FWriteFrozenMemoryImageFunc * WriteFrozenMemoryImageFunc
Definition MemoryLayout.h:99
const TCHAR * Name
Definition MemoryLayout.h:96
void() FWriteFrozenMemoryImageFunc(FMemoryImageWriter &Writer, const void *Object, const void *FieldObject, const FTypeLayoutDesc &TypeDesc, const FTypeLayoutDesc &DerivedTypeDesc)
Definition MemoryLayout.h:94
uint8 UFieldNameLength
Definition MemoryLayout.h:104
const struct FTypeLayoutDesc * Type
Definition MemoryLayout.h:97
EFieldLayoutFlags::Type Flags
Definition MemoryLayout.h:102
Definition MemoryLayout.h:51
CORE_API void AppendNullptr()
Definition MemoryImage.cpp:718
const FPointerTableBase * PrevPointerTable
Definition MemoryLayout.h:60
const FPointerTableBase * TryGetPrevPointerTable() const
Definition MemoryLayout.h:57
FStringBuilderBase * String
Definition MemoryLayout.h:59
CORE_API void AppendFrozenPointer(const FTypeLayoutDesc &StaticTypeDesc, int32 FrozenTypeIndex)
Definition MemoryImage.cpp:728
int32 Indent
Definition MemoryLayout.h:61
CORE_API void AppendIndent()
Definition MemoryImage.cpp:733
CORE_API void AppendUnfrozenPointer(const FTypeLayoutDesc &StaticTypeDesc)
Definition MemoryImage.cpp:723
static UE_FORCEINLINE_HINT void * Memset(void *Dest, uint8 Char, SIZE_T Count)
Definition UnrealMemory.h:119
Definition MemoryLayout.h:799
LAYOUT_FIELD_INITIALIZED(uint32, Flags, 0u)
CORE_API void InitializeForCurrent()
Definition MemoryImage.cpp:81
friend FArchive & operator<<(FArchive &Ar, FPlatformTypeLayoutParameters &Ref)
Definition MemoryLayout.h:823
CORE_API void AppendKeyString(FString &KeyString) const
Definition MemoryImage.cpp:117
uint32 GetRawPointerSize() const
Definition MemoryLayout.h:821
CORE_API bool IsCurrentPlatform() const
Definition MemoryImage.cpp:37
CORE_API void InitializeForPlatform(const ITargetPlatform *TargetPlatform)
Definition MemoryImage.cpp:57
bool Is32Bit() const
Definition MemoryLayout.h:814
bool WithCasePreservingFName() const
Definition MemoryLayout.h:819
Flags
Definition MemoryLayout.h:803
@ Flag_Is32Bit
Definition MemoryLayout.h:805
@ Flag_Initialized
Definition MemoryLayout.h:804
@ Flag_AlignBases
Definition MemoryLayout.h:806
@ Flag_WithEditorOnly
Definition MemoryLayout.h:807
LAYOUT_FIELD_INITIALIZED(uint32, MaxFieldAlignment, 0xffffffff)
bool IsInitialized() const
Definition MemoryLayout.h:813
friend bool operator==(const FPlatformTypeLayoutParameters &Lhs, const FPlatformTypeLayoutParameters &Rhs)
Definition MemoryLayout.h:828
bool WithEditorOnly() const
Definition MemoryLayout.h:816
DECLARE_EXPORTED_TYPE_LAYOUT(FPlatformTypeLayoutParameters, CORE_API, NonVirtual)
bool HasAlignBases() const
Definition MemoryLayout.h:815
CORE_API void InitializeForArchive(FArchive &Ar)
Definition MemoryImage.cpp:44
CORE_API void InitializeForClang()
Definition MemoryImage.cpp:105
friend void Append(FShaderKeyGenerator &KeyGen, const FPlatformTypeLayoutParameters &Value)
Definition MemoryLayout.h:864
friend bool operator!=(const FPlatformTypeLayoutParameters &Lhs, const FPlatformTypeLayoutParameters &Rhs)
Definition MemoryLayout.h:833
CORE_API void InitializeForMSVC()
Definition MemoryImage.cpp:97
Definition MemoryLayout.h:152
CORE_API FRegisterTypeLayoutDesc(const TCHAR *Name, FTypeLayoutDesc &TypeDesc)
CORE_API FRegisterTypeLayoutDesc(FTypeLayoutDesc &TypeDesc)
Definition MemoryLayout.h:108
const FFieldLayoutDesc * Fields
Definition MemoryLayout.h:128
uint32() FGetTargetAlignmentFunc(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams)
Definition MemoryLayout.h:113
const TCHAR * Name
Definition MemoryLayout.h:127
uint32 Alignment
Definition MemoryLayout.h:140
CORE_API uint32 GetOffsetToBase(const FTypeLayoutDesc &BaseTypeDesc) const
Definition MemoryImage.cpp:369
FToStringFunc * ToStringFunc
Definition MemoryLayout.h:134
friend bool operator!=(const FTypeLayoutDesc &Lhs, const FTypeLayoutDesc &Rhs)
Definition MemoryLayout.h:148
void() FToStringFunc(const void *Object, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FMemoryToStringContext &OutContext)
Definition MemoryLayout.h:114
FAppendHashFunc * AppendHashFunc
Definition MemoryLayout.h:132
uint32() FUnfrozenCopyFunc(const FMemoryUnfreezeContent &Context, const void *Object, const FTypeLayoutDesc &TypeDesc, void *OutDst)
Definition MemoryLayout.h:111
uint8 NumBases
Definition MemoryLayout.h:142
void() FDestroyFunc(void *Object, const FTypeLayoutDesc &TypeDesc, const FPointerTableBase *PtrTable, bool bIsFrozen)
Definition MemoryLayout.h:109
uint8 IsInitialized
Definition MemoryLayout.h:145
uint64 NameHash
Definition MemoryLayout.h:137
const void *() FGetDefaultFunc()
Definition MemoryLayout.h:115
const FTypeLayoutDesc * HashNext
Definition MemoryLayout.h:126
uint32 Size
Definition MemoryLayout.h:138
FGetDefaultFunc * GetDefaultObjectFunc
Definition MemoryLayout.h:135
ETypeLayoutInterface::Type Interface
Definition MemoryLayout.h:141
FWriteFrozenMemoryImageFunc * WriteFrozenMemoryImageFunc
Definition MemoryLayout.h:130
FDestroyFunc * DestroyFunc
Definition MemoryLayout.h:129
FUnfrozenCopyFunc * UnfrozenCopyFunc
Definition MemoryLayout.h:131
friend bool operator==(const FTypeLayoutDesc &Lhs, const FTypeLayoutDesc &Rhs)
Definition MemoryLayout.h:147
uint8 NumVirtualBases
Definition MemoryLayout.h:143
uint32() FAppendHashFunc(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition MemoryLayout.h:112
void() FWriteFrozenMemoryImageFunc(FMemoryImageWriter &Writer, const void *Object, const FTypeLayoutDesc &TypeDesc, const FTypeLayoutDesc &DerivedTypeDesc)
Definition MemoryLayout.h:110
static CORE_API const FTypeLayoutDesc & GetInvalidTypeLayout()
Definition MemoryImage.cpp:288
uint8 IsIntrinsic
Definition MemoryLayout.h:144
CORE_API bool IsDerivedFrom(const FTypeLayoutDesc &BaseTypeDesc) const
Definition MemoryImage.cpp:377
FGetTargetAlignmentFunc * GetTargetAlignmentFunc
Definition MemoryLayout.h:133
uint32 SizeFromFields
Definition MemoryLayout.h:139
Definition MemoryLayout.h:373
static void Test(...)
static InternalType::DerivedType Test(const typename InternalType::DerivedType *)
UE_STATIC_ONLY(TGetBaseTypeHelper)
decltype(Test< T >(nullptr)) Type
Definition MemoryLayout.h:378
static const void * Do()
Definition MemoryLayout.h:210
Definition MemoryLayout.h:201
static const void * Do()
Definition MemoryLayout.h:203
UE_STATIC_ONLY(TGetDefaultObjectHelper)
Definition MemoryLayout.h:340
static UE_FORCEINLINE_HINT FFieldLayoutDesc::FWriteFrozenMemoryImageFunc * Do()
Definition MemoryLayout.h:341
Definition MemoryLayout.h:334
static UE_FORCEINLINE_HINT FTypeLayoutDesc::FWriteFrozenMemoryImageFunc * Do()
Definition MemoryLayout.h:335
Definition MemoryLayout.h:640
UE_STATIC_ONLY(TGetTypeLayoutHelper)
static const FTypeLayoutDesc & Do(const T &Object)
Definition MemoryLayout.h:642
Definition MemoryLayout.h:181
static constexpr bool Value
Definition MemoryLayout.h:182
Definition MemoryLayout.h:626
UE_STATIC_ONLY(THasTypeLayout)
static constexpr bool Value
Definition MemoryLayout.h:628
static UE_FORCEINLINE_HINT void Initialize(FTypeLayoutDesc &TypeDesc)
Definition MemoryLayout.h:392
UE_STATIC_ONLY(TInitializeBaseHelper)
Definition MemoryLayout.h:383
UE_STATIC_ONLY(TInitializeBaseHelper)
static void Initialize(FTypeLayoutDesc &TypeDesc)
Definition MemoryLayout.h:385
Definition IsAbstract.h:10
Definition IsPolymorphic.h:10
Definition MemoryLayout.h:633
UE_STATIC_ONLY(TStaticGetTypeLayoutHelper)
static const FTypeLayoutDesc & Do()
Definition MemoryLayout.h:635
Definition MemoryLayout.h:328
static constexpr bool Value
Definition MemoryLayout.h:329
Definition MemoryLayout.h:215