static_assert(sizeof(FObjectPtr)==sizeof(FObjectHandle),"FObjectPtr type must always compile to something equivalent to an FObjectHandle size.");
static_assert(sizeof(FObjectPtr)==sizeof(void*),"FObjectPtr type must always compile to something equivalent to a pointer size.");
static_assert(sizeof(TObjectPtr<UObject>)==sizeof(void*),"TObjectPtr<UObject> type must always compile to something equivalent to a pointer size.");
// Ensure that a TObjectPtr is trivially copyable, (copy/move) constructible, (copy/move) assignable, and destructible
static_assert(std::is_trivially_copyable<FMutableObjectPtr>::value,"TObjectPtr must be trivially copyable");
static_assert(std::is_trivially_copy_constructible<FMutableObjectPtr>::value,"TObjectPtr must be trivially copy constructible");
static_assert(std::is_trivially_move_constructible<FMutableObjectPtr>::value,"TObjectPtr must be trivially move constructible");
static_assert(std::is_trivially_copy_assignable<FMutableObjectPtr>::value,"TObjectPtr must be trivially copy assignable");
static_assert(std::is_trivially_move_assignable<FMutableObjectPtr>::value,"TObjectPtr must be trivially move assignable");
static_assert(std::is_trivially_destructible<FMutableObjectPtr>::value,"TObjectPtr must be trivially destructible");
// Ensure that raw pointers can be used to construct wrapped object pointers and that const-ness isn't stripped when constructing or converting with raw pointers
static_assert(std::is_constructible<FMutableObjectPtr,UObject*>::value,"TObjectPtr<UObject> must be constructible from a raw UObject*");
static_assert(!std::is_constructible<FMutableObjectPtr,constUObject*>::value,"TObjectPtr<UObject> must not be constructible from a const raw UObject*");
static_assert(std::is_convertible<FMutableObjectPtr,UObject*>::value,"TObjectPtr<UObject> must be convertible to a raw UObject*");
static_assert(std::is_convertible<FMutableObjectPtr,constUObject*>::value,"TObjectPtr<UObject> must be convertible to a const raw UObject*");
static_assert(std::is_constructible<FConstObjectPtr,UObject*>::value,"TObjectPtr<const UObject> must be constructible from a raw UObject*");
static_assert(std::is_constructible<FConstObjectPtr,constUObject*>::value,"TObjectPtr<const UObject> must be constructible from a const raw UObject*");
static_assert(!std::is_convertible<FConstObjectPtr,UObject*>::value,"TObjectPtr<const UObject> must not be convertible to a raw UObject*");
static_assert(std::is_convertible<FConstObjectPtr,constUObject*>::value,"TObjectPtr<const UObject> must be convertible to a const raw UObject*");
// Ensure that a TObjectPtr<const UObject> is constructible and assignable from a TObjectPtr<UObject> but not vice versa
static_assert(std::is_constructible<FConstObjectPtr,constFMutableObjectPtr&>::value,"Missing constructor (TObjectPtr<const UObject> from TObjectPtr<UObject>)");
static_assert(!std::is_constructible<FMutableObjectPtr,constFConstObjectPtr&>::value,"Invalid constructor (TObjectPtr<UObject> from TObjectPtr<const UObject>)");
static_assert(std::is_assignable<FConstObjectPtr,constFMutableObjectPtr&>::value,"Missing assignment (TObjectPtr<const UObject> from TObjectPtr<UObject>)");
static_assert(!std::is_assignable<FMutableObjectPtr,constFConstObjectPtr&>::value,"Invalid assignment (TObjectPtr<UObject> from TObjectPtr<const UObject>)");
static_assert(std::is_constructible<FConstObjectPtr,constFConstObjectPtr&>::value,"Missing constructor (TObjectPtr<const UObject> from TObjectPtr<const UObject>)");
static_assert(std::is_assignable<FConstObjectPtr,constFConstObjectPtr&>::value,"Missing assignment (TObjectPtr<const UObject> from TObjectPtr<const UObject>)");
// Ensure that a TObjectPtr<UObject> is constructible and assignable from a TObjectPtr<UInterface> but not vice versa
static_assert(std::is_constructible<FMutableObjectPtr,constFMutableInterfacePtr&>::value,"Missing constructor (TObjectPtr<UObject> from TObjectPtr<UInterface>)");
static_assert(!std::is_constructible<FMutableInterfacePtr,constFMutableObjectPtr&>::value,"Invalid constructor (TObjectPtr<UInterface> from TObjectPtr<UObject>)");
static_assert(std::is_constructible<FConstObjectPtr,constFConstInterfacePtr&>::value,"Missing constructor (TObjectPtr<const UObject> from TObjectPtr<const UInterface>)");
static_assert(std::is_constructible<FConstObjectPtr,constFMutableInterfacePtr&>::value,"Missing constructor (TObjectPtr<const UObject> from TObjectPtr<UInterface>)");
static_assert(!std::is_constructible<FConstInterfacePtr,constFConstObjectPtr&>::value,"Invalid constructor (TObjectPtr<const UInterface> from TObjectPtr<const UObject>)");
static_assert(!std::is_constructible<FConstInterfacePtr,constFMutableObjectPtr&>::value,"Invalid constructor (TObjectPtr<const UInterface> from TObjectPtr<UObject>)");
static_assert(std::is_assignable<FMutableObjectPtr,constFMutableInterfacePtr&>::value,"Missing assignment (TObjectPtr<UObject> from TObjectPtr<UInterface>)");
static_assert(std::is_assignable<FConstObjectPtr,constFMutableInterfacePtr&>::value,"Missing assignment (TObjectPtr<const UObject> from TObjectPtr<UInterface>)");
static_assert(std::is_assignable<FConstObjectPtr,constFConstInterfacePtr&>::value,"Missing assignment (TObjectPtr<const UObject> from TObjectPtr<const UInterface>)");
static_assert(!std::is_assignable<FMutableInterfacePtr,constFMutableObjectPtr&>::value,"Invalid assignment (TObjectPtr<UInterface> from TObjectPtr<UObject>)");
static_assert(!std::is_assignable<FConstInterfacePtr,constFMutableObjectPtr&>::value,"Invalid assignment (TObjectPtr<const UInterface> from TObjectPtr<UObject>)");
static_assert(!std::is_assignable<FConstInterfacePtr,constFConstObjectPtr&>::value,"Invalid assignment (TObjectPtr<const UInterface> from TObjectPtr<const UObject>)");
// Ensure that TObjectPtr<[const] UObject> is comparable with another TObjectPtr<[const] UObject> regardless of constness
static_assert(TModels_V<CEqualityComparableWith,FConstObjectPtr,FConstObjectPtr>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and TObjectPtr<const UObject>");
static_assert(TModels_V<CEqualityComparableWith,FMutableObjectPtr,FConstObjectPtr>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and TObjectPtr<const UObject>");
static_assert(TModels_V<CEqualityComparableWith,FConstObjectPtr,FConstInterfacePtr>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and TObjectPtr<const UInterface>");
static_assert(TModels_V<CEqualityComparableWith,FMutableObjectPtr,FConstInterfacePtr>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and TObjectPtr<const UInterface>");
static_assert(TModels_V<CEqualityComparableWith,FConstObjectPtr,FMutableInterfacePtr>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and TObjectPtr<UInterface>");
static_assert(TModels_V<CEqualityComparableWith,FMutableObjectPtr,FMutableInterfacePtr>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and TObjectPtr<UInterface>");
static_assert(!TModels_V<CEqualityComparableWith,FConstPackagePtr,FConstInterfacePtr>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UPackage> and TObjectPtr<const UInterface>");
static_assert(!TModels_V<CEqualityComparableWith,FMutablePackagePtr,FConstInterfacePtr>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UPackage> and TObjectPtr<const UInterface>");
static_assert(!TModels_V<CEqualityComparableWith,FConstPackagePtr,FMutableInterfacePtr>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UPackage> and TObjectPtr<UInterface>");
static_assert(!TModels_V<CEqualityComparableWith,FMutablePackagePtr,FMutableInterfacePtr>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UPackage> and TObjectPtr<UInterface>");
static_assert(TModels_V<CEqualityComparableWith,FConstObjectPtr,constUObject*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and const UObject*");
static_assert(TModels_V<CEqualityComparableWith,FMutableObjectPtr,constUObject*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and const UObject*");
static_assert(TModels_V<CEqualityComparableWith,FConstObjectPtr,UObject*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and UObject*");
static_assert(TModels_V<CEqualityComparableWith,FMutableObjectPtr,UObject*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and UObject*");
static_assert(TModels_V<CEqualityComparableWith,FConstObjectPtr,constUInterface*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and const UInterface*");
static_assert(TModels_V<CEqualityComparableWith,FMutableObjectPtr,constUInterface*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and const UInterface*");
static_assert(TModels_V<CEqualityComparableWith,FConstObjectPtr,UInterface*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and UInterface*");
static_assert(TModels_V<CEqualityComparableWith,FMutableObjectPtr,UInterface*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and UInterface*");
static_assert(TModels_V<CEqualityComparableWith,FConstInterfacePtr,constUObject*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UInterface> and const UObject*");
static_assert(TModels_V<CEqualityComparableWith,FMutableInterfacePtr,constUObject*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UInterface> and const UObject*");
static_assert(TModels_V<CEqualityComparableWith,FConstInterfacePtr,UObject*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UInterface> and UObject*");
static_assert(TModels_V<CEqualityComparableWith,FMutableInterfacePtr,UObject*>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UInterface> and UObject*");
static_assert(!TModels_V<CEqualityComparableWith,FConstInterfacePtr,constUPackage*>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UInterface> and const UPackage*");
static_assert(!TModels_V<CEqualityComparableWith,FMutableInterfacePtr,constUPackage*>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UInterface> and const UPackage*");
static_assert(!TModels_V<CEqualityComparableWith,FConstInterfacePtr,UPackage*>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UInterface> and UPackage*");
static_assert(!TModels_V<CEqualityComparableWith,FMutableInterfacePtr,UPackage*>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UInterface> and UPackage*");
static_assert(!TModels_V<CEqualityComparableWith,FConstObjectPtr,constchar*>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and const UObject*");
static_assert(!TModels_V<CEqualityComparableWith,FMutableObjectPtr,constchar*>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and const UObject*");
static_assert(!TModels_V<CEqualityComparableWith,FConstObjectPtr,char*>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and UObject*");
static_assert(!TModels_V<CEqualityComparableWith,FMutableObjectPtr,char*>,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and UObject*");
static_assert(TModels_V<CEqualityComparableWith,FConstObjectPtr,TYPE_OF_NULLPTR>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and nullptr");
static_assert(TModels_V<CEqualityComparableWith,FMutableObjectPtr,TYPE_OF_NULLPTR>,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and nullptr");
static_assert(!TModels_V<CEqualityComparableWith,FConstObjectPtr,long>,"Should not be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and long");
static_assert(!TModels_V<CEqualityComparableWith,FMutableObjectPtr,long>,"Should not be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and long");
// Ensure that the use of incomplete types doesn't provide a means to bypass type safety on TObjectPtr
// NOTE: This is disabled because we're permitting this operation with a deprecation warning.
//static_assert(!std::is_assignable<TObjectPtr<UForwardDeclaredObjDerived>, UForwardDeclaredObjDerived*>::value, "Should not be able to assign raw pointer of incomplete type that descends from UObject to exactly this type of TObjectPtr");
//static_assert(!std::is_assignable<TObjectPtr<FForwardDeclaredNotObjDerived>, FForwardDeclaredNotObjDerived*>::value, "Should not be able to assign raw pointer of incomplete type that does not descend from UObject to exactly this type of TObjectPtr");
ObjectRefMetrics.TestNumResolves(TEXT("Serializing an FObjectPtr twice should only require it to resolve once"),UE_WITH_OBJECT_HANDLE_LATE_RESOLVE?1:0);
TEST_EQUAL_STR(TEXT("Soft object path constructed from an FObjectPtr does not have the expected path value"),TEXT("/Engine/Test/ObjectPtrSoftObjectPath/Transient.TestSoftObject"),*DefaultSoftObjPath.ToString());
TEST_EQUAL(TEXT("Hash of resolved public FObjectPtr before rename should equal hash of resolved public FObjectPtr after rename"),HashWrappedAfterRename,HashWrapped);
TEST_EQUAL(TEXT("Hash of resolved public FObjectPtr before reparenting should equal hash of resolved public FObjectPtr after reparenting"),HashWrappedAfterReparent,HashWrapped);