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<CEqualityComparableWith,FConstObjectPtr,FConstObjectPtr>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and TObjectPtr<const UObject>");
static_assert(TModels<CEqualityComparableWith,FMutableObjectPtr,FConstObjectPtr>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and TObjectPtr<const UObject>");
// Ensure that TObjectPtr<[const] UObject> is comparable with another TObjectPtr<[const] UInterface> regardless of constness
static_assert(TModels<CEqualityComparableWith,FConstObjectPtr,FConstInterfacePtr>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and TObjectPtr<const UInterface>");
static_assert(TModels<CEqualityComparableWith,FMutableObjectPtr,FConstInterfacePtr>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and TObjectPtr<const UInterface>");
static_assert(TModels<CEqualityComparableWith,FConstObjectPtr,FMutableInterfacePtr>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and TObjectPtr<UInterface>");
static_assert(TModels<CEqualityComparableWith,FMutableObjectPtr,FMutableInterfacePtr>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and TObjectPtr<UInterface>");
// Ensure that TObjectPtr<[const] UPackage> is not comparable with a TObjectPtr<[const] UInterface> regardless of constness
// TODO: This only ensures that at least one of the A==B,B==A,A!=B,B!=A operations fail, not that they all fail.
static_assert(!TModels<CEqualityComparableWith,FConstPackagePtr,FConstInterfacePtr>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UPackage> and TObjectPtr<const UInterface>");
static_assert(!TModels<CEqualityComparableWith,FMutablePackagePtr,FConstInterfacePtr>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UPackage> and TObjectPtr<const UInterface>");
static_assert(!TModels<CEqualityComparableWith,FConstPackagePtr,FMutableInterfacePtr>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UPackage> and TObjectPtr<UInterface>");
static_assert(!TModels<CEqualityComparableWith,FMutablePackagePtr,FMutableInterfacePtr>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UPackage> and TObjectPtr<UInterface>");
// Ensure that TObjectPtr<[const] UObject> is comparable with a raw pointer of the same referenced type regardless of constness
static_assert(TModels<CEqualityComparableWith,FConstObjectPtr,constUObject*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and const UObject*");
static_assert(TModels<CEqualityComparableWith,FMutableObjectPtr,constUObject*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and const UObject*");
static_assert(TModels<CEqualityComparableWith,FConstObjectPtr,UObject*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and UObject*");
static_assert(TModels<CEqualityComparableWith,FMutableObjectPtr,UObject*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and UObject*");
// Ensure that TObjectPtr<[const] UObject> is comparable with a UInterface raw pointer regardless of constness
static_assert(TModels<CEqualityComparableWith,FConstObjectPtr,constUInterface*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and const UInterface*");
static_assert(TModels<CEqualityComparableWith,FMutableObjectPtr,constUInterface*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and const UInterface*");
static_assert(TModels<CEqualityComparableWith,FConstObjectPtr,UInterface*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and UInterface*");
static_assert(TModels<CEqualityComparableWith,FMutableObjectPtr,UInterface*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and UInterface*");
// Ensure that TObjectPtr<[const] UInterface> is comparable with a UObject raw pointer regardless of constness
static_assert(TModels<CEqualityComparableWith,FConstInterfacePtr,constUObject*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UInterface> and const UObject*");
static_assert(TModels<CEqualityComparableWith,FMutableInterfacePtr,constUObject*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UInterface> and const UObject*");
static_assert(TModels<CEqualityComparableWith,FConstInterfacePtr,UObject*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UInterface> and UObject*");
static_assert(TModels<CEqualityComparableWith,FMutableInterfacePtr,UObject*>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UInterface> and UObject*");
// Ensure that TObjectPtr<[const] UInterface> is not comparable with a UPackage raw pointer regardless of constness
// TODO: This only ensures that at least one of the A==B,B==A,A!=B,B!=A operations fail, not that they all fail.
static_assert(!TModels<CEqualityComparableWith,FConstInterfacePtr,constUPackage*>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UInterface> and const UPackage*");
static_assert(!TModels<CEqualityComparableWith,FMutableInterfacePtr,constUPackage*>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UInterface> and const UPackage*");
static_assert(!TModels<CEqualityComparableWith,FConstInterfacePtr,UPackage*>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UInterface> and UPackage*");
static_assert(!TModels<CEqualityComparableWith,FMutableInterfacePtr,UPackage*>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UInterface> and UPackage*");
// Ensure that TObjectPtr<[const] UInterface> is not comparable with a char raw pointer regardless of constness
// TODO: This only ensures that at least one of the A==B,B==A,A!=B,B!=A operations fail, not that they all fail.
static_assert(!TModels<CEqualityComparableWith,FConstObjectPtr,constchar*>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and const UObject*");
static_assert(!TModels<CEqualityComparableWith,FMutableObjectPtr,constchar*>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and const UObject*");
static_assert(!TModels<CEqualityComparableWith,FConstObjectPtr,char*>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and UObject*");
static_assert(!TModels<CEqualityComparableWith,FMutableObjectPtr,char*>::Value,"Must not be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and UObject*");
// Ensure that TObjectPtr<[const] UObject> is comparable with nullptr regardless of constness
static_assert(TModels<CEqualityComparableWith,FConstObjectPtr,TYPE_OF_NULLPTR>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and nullptr");
static_assert(TModels<CEqualityComparableWith,FMutableObjectPtr,TYPE_OF_NULLPTR>::Value,"Must be able to compare equality and inequality bidirectionally between TObjectPtr<UObject> and nullptr");
static_assert(!TModels<CEqualityComparableWith,FConstObjectPtr,long>::Value,"Should not be able to compare equality and inequality bidirectionally between TObjectPtr<const UObject> and long");
static_assert(!TModels<CEqualityComparableWith,FMutableObjectPtr,long>::Value,"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");
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 first wrapped public redirector should equal hash of wrapped public FObjectPtr it references"),HashWrapped,HashWrappedRedir1);
TEST_EQUAL(TEXT("Hash of first wrapped public redirector should equal hash of wrapped public FObjectPtr it references"),HashWrapped,HashWrappedRedir1);
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);