Compare commits

...

2 Commits

5 changed files with 2579 additions and 62 deletions

View File

@ -26,6 +26,7 @@ void TestTemplates()
TestAtomic();
TestScopeHelper();
TestUniquePointer();
TestSharedPointer();
TestMiscTemplates();
}
@ -1504,7 +1505,7 @@ void TestUniquePointer()
{
TUniqueRef<int32> Temp(new int32);
*Temp = 15;
check(*Temp.Get() = 15);
always_check(*Temp.Get() = 15);
}
FCounter::Num = 0;
@ -1519,45 +1520,45 @@ void TestUniquePointer()
TUniqueRef<FCounter, FDeleter> TempB(PtrB);
TUniqueRef<FCounter, FDeleter> TempC(PtrC, FDeleter());
check(TempA == PtrA);
check(TempC != TempB);
check((TempA <=> PtrA) == strong_ordering::equal);
check((TempC <=> TempB) != strong_ordering::equal);
always_check(TempA == PtrA);
always_check(TempC != TempB);
always_check((TempA <=> PtrA) == strong_ordering::equal);
always_check((TempC <=> TempB) != strong_ordering::equal);
int32 TempNum;
TempNum = FCounter::Num;
TempB.Reset(new FCounter);
check(FCounter::Num == TempNum);
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
TempB.Reset(new FCounter, FDeleter());
check(FCounter::Num == TempNum);
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
FCounter* PtrX = TempB.ReleaseAndReset(new FCounter);
check(FCounter::Num == TempNum + 1);
always_check(FCounter::Num == TempNum + 1);
delete PtrX;
TempNum = FCounter::Num;
FCounter* PtrY = TempB.ReleaseAndReset(new FCounter, FDeleter());
check(FCounter::Num == TempNum + 1);
always_check(FCounter::Num == TempNum + 1);
delete PtrY;
check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
always_check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
Swap(TempB, TempC);
check(TempC.GetDeleter().Num == 2);
always_check(TempC.GetDeleter().Num == 2);
}
check(FCounter::Num == 0);
check(FDeleter::Num == 4);
always_check(FCounter::Num == 0);
always_check(FDeleter::Num == 4);
{
TUniqueRef<int32[]> Temp(new int32[4]);
Temp[0] = 15;
check(Temp.Get()[0] = 15);
always_check(Temp.Get()[0] = 15);
}
FCounter::Num = 0;
@ -1572,51 +1573,51 @@ void TestUniquePointer()
TUniqueRef<FCounter[], FArrayDeleter> TempB(PtrB);
TUniqueRef<FCounter[], FArrayDeleter> TempC(PtrC, FArrayDeleter());
check(TempA == PtrA);
check(TempC != TempB);
check((TempA <=> PtrA) == strong_ordering::equal);
check((TempC <=> TempB) != strong_ordering::equal);
always_check(TempA == PtrA);
always_check(TempC != TempB);
always_check((TempA <=> PtrA) == strong_ordering::equal);
always_check((TempC <=> TempB) != strong_ordering::equal);
int32 TempNum;
TempNum = FCounter::Num;
TempB.Reset(new FCounter[4]);
check(FCounter::Num == TempNum);
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
TempB.Reset(new FCounter[4], FArrayDeleter());
check(FCounter::Num == TempNum);
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
FCounter* PtrX = TempB.ReleaseAndReset(new FCounter[4]);
check(FCounter::Num == TempNum + 4);
always_check(FCounter::Num == TempNum + 4);
delete [] PtrX;
TempNum = FCounter::Num;
FCounter* PtrY = TempB.ReleaseAndReset(new FCounter[4], FArrayDeleter());
check(FCounter::Num == TempNum + 4);
always_check(FCounter::Num == TempNum + 4);
delete [] PtrY;
check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
always_check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
Swap(TempB, TempC);
check(TempC.GetDeleter().Num == 2);
always_check(TempC.GetDeleter().Num == 2);
}
check( FCounter::Num == 0);
check(FArrayDeleter::Num == 4);
always_check( FCounter::Num == 0);
always_check(FArrayDeleter::Num == 4);
{
TUniquePtr<int32> Temp = MakeUnique<int32>(NoInit);
*Temp = 15;
check(*Temp.Get() = 15);
always_check(*Temp.Get() = 15);
}
{
TUniquePtr<int32> Temp = MakeUnique<int32>();
*Temp = 15;
check(*Temp.Get() = 15);
always_check(*Temp.Get() = 15);
}
FCounter::Num = 0;
@ -1631,36 +1632,36 @@ void TestUniquePointer()
TUniquePtr<FCounter, FDeleter> TempB(PtrB);
TUniquePtr<FCounter, FDeleter> TempC(PtrC, FDeleter());
check(TempA == PtrA);
check(TempC != TempB);
check((TempA <=> PtrA) == strong_ordering::equal);
check((TempC <=> TempB) != strong_ordering::equal);
always_check(TempA == PtrA);
always_check(TempC != TempB);
always_check((TempA <=> PtrA) == strong_ordering::equal);
always_check((TempC <=> TempB) != strong_ordering::equal);
int32 TempNum;
TempNum = FCounter::Num;
TempB.Reset(new FCounter);
check(FCounter::Num == TempNum);
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
TempB.Reset(new FCounter, FDeleter());
check(FCounter::Num == TempNum);
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
FCounter* PtrX = TempB.ReleaseAndReset(new FCounter);
check(FCounter::Num == TempNum + 1);
always_check(FCounter::Num == TempNum + 1);
delete PtrX;
TempNum = FCounter::Num;
FCounter* PtrY = TempB.ReleaseAndReset(new FCounter, FDeleter());
check(FCounter::Num == TempNum + 1);
always_check(FCounter::Num == TempNum + 1);
delete PtrY;
check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
always_check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
Swap(TempB, TempC);
check(TempC.GetDeleter().Num == 2);
always_check(TempC.GetDeleter().Num == 2);
TUniquePtr<FCounter, FDeleter> TempD(MoveTemp(TempB));
@ -1669,25 +1670,25 @@ void TestUniquePointer()
TempE = nullptr;
TempB.Reset(new FCounter);
check(!!TempB);
check(TempB.IsValid());
always_check(!!TempB);
always_check(TempB.IsValid());
delete TempB.Release();
}
check(FCounter::Num == 0);
check(FDeleter::Num == 4);
always_check(FCounter::Num == 0);
always_check(FDeleter::Num == 4);
{
TUniquePtr<int32[]> Temp = MakeUnique<int32[]>(4, NoInit);
Temp[0] = 15;
check(Temp.Get()[0] = 15);
always_check(Temp.Get()[0] = 15);
}
{
TUniquePtr<int32[]> Temp = MakeUnique<int32[]>(4);
Temp[0] = 15;
check(Temp.Get()[0] = 15);
always_check(Temp.Get()[0] = 15);
}
FCounter::Num = 0;
@ -1702,36 +1703,36 @@ void TestUniquePointer()
TUniquePtr<FCounter[], FArrayDeleter> TempB(PtrB);
TUniquePtr<FCounter[], FArrayDeleter> TempC(PtrC, FArrayDeleter());
check(TempA == PtrA);
check(TempC != TempB);
check((TempA <=> PtrA) == strong_ordering::equal);
check((TempC <=> TempB) != strong_ordering::equal);
always_check(TempA == PtrA);
always_check(TempC != TempB);
always_check((TempA <=> PtrA) == strong_ordering::equal);
always_check((TempC <=> TempB) != strong_ordering::equal);
int32 TempNum;
TempNum = FCounter::Num;
TempB.Reset(new FCounter[4]);
check(FCounter::Num == TempNum);
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
TempB.Reset(new FCounter[4], FArrayDeleter());
check(FCounter::Num == TempNum);
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
FCounter* PtrX = TempB.ReleaseAndReset(new FCounter[4]);
check(FCounter::Num == TempNum + 4);
always_check(FCounter::Num == TempNum + 4);
delete [] PtrX;
TempNum = FCounter::Num;
FCounter* PtrY = TempB.ReleaseAndReset(new FCounter[4], FArrayDeleter());
check(FCounter::Num == TempNum + 4);
always_check(FCounter::Num == TempNum + 4);
delete [] PtrY;
check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
always_check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
Swap(TempB, TempC);
check(TempC.GetDeleter().Num == 2);
always_check(TempC.GetDeleter().Num == 2);
TUniquePtr<FCounter[], FArrayDeleter> TempD(MoveTemp(TempB));
@ -1740,14 +1741,526 @@ void TestUniquePointer()
TempE = nullptr;
TempB.Reset(new FCounter[4]);
check(!!TempB);
check(TempB.IsValid());
always_check(!!TempB);
always_check(TempB.IsValid());
delete [] TempB.Release();
}
check( FCounter::Num == 0);
check(FArrayDeleter::Num == 4);
always_check( FCounter::Num == 0);
always_check(FArrayDeleter::Num == 4);
{
TUniquePtr<int32> TempA;
TUniquePtr<const int32> TempB = MoveTemp(TempA);
TUniquePtr<const int32> TempC;
TempC = MoveTemp(TempA);
}
{
TUniquePtr<int32[]> TempA;
TUniquePtr<const int32[]> TempB = MoveTemp(TempA);
TUniquePtr<const int32[]> TempC;
TempC = MoveTemp(TempA);
}
}
void TestSharedPointer()
{
FCounter::Num = 0;
FDeleter::Num = 0;
{
FCounter* PtrA = new FCounter;
FCounter* PtrB = new FCounter;
FCounter* PtrC = new FCounter;
TSharedRef<FCounter> TempA(PtrA);
TSharedRef<FCounter> TempB(PtrB, FDeleter());
TSharedRef<FCounter> TempC(PtrC, FDeleter());
always_check(TempA == PtrA);
always_check(TempC != TempB);
always_check((TempA <=> PtrA) == strong_ordering::equal);
always_check((TempC <=> TempB) != strong_ordering::equal);
int32 TempNum;
TempNum = FCounter::Num;
TempB.Reset(new FCounter, FDeleter());
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
TempC.Reset(new FCounter, FDeleter());
always_check(FCounter::Num == TempNum);
always_check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
Swap(TempB, TempC);
always_check(TempA.GetDeleter<FDeleter>() == nullptr);
always_check(TempC.GetDeleter<FDeleter>() != nullptr);
always_check(TempC.GetDeleter<FDeleter>()->Num == 2);
TSharedRef<FCounter> TempD(MoveTemp(TempB));
}
always_check(FCounter::Num == 0);
always_check(FDeleter::Num == 4);
{
TSharedRef<int32[]> Temp = MakeShared<int32[]>(4, NoInit);
Temp[0] = 15;
always_check(Temp.Get()[0] = 15);
}
{
TSharedRef<int32[]> Temp = MakeShared<int32[]>(4);
Temp[0] = 15;
always_check(Temp.Get()[0] = 15);
}
FCounter::Num = 0;
FArrayDeleter::Num = 0;
{
FCounter* PtrA = new FCounter[4];
FCounter* PtrB = new FCounter[4];
FCounter* PtrC = new FCounter[4];
TSharedRef<FCounter[]> TempA(PtrA);
TSharedRef<FCounter[]> TempB(PtrB, FArrayDeleter());
TSharedRef<FCounter[]> TempC(PtrC, FArrayDeleter());
always_check(TempA == PtrA);
always_check(TempC != TempB);
always_check((TempA <=> PtrA) == strong_ordering::equal);
always_check((TempC <=> TempB) != strong_ordering::equal);
int32 TempNum;
TempNum = FCounter::Num;
TempB.Reset(new FCounter[4], FArrayDeleter());
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
TempB.Reset(new FCounter[4], FArrayDeleter());
always_check(FCounter::Num == TempNum);
always_check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
Swap(TempB, TempC);
always_check(TempA.GetDeleter<FArrayDeleter>() == nullptr);
always_check(TempC.GetDeleter<FArrayDeleter>() != nullptr);
always_check(TempC.GetDeleter<FArrayDeleter>()->Num == 2);
TSharedRef<FCounter[]> TempD(MoveTemp(TempB));
}
always_check( FCounter::Num == 0);
always_check(FArrayDeleter::Num == 4);
FCounter::Num = 0;
FDeleter::Num = 0;
{
FCounter* PtrA = new FCounter;
FCounter* PtrB = new FCounter;
FCounter* PtrC = new FCounter;
TSharedPtr<FCounter> TempA(PtrA);
TSharedPtr<FCounter> TempB(PtrB, FDeleter());
TSharedPtr<FCounter> TempC(PtrC, FDeleter());
always_check(TempA == PtrA);
always_check(TempC != TempB);
always_check((TempA <=> PtrA) == strong_ordering::equal);
always_check((TempC <=> TempB) != strong_ordering::equal);
int32 TempNum;
TempNum = FCounter::Num;
TempB.Reset(new FCounter, FDeleter());
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
TempB.Reset(new FCounter, FDeleter());
always_check(FCounter::Num == TempNum);
always_check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
Swap(TempB, TempC);
always_check(TempA.GetDeleter<FDeleter>() == nullptr);
always_check(TempC.GetDeleter<FDeleter>() != nullptr);
always_check(TempC.GetDeleter<FDeleter>()->Num == 2);
TSharedPtr<FCounter> TempD(MoveTemp(TempB));
TSharedPtr<FCounter> TempE;
TempE = MoveTemp(TempC);
TempE = nullptr;
TempB.Reset(new FCounter, FDeleter());
always_check(!!TempB);
always_check(TempB.IsValid());
}
always_check(FCounter::Num == 0);
always_check(FDeleter::Num == 5);
{
TSharedPtr<int32[]> Temp = MakeShared<int32[]>(4, NoInit);
Temp[0] = 15;
always_check(Temp.Get()[0] = 15);
}
{
TSharedPtr<int32[]> Temp = MakeShared<int32[]>(4);
Temp[0] = 15;
always_check(Temp.Get()[0] = 15);
}
FCounter::Num = 0;
FArrayDeleter::Num = 0;
{
FCounter* PtrA = new FCounter[4];
FCounter* PtrB = new FCounter[4];
FCounter* PtrC = new FCounter[4];
TSharedPtr<FCounter[]> TempA(PtrA);
TSharedPtr<FCounter[]> TempB(PtrB, FArrayDeleter());
TSharedPtr<FCounter[]> TempC(PtrC, FArrayDeleter());
always_check(TempA == PtrA);
always_check(TempC != TempB);
always_check((TempA <=> PtrA) == strong_ordering::equal);
always_check((TempC <=> TempB) != strong_ordering::equal);
int32 TempNum;
TempNum = FCounter::Num;
TempB.Reset(new FCounter[4], FArrayDeleter());
always_check(FCounter::Num == TempNum);
TempNum = FCounter::Num;
TempB.Reset(new FCounter[4], FArrayDeleter());
always_check(FCounter::Num == TempNum);
always_check(GetTypeHash(TempB) == GetTypeHash(TempB.Get()));
Swap(TempB, TempC);
always_check(TempA.GetDeleter<FArrayDeleter>() == nullptr);
always_check(TempC.GetDeleter<FArrayDeleter>() != nullptr);
always_check(TempC.GetDeleter<FArrayDeleter>()->Num == 2);
TSharedPtr<FCounter[]> TempD(MoveTemp(TempB));
TSharedPtr<FCounter[]> TempE;
TempE = MoveTemp(TempC);
TempE = nullptr;
TempB.Reset(new FCounter[4], FArrayDeleter());
always_check(!!TempB);
always_check(TempB.IsValid());
}
always_check( FCounter::Num == 0);
always_check(FArrayDeleter::Num == 5);
{
TSharedPtr<bool> Temp;
always_check(!Temp.IsValid());
if (Temp.Get() == nullptr) { }
}
{
TSharedPtr<int32> Temp(new int32(123));
always_check(Temp.IsValid());
always_check(Temp.IsUnique());
const int32 DeferenceTest = *Temp;
Temp.Reset();
always_check(Temp.GetSharedReferenceCount() == 0);
}
{
TSharedPtr<bool> TempA(new bool(false));
TSharedPtr<bool> TempB(TempA);
}
{
TSharedPtr<bool> TempA(new bool(false));
TSharedPtr<bool> TempB;
TempB = TempA;
}
{
struct FSharedTest { bool bTest; };
TSharedPtr<FSharedTest> TempA(new FSharedTest());
TempA->bTest = true;
(*TempA).bTest = false;
TSharedPtr<FSharedTest> TempB(TempA);
TempA.Reset();
}
{
class FBase { bool bTest; };
class FDerived : public FBase { };
{
TSharedPtr<FBase> TempA(new FDerived());
TSharedPtr<FDerived> TempB(StaticCast<FDerived>(TempA));
}
{
TSharedPtr<FDerived> TempA(new FDerived());
TSharedPtr<FBase> TempB(TempA);
}
{
TSharedPtr<FDerived> TempA(new FDerived());
TSharedPtr<FBase> TempB;
TempB = TempA;
}
}
{
bool* Ptr = nullptr;
TSharedPtr<bool> Temp(Ptr);
always_check(!Temp.IsValid());
}
{
TSharedPtr<bool> Temp(new bool(true));
always_check(Temp.IsValid());
}
{
TWeakPtr<bool> Temp;
always_check(!Temp.Lock().IsValid());
}
{
TSharedPtr<int32> TempShared(new int32(64));
TWeakPtr<int32> TempWeak(TempShared);
always_check(TempWeak.Lock().IsValid());
}
{
TSharedPtr<int32> TempShared(new int32(64));
TWeakPtr<int32> TempWeak;
TempWeak = TempShared;
always_check(TempWeak.Lock().IsValid());
TempWeak.Reset();
always_check(!TempWeak.Lock().IsValid());
}
{
TSharedPtr<int32> TempShared(new int32(64));
TWeakPtr<int32> TempWeak = TempShared;
TempShared.Reset();
always_check(!TempWeak.Lock().IsValid());
}
{
TSharedPtr<int32> TempA(new int32(64));
TSharedPtr<int32> TempB(new int32(21));
TSharedPtr<int32> TempC(TempB);
always_check(!(TempA == TempB));
always_check(TempA != TempB);
always_check(TempB == TempC);
}
{
TSharedPtr<int32> TempA(new int32(64));
TSharedPtr<int32> TempB(new int32(21));
TWeakPtr<int32> WeakA(TempA);
TWeakPtr<int32> WeakB(TempB);
TWeakPtr<int32> WeakC(TempB);
always_check(!(WeakA.Lock() == WeakB.Lock()));
always_check(WeakA.Lock() != WeakB.Lock());
always_check(WeakB.Lock() == WeakC.Lock());
}
{
TSharedPtr<const int32> TempA(new int32(10));
TSharedPtr<const float32> TempB(new float32(1.0f));
TSharedPtr<const float32> TempC(new float32(2.0f));
if (TempB == TempC) { }
TempB = TempC;
TSharedPtr<float32> TempD(new float32(123.0f));
TempB = TempD;
TWeakPtr<const float32> TempE = TempB;
TWeakPtr<float32> TempF;
TempF = ConstCast<float32>(TempC);
*TempF.Lock() = 20.0f;
}
{
TSharedPtr<struct FTest> Temp;
struct FTest { int32 Value; };
Temp = TSharedPtr<FTest>(new FTest());
Temp->Value = 20;
}
{
TSharedPtr<bool> TempA(nullptr);
TSharedPtr<float32> TempB = nullptr;
TWeakPtr<bool> TempD(nullptr);
TWeakPtr<float32> TempE = nullptr;
TempB = TSharedPtr<float32>(new float32(0.1f));
TempB = nullptr;
TempB = MakeShared<float32>(30.0f);
TSharedPtr<float64> TempC(MakeShared<float64>(2.0));
struct FTest
{
TSharedPtr<float32> Value;
TSharedPtr<float32> FuncA() { return Value; }
TSharedPtr<float32> FuncB() { return MakeShared<float32>(123.0f); }
};
}
{
TSharedRef<float32> Temp(new float32(123.0f));
}
{
TSharedRef<float32> Temp(new float32(123.0f));
const float& RefA = *Temp;
const float& RefB = *Temp.Get();
}
{
TSharedRef<float32> Temp = MakeShared<float32>(123.0f);
}
{
TSharedRef<int32> TempA(new int32(1));
TSharedPtr<int32> TempB(TempA);
}
{
TSharedPtr<int32> TempA(new int32(1));
TSharedRef<int32> TempB(TempA.ToSharedRef());
}
{
TSharedRef<int32> Temp(new int32(10));
Temp = TSharedRef<int32>(new int32(20));
}
{
TSharedRef<int32> TempA(new int32(99));
TWeakPtr<int32> TempB = TempA;
always_check(TempB.Lock());
}
{
TSharedRef<int32> IntRef1(new int32(99));
TSharedRef<int32> IntRef2(new int32(21));
always_check(!(IntRef1 == IntRef2));
always_check(IntRef1 != IntRef2);
}
{
TSharedRef<int32> TempA(new int32(21));
TSharedPtr<int32> TempB(TempA);
TSharedPtr<int32> TempC;
always_check(TempA == TempB && TempB == TempA);
always_check(!(TempA != TempB || TempB != TempA));
always_check(!(TempA == TempC) && (TempA != TempC));
}
{
struct FTest : public TSharedFromThis<FTest>
{
TSharedRef<FTest> FuncTest() { return AsShared(); }
};
TSharedPtr<FTest> TempA(new FTest());
{
FTest* Ptr = TempA.Get();
TSharedRef<FTest> TempB(Ptr->FuncTest());
}
}
{
TSharedRef<int32> TempA = MakeShared<int32>();
TSharedRef<const int32> TempB = TempA;
TSharedRef<const int32> TempC = MakeShared<int32>();
TempC = TempA;
}
{
TSharedRef<int32[]> TempA = MakeShared<int32[]>(4);
TSharedRef<const int32[]> TempB = TempA;
TSharedRef<const int32[]> TempC = MakeShared<int32[]>(4);
TempC = TempA;
}
{
TSharedPtr<int32> TempA;
TSharedPtr<const int32> TempB = TempA;
TSharedPtr<const int32> TempC;
TempC = TempA;
}
{
TSharedPtr<int32[]> TempA;
TSharedPtr<const int32[]> TempB = TempA;
TSharedPtr<const int32[]> TempC;
TempC = TempA;
}
{
TWeakPtr<int32> TempA;
TWeakPtr<const int32> TempB = TempA;
TWeakPtr<const int32> TempC;
TempC = TempA;
}
{
TWeakPtr<int32[]> TempA;
TWeakPtr<const int32[]> TempB = TempA;
TWeakPtr<const int32[]> TempC;
TempC = TempA;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -16,3 +16,4 @@
#include "Templates/Atomic.h"
#include "Templates/ScopeHelper.h"
#include "Templates/UniquePointer.h"
#include "Templates/SharedPointer.h"

View File

@ -407,7 +407,7 @@ public:
/** Move assignment operator. Transfers ownership from 'InValue' to *this. */
template <typename U, typename InE> requires (CConvertibleTo<U*, T*>
&& !CArray<U> && !CReference<E> && CAssignableFrom<E&, InE&&>)
FORCEINLINE constexpr TUniquePtr& operator=(TUniquePtr<U, E>&& InValue)
FORCEINLINE constexpr TUniquePtr& operator=(TUniquePtr<U, InE>&& InValue)
{
Reset(InValue.Release());
GetDeleter() = Forward<InE>(InValue.GetDeleter());
@ -526,7 +526,7 @@ public:
FORCEINLINE constexpr TUniquePtr(TUniquePtr&& InValue) : Storage(InValue.Release(), Forward<E>(InValue.GetDeleter())) { }
/** Constructs a TUniquePtr by transferring ownership from 'InValue' to *this and stores the nullptr in 'InValue'. */
template <typename U, typename InE> requires (CConvertibleTo<U(*)[], T(*)[]> && CArray<U>
template <typename U, typename InE> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]> && CArray<U>
&& ((CReference<E> && CSameAs<InE, E>) || (!CReference<E> && CConvertibleTo<InE, E>)))
FORCEINLINE constexpr TUniquePtr(TUniquePtr<U, InE>&& InValue) : Storage(InValue.Release(), Forward<InE>(InValue.GetDeleter())) { }
@ -542,9 +542,9 @@ public:
}
/** Move assignment operator. Transfers ownership from 'InValue' to *this. */
template <typename U, typename InE> requires (CConvertibleTo<U(*)[], T(*)[]>
template <typename U, typename InE> requires (CConvertibleTo<TRemoveExtent<U>(*)[], T(*)[]>
&& CArray<U> && !CReference<E> && CAssignableFrom<E&, InE&&>)
FORCEINLINE constexpr TUniquePtr& operator=(TUniquePtr<U, E>&& InValue)
FORCEINLINE constexpr TUniquePtr& operator=(TUniquePtr<U, InE>&& InValue)
{
Reset(InValue.Release());
GetDeleter() = Forward<InE>(InValue.GetDeleter());

View File

@ -19,6 +19,7 @@ REDCRAFTUTILITY_API void TestFunction();
REDCRAFTUTILITY_API void TestAtomic();
REDCRAFTUTILITY_API void TestScopeHelper();
REDCRAFTUTILITY_API void TestUniquePointer();
REDCRAFTUTILITY_API void TestSharedPointer();
REDCRAFTUTILITY_API void TestMiscTemplates();
NAMESPACE_END(Testing)