// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "UObject/UnrealType.h" #include "UObject/PropertyOptional.h" namespace UE::Private { template struct TDoesStaticFunctionSignatureMatchImpl; // These simple helpers aren't enough to truly detect all UEnums and UStructs, // we would also need specializations for non-UHT generated UStructs,to make // this edge case more obvious I have chosen these names: template struct TIsUHTUEnum : std::false_type { }; template struct TIsUHTUEnum > : std::true_type {}; template struct TIsUHTUStruct : std::false_type { }; template struct TIsUHTUStruct > : std::true_type {}; /* FProperty <-> CPPType mappings, encoded in TCPPTypeToPropertyType: FInt8Property <-> int8 FInt16Property <-> int16 FIntProperty <-> int32 FInt64Property <-> int64 FByteProperty <-> uint8 FUInt16Property <-> uint16 FUInt32Property <-> uint32 FUInt64Property <-> uint64 FFloatProperty <-> float FDoubleProperty <-> double FBoolProperty <-> bool FStrProperty <-> FString FNameProperty <-> FName FTextProperty <-> FText FObjectProperty <-> TObjectPtr FClassProperty <-> TSubclassOf FSoftObjectProperty <-> TSoftObjectPtr FSoftClassProperty <-> TSoftClassPtr FWeakObjectProperty <-> TWeakObjectPtr FLazyObjectProperty <-> TLazyObjectPtr FSetProperty <-> TSet FArrayProperty <-> TArray FMapProperty <-> TMap FOptionalProperty <-> TOptional FInterfaceProperty <-> TScriptInterface FMulticastInlineDelegateProperty <-> TMulticastDelegate FMulticastSparseDelegateProperty <-> TSparseDynamicDelegate FDelegateProperty <-> TScriptDelegate FEnumProperty <-> UEnum FStructProperty <-> UStruct */ template struct TCPPTypeToPropertyType { using PropertyType = std::conditional< TIsUHTUStruct::value, FStructProperty, std::conditional::value, FEnumProperty, std::false_type>>; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FInt8Property; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FInt16Property; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FIntProperty; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FInt64Property; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FByteProperty; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FUInt16Property; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FUInt32Property; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FUInt64Property; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FFloatProperty; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FDoubleProperty; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FBoolProperty; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FStrProperty; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FNameProperty; }; template<> struct TCPPTypeToPropertyType { using PropertyType = FTextProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FObjectProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FClassProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FSoftObjectProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FSoftClassProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FWeakObjectProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FLazyObjectProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FArrayProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FMapProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FOptionalProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FInterfaceProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FMulticastInlineDelegateProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FMulticastSparseDelegateProperty; }; template struct TCPPTypeToPropertyType> { using PropertyType = FDelegateProperty; }; // This implementation handles UStructs, UEnums, and all non-parameterized types, specializations below handle parameterized types template struct TDoesParamMatchImpl { static bool DoesMatchProperty(const FProperty* Property) { using PropertyType = typename TCPPTypeToPropertyType::PropertyType; if constexpr (TIsUHTUStruct::value) { const PropertyType* SP = CastField(Property); return SP && SP->Struct == T::StaticStruct(); } else if constexpr (TIsUHTUEnum::value) { const PropertyType* EP = CastField(Property); return EP && EP->Enum == T::StaticEnum(); } else { return CastField(Property) != nullptr; } } }; // This handles all reference types (TObjectPtr, TSubclassOf, TSoftObjectPtr, TSoftClassPtr, TWeakObjectPtr, TLazyObjectPtr: template bool DoesReferencePropertyMatch(const T* Property, UClass* Type) { check(Type); return Property && Type->IsChildOf(Property->PropertyClass); } template<> bool DoesReferencePropertyMatch(const FClassProperty* Property, UClass* Type) { check(Type); return Property && Type->IsChildOf(Property->MetaClass); } template<> bool DoesReferencePropertyMatch(const FSoftClassProperty* Property, UClass* Type) { check(Type); return Property && Type->IsChildOf(Property->MetaClass); } template