refactor(templates): optimize the implementation of TOptional and TVariant
This commit is contained in:
@ -85,247 +85,277 @@ void TestReferenceWrapper()
|
||||
|
||||
void TestOptional()
|
||||
{
|
||||
TOptional<int32> TempA;
|
||||
TOptional<int32> TempB(Invalid);
|
||||
TOptional<int32> TempC(InPlace, 0);
|
||||
TOptional<int32> TempD(0);
|
||||
TOptional<int32> TempE(0l);
|
||||
TOptional<int32> TempF(0.0);
|
||||
TOptional<int32> TempG(TempA);
|
||||
TOptional<int32> TempH(TempD);
|
||||
TOptional<int32> TempI(MakeOptional<int32>(0));
|
||||
TOptional<int32> TempJ(MakeOptional<int32>(Invalid));
|
||||
|
||||
TOptional<int32> TempK, TempL, TempM, TempN;
|
||||
TempK = TempA;
|
||||
TempL = TempD;
|
||||
TempM = MakeOptional<int32>(0);
|
||||
TempN = MakeOptional<int32>(Invalid);
|
||||
|
||||
*TempL = 303;
|
||||
*TempM = 404;
|
||||
|
||||
TOptional<int32> TempO;
|
||||
TempO.Emplace(404);
|
||||
|
||||
always_check(TempO);
|
||||
always_check(TempO.IsValid());
|
||||
|
||||
always_check(*TempO == 404);
|
||||
always_check(TempO.GetValue() == 404);
|
||||
always_check(TempO.Get(500) == 404);
|
||||
|
||||
TempO.Reset();
|
||||
always_check(TempO == TempO);
|
||||
always_check(!(TempO != TempO));
|
||||
always_check(TempO.Get(500) == 500);
|
||||
|
||||
int32 TempP = 200;
|
||||
TempO = TempP;
|
||||
TempO = 300;
|
||||
|
||||
always_check(TempO != TempA);
|
||||
always_check(TempO != TempD);
|
||||
always_check(TempO == TempO);
|
||||
always_check(TempO == 300);
|
||||
always_check(300 == TempO);
|
||||
|
||||
int16 TempQ = 1024;
|
||||
TOptional<int16> TempR = TempQ;
|
||||
|
||||
TOptional<int32> TempS(InPlace, TempQ);
|
||||
TOptional<int32> TempT(TempQ);
|
||||
TOptional<int32> TempU(TempR);
|
||||
TOptional<int32> TempV(MakeOptional<int16>(2048));
|
||||
|
||||
TOptional<int32> TempW, TempX, TempY;
|
||||
TempW = TempQ;
|
||||
TempX = TempR;
|
||||
TempY = MakeOptional<int16>(2048);
|
||||
|
||||
struct FTracker
|
||||
{
|
||||
FTracker() { }
|
||||
FTracker(const FTracker& InValue) { always_check_no_entry(); }
|
||||
FTracker(FTracker&& InValue) { }
|
||||
FTracker& operator=(const FTracker& InValue) { always_check_no_entry(); return *this; }
|
||||
FTracker& operator=(FTracker&& InValue) { return *this; }
|
||||
};
|
||||
TOptional<int32> TempA;
|
||||
TOptional<int32> TempB(Invalid);
|
||||
TOptional<int32> TempC(InPlace, 0);
|
||||
TOptional<int32> TempD(0);
|
||||
TOptional<int32> TempE(0l);
|
||||
TOptional<int32> TempF(0.0);
|
||||
TOptional<int32> TempG(TempA);
|
||||
TOptional<int32> TempH(TempD);
|
||||
TOptional<int32> TempI(MakeOptional<int32>(0));
|
||||
TOptional<int32> TempJ(MakeOptional<int32>(Invalid));
|
||||
|
||||
TOptional<FTracker> TempZ(MakeOptional<FTracker>());
|
||||
TempZ = MakeOptional<FTracker>();
|
||||
TempZ = FTracker();
|
||||
TOptional<int32> TempK, TempL, TempM, TempN;
|
||||
TempK = TempA;
|
||||
TempL = TempD;
|
||||
TempM = MakeOptional<int32>(0);
|
||||
TempN = MakeOptional<int32>(Invalid);
|
||||
|
||||
always_check(GetTypeHash(MakeOptional<int32>(114)) == GetTypeHash(MakeOptional<int32>(114)));
|
||||
always_check(GetTypeHash(MakeOptional<int32>(114)) != GetTypeHash(MakeOptional<int32>(514)));
|
||||
*TempL = 303;
|
||||
*TempM = 404;
|
||||
|
||||
TOptional<int32> TempO;
|
||||
TempO.Emplace(404);
|
||||
|
||||
always_check(TempO);
|
||||
always_check(TempO.IsValid());
|
||||
|
||||
always_check(*TempO == 404);
|
||||
always_check(TempO.GetValue() == 404);
|
||||
always_check(TempO.Get(500) == 404);
|
||||
|
||||
TempO.Reset();
|
||||
always_check(TempO == TempO);
|
||||
always_check(!(TempO != TempO));
|
||||
always_check(TempO.Get(500) == 500);
|
||||
|
||||
int32 TempP = 200;
|
||||
TempO = TempP;
|
||||
TempO = 300;
|
||||
|
||||
always_check(TempO != TempA);
|
||||
always_check(TempO != TempD);
|
||||
always_check(TempO == TempO);
|
||||
always_check(TempO == 300);
|
||||
always_check(300 == TempO);
|
||||
|
||||
int16 TempQ = 1024;
|
||||
TOptional<int16> TempR = TempQ;
|
||||
|
||||
TOptional<int32> TempS(InPlace, TempQ);
|
||||
TOptional<int32> TempT(TempQ);
|
||||
TOptional<int32> TempU(TempR);
|
||||
TOptional<int32> TempV(MakeOptional<int16>(2048));
|
||||
|
||||
TOptional<int32> TempW, TempX, TempY;
|
||||
TempW = TempQ;
|
||||
TempX = TempR;
|
||||
TempY = MakeOptional<int16>(2048);
|
||||
|
||||
struct FTracker
|
||||
{
|
||||
FTracker() { }
|
||||
FTracker(const FTracker& InValue) { always_check_no_entry(); }
|
||||
FTracker(FTracker&& InValue) { }
|
||||
FTracker& operator=(const FTracker& InValue) { always_check_no_entry(); return *this; }
|
||||
FTracker& operator=(FTracker&& InValue) { return *this; }
|
||||
};
|
||||
|
||||
TOptional<FTracker> TempZ(MakeOptional<FTracker>());
|
||||
TempZ = MakeOptional<FTracker>();
|
||||
TempZ = FTracker();
|
||||
|
||||
always_check(GetTypeHash(MakeOptional<int32>(114)) == GetTypeHash(MakeOptional<int32>(114)));
|
||||
always_check(GetTypeHash(MakeOptional<int32>(114)) != GetTypeHash(MakeOptional<int32>(514)));
|
||||
}
|
||||
|
||||
{
|
||||
TOptional<uint8> TempA = Invalid;
|
||||
TOptional<int16> TempB = 16;
|
||||
TOptional<int64> TempC = 32;
|
||||
|
||||
always_check(TempA != TempB);
|
||||
always_check(TempB != TempC);
|
||||
always_check(TempB <= TempC);
|
||||
always_check(TempA <=> TempB == partial_ordering::unordered);
|
||||
}
|
||||
}
|
||||
|
||||
void TestVariant()
|
||||
{
|
||||
TVariant<int32> TempA;
|
||||
TVariant<int32> TempB(Invalid);
|
||||
TVariant<int32> TempC(InPlaceType<int32>, 0);
|
||||
TVariant<int32> TempD(0);
|
||||
TVariant<int32> TempE(0l);
|
||||
TVariant<int32> TempF(0.0);
|
||||
TVariant<int32> TempG(TempA);
|
||||
TVariant<int32> TempH(TempD);
|
||||
TVariant<int32> TempI(TVariant<int32>(0));
|
||||
TVariant<int32> TempJ(TVariant<int32>(Invalid));
|
||||
|
||||
TVariant<int32> TempK, TempL, TempM, TempN;
|
||||
TempK = TempA;
|
||||
TempL = TempD;
|
||||
TempM = TVariant<int32>(0);
|
||||
TempN = TVariant<int32>(Invalid);
|
||||
|
||||
TempL = 303;
|
||||
TempM = 404;
|
||||
|
||||
TVariant<int32> TempO;
|
||||
TempO.Emplace<int32>(202);
|
||||
TempO.Emplace<0>(404);
|
||||
|
||||
always_check(TempO);
|
||||
always_check(TempO.IsValid());
|
||||
|
||||
always_check(TempO == 404);
|
||||
always_check(TempO.GetValue<int32>() == 404);
|
||||
always_check(TempO.Get<0>(500) == 404);
|
||||
|
||||
TempO.Reset();
|
||||
always_check(TempO == TempO);
|
||||
always_check(!(TempO != TempO));
|
||||
always_check(TempO.Get<int32>(500) == 500);
|
||||
|
||||
int32 TempP = 200;
|
||||
TempO = TempP;
|
||||
TempO = 300;
|
||||
|
||||
always_check(TempO != TempA);
|
||||
always_check(TempO != TempD);
|
||||
always_check(TempO == TempO);
|
||||
always_check(TempO == 300);
|
||||
always_check(300 == TempO);
|
||||
|
||||
Swap(TempD, TempA);
|
||||
|
||||
int16 TempQ = 1024;
|
||||
TVariant<int16, int32> TempR = TempQ;
|
||||
|
||||
TVariant<int16, int32> TempS(InPlaceType<int32>, TempQ);
|
||||
TVariant<int16, int32> TempT(TempQ);
|
||||
TVariant<int16, int32> TempU(TempR);
|
||||
TVariant<int16, int32> TempV(TVariant<int16, int32>(2048));
|
||||
|
||||
TVariant<int16, int32> TempW, TempX, TempY;
|
||||
TempW = TempQ;
|
||||
TempX = TempR;
|
||||
TempY = TVariant<int16, int32>(2048);
|
||||
|
||||
Swap(TempW, TempX);
|
||||
Swap(TempW, TempX);
|
||||
|
||||
struct FTracker
|
||||
{
|
||||
FTracker() { }
|
||||
FTracker(const FTracker& InValue) { always_check_no_entry(); }
|
||||
FTracker(FTracker&& InValue) { }
|
||||
FTracker& operator=(const FTracker& InValue) { always_check_no_entry(); return *this; }
|
||||
FTracker& operator=(FTracker&& InValue) { return *this; }
|
||||
};
|
||||
TVariant<int32> TempA;
|
||||
TVariant<int32> TempB(Invalid);
|
||||
TVariant<int32> TempC(InPlaceType<int32>, 0);
|
||||
TVariant<int32> TempD(0);
|
||||
TVariant<int32> TempE(0l);
|
||||
TVariant<int32> TempF(0.0);
|
||||
TVariant<int32> TempG(TempA);
|
||||
TVariant<int32> TempH(TempD);
|
||||
TVariant<int32> TempI(TVariant<int32>(0));
|
||||
TVariant<int32> TempJ(TVariant<int32>(Invalid));
|
||||
|
||||
TVariant<FTracker> TempZ(Invalid);
|
||||
TempZ = TVariant<FTracker>();
|
||||
TempZ = FTracker();
|
||||
TVariant<int32> TempK, TempL, TempM, TempN;
|
||||
TempK = TempA;
|
||||
TempL = TempD;
|
||||
TempM = TVariant<int32>(0);
|
||||
TempN = TVariant<int32>(Invalid);
|
||||
|
||||
always_check((TIsSame<int32, TVariantAlternativeType<0, TVariant<int32, float>>::Type>::Value));
|
||||
always_check((TIsSame<float, TVariantAlternativeType<1, TVariant<int32, float>>::Type>::Value));
|
||||
always_check((TIsSame<const int32, TVariantAlternativeType<0, const TVariant<int32, float>>::Type>::Value));
|
||||
TempL = 303;
|
||||
TempM = 404;
|
||||
|
||||
always_check((TVariantAlternativeIndex<int32, TVariant<int32, float>>::Value == 0));
|
||||
always_check((TVariantAlternativeIndex<float, TVariant<int32, float>>::Value == 1));
|
||||
TVariant<int32> TempO;
|
||||
TempO.Emplace<int32>(202);
|
||||
TempO.Emplace<0>(404);
|
||||
|
||||
bool bIsConst;
|
||||
bool bIsLValue;
|
||||
bool bIsRValue;
|
||||
always_check(TempO);
|
||||
always_check(TempO.IsValid());
|
||||
|
||||
auto TestQualifiers = [&bIsConst, &bIsLValue, &bIsRValue](auto&& Arg) -> int32
|
||||
always_check(TempO == 404);
|
||||
always_check(TempO.GetValue<int32>() == 404);
|
||||
always_check(TempO.Get<0>(500) == 404);
|
||||
|
||||
TempO.Reset();
|
||||
always_check(TempO == TempO);
|
||||
always_check(!(TempO != TempO));
|
||||
always_check(TempO.Get<int32>(500) == 500);
|
||||
|
||||
int32 TempP = 200;
|
||||
TempO = TempP;
|
||||
TempO = 300;
|
||||
|
||||
always_check(TempO != TempA);
|
||||
always_check(TempO != TempD);
|
||||
always_check(TempO == TempO);
|
||||
always_check(TempO == 300);
|
||||
always_check(300 == TempO);
|
||||
|
||||
Swap(TempD, TempA);
|
||||
|
||||
int16 TempQ = 1024;
|
||||
TVariant<int16, int32> TempR = TempQ;
|
||||
|
||||
TVariant<int16, int32> TempS(InPlaceType<int32>, TempQ);
|
||||
TVariant<int16, int32> TempT(TempQ);
|
||||
TVariant<int16, int32> TempU(TempR);
|
||||
TVariant<int16, int32> TempV(TVariant<int16, int32>(2048));
|
||||
|
||||
TVariant<int16, int32> TempW, TempX, TempY;
|
||||
TempW = TempQ;
|
||||
TempX = TempR;
|
||||
TempY = TVariant<int16, int32>(2048);
|
||||
|
||||
Swap(TempW, TempX);
|
||||
Swap(TempW, TempX);
|
||||
}
|
||||
|
||||
{
|
||||
using T = decltype(Arg);
|
||||
always_check(Arg == 10);
|
||||
always_check(TIsConst<typename TRemoveReference<T>::Type>::Value == bIsConst);
|
||||
always_check(TIsLValueReference<T>::Value == bIsLValue);
|
||||
always_check(TIsRValueReference<T>::Value == bIsRValue);
|
||||
return 0;
|
||||
};
|
||||
struct FTracker
|
||||
{
|
||||
FTracker() { }
|
||||
FTracker(const FTracker& InValue) { always_check_no_entry(); }
|
||||
FTracker(FTracker&& InValue) { }
|
||||
FTracker& operator=(const FTracker& InValue) { always_check_no_entry(); return *this; }
|
||||
FTracker& operator=(FTracker&& InValue) { return *this; }
|
||||
};
|
||||
|
||||
bIsConst = false;
|
||||
bIsLValue = true;
|
||||
bIsRValue = false;
|
||||
TVariant<FTracker> TempZ(Invalid);
|
||||
TempZ = TVariant<FTracker>();
|
||||
TempZ = FTracker();
|
||||
|
||||
TVariant<int32> TempLA = 10;
|
||||
auto ReturnLA = TempLA.Visit(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnLA)>::Value));
|
||||
always_check((TIsSame<int32, TVariantAlternativeType<0, TVariant<int32, float>>::Type>::Value));
|
||||
always_check((TIsSame<float, TVariantAlternativeType<1, TVariant<int32, float>>::Type>::Value));
|
||||
always_check((TIsSame<const int32, TVariantAlternativeType<0, const TVariant<int32, float>>::Type>::Value));
|
||||
|
||||
bIsConst = true;
|
||||
bIsLValue = true;
|
||||
bIsRValue = false;
|
||||
always_check((TVariantAlternativeIndex<int32, TVariant<int32, float>>::Value == 0));
|
||||
always_check((TVariantAlternativeIndex<float, TVariant<int32, float>>::Value == 1));
|
||||
|
||||
const TVariant<int32> TempLB = TempLA;
|
||||
auto ReturnLB = TempLB.Visit(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnLB)>::Value));
|
||||
bool bIsConst;
|
||||
bool bIsLValue;
|
||||
bool bIsRValue;
|
||||
|
||||
auto TestQualifiers = [&bIsConst, &bIsLValue, &bIsRValue](auto&& Arg) -> int32
|
||||
{
|
||||
using T = decltype(Arg);
|
||||
always_check(Arg == 10);
|
||||
always_check(TIsConst<typename TRemoveReference<T>::Type>::Value == bIsConst);
|
||||
always_check(TIsLValueReference<T>::Value == bIsLValue);
|
||||
always_check(TIsRValueReference<T>::Value == bIsRValue);
|
||||
return 0;
|
||||
};
|
||||
|
||||
bIsConst = false;
|
||||
bIsLValue = true;
|
||||
bIsRValue = false;
|
||||
|
||||
TVariant<int32> TempLA = 10;
|
||||
auto ReturnLA = TempLA.Visit(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnLA)>::Value));
|
||||
|
||||
bIsConst = true;
|
||||
bIsLValue = true;
|
||||
bIsRValue = false;
|
||||
|
||||
const TVariant<int32> TempLB = TempLA;
|
||||
auto ReturnLB = TempLB.Visit(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnLB)>::Value));
|
||||
|
||||
bIsConst = false;
|
||||
bIsLValue = false;
|
||||
bIsRValue = true;
|
||||
|
||||
TVariant<int32> TempRA = 10;
|
||||
auto ReturnRA = MoveTemp(TempRA).Visit(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnRA)>::Value));
|
||||
|
||||
bIsConst = true;
|
||||
bIsLValue = false;
|
||||
bIsRValue = true;
|
||||
|
||||
const TVariant<int32> TempRB = TempLA;
|
||||
auto ReturnRB = MoveTemp(TempRB).Visit(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnRB)>::Value));
|
||||
|
||||
bIsConst = false;
|
||||
bIsLValue = true;
|
||||
bIsRValue = false;
|
||||
|
||||
TVariant<int32> TempLC = 10;
|
||||
auto ReturnLC = TempLC.Visit<int32>(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnLC)>::Value));
|
||||
|
||||
bIsConst = true;
|
||||
bIsLValue = true;
|
||||
bIsRValue = false;
|
||||
|
||||
const TVariant<int32> TempLD = TempLC;
|
||||
auto ReturnLD = TempLD.Visit<int32>(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnLD)>::Value));
|
||||
|
||||
bIsConst = false;
|
||||
bIsLValue = false;
|
||||
bIsRValue = true;
|
||||
|
||||
TVariant<int32> TempRC = 10;
|
||||
auto ReturnRC = MoveTemp(TempRC).Visit<int32>(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnRC)>::Value));
|
||||
|
||||
bIsConst = true;
|
||||
bIsLValue = false;
|
||||
bIsRValue = true;
|
||||
|
||||
const TVariant<int32> TempRD = TempLC;
|
||||
auto ReturnRD = MoveTemp(TempRD).Visit<int32>(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnRD)>::Value));
|
||||
|
||||
always_check(GetTypeHash(TVariant<int32, float>(114)) == GetTypeHash(TVariant<int32, float>(114)));
|
||||
always_check(GetTypeHash(TVariant<int32, float>(114)) != GetTypeHash(TVariant<int32, float>(514)));
|
||||
}
|
||||
|
||||
bIsConst = false;
|
||||
bIsLValue = false;
|
||||
bIsRValue = true;
|
||||
{
|
||||
TVariant<uint8, int16, int32> TempA = Invalid;
|
||||
TVariant<uint8, int16, int32> TempB = static_cast<int16>(16);
|
||||
TVariant<uint8, int16, int32> TempC = static_cast<int32>(16);
|
||||
TVariant<uint8, int16, int32> TempD = static_cast<int32>(32);
|
||||
|
||||
TVariant<int32> TempRA = 10;
|
||||
auto ReturnRA = MoveTemp(TempRA).Visit(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnRA)>::Value));
|
||||
|
||||
bIsConst = true;
|
||||
bIsLValue = false;
|
||||
bIsRValue = true;
|
||||
|
||||
const TVariant<int32> TempRB = TempLA;
|
||||
auto ReturnRB = MoveTemp(TempRB).Visit(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnRB)>::Value));
|
||||
|
||||
bIsConst = false;
|
||||
bIsLValue = true;
|
||||
bIsRValue = false;
|
||||
|
||||
TVariant<int32> TempLC = 10;
|
||||
auto ReturnLC = TempLC.Visit<int32>(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnLC)>::Value));
|
||||
|
||||
bIsConst = true;
|
||||
bIsLValue = true;
|
||||
bIsRValue = false;
|
||||
|
||||
const TVariant<int32> TempLD = TempLC;
|
||||
auto ReturnLD = TempLD.Visit<int32>(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnLD)>::Value));
|
||||
|
||||
bIsConst = false;
|
||||
bIsLValue = false;
|
||||
bIsRValue = true;
|
||||
|
||||
TVariant<int32> TempRC = 10;
|
||||
auto ReturnRC = MoveTemp(TempRC).Visit<int32>(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnRC)>::Value));
|
||||
|
||||
bIsConst = true;
|
||||
bIsLValue = false;
|
||||
bIsRValue = true;
|
||||
|
||||
const TVariant<int32> TempRD = TempLC;
|
||||
auto ReturnRD = MoveTemp(TempRD).Visit<int32>(TestQualifiers);
|
||||
always_check((TIsSame<int32, decltype(ReturnRD)>::Value));
|
||||
|
||||
always_check(GetTypeHash(TVariant<int32, float>(114)) == GetTypeHash(TVariant<int32, float>(114)));
|
||||
always_check(GetTypeHash(TVariant<int32, float>(114)) != GetTypeHash(TVariant<int32, float>(514)));
|
||||
always_check(TempA != TempB);
|
||||
always_check(TempB != TempC);
|
||||
always_check(TempB != TempC);
|
||||
always_check(TempD >= TempC);
|
||||
always_check(TempA <=> TempB == partial_ordering::unordered);
|
||||
}
|
||||
}
|
||||
|
||||
void TestAny()
|
||||
@ -530,6 +560,19 @@ void TestAny()
|
||||
TempZ = FAny();
|
||||
TempZ = FTracker();
|
||||
}
|
||||
|
||||
{
|
||||
FAny TempA = Invalid;
|
||||
FAny TempB = static_cast<int16>(16);
|
||||
FAny TempC = static_cast<int32>(16);
|
||||
FAny TempD = static_cast<int32>(32);
|
||||
|
||||
always_check(TempA != TempB);
|
||||
always_check(TempB != TempC);
|
||||
always_check(TempB != TempC);
|
||||
always_check(TempD >= TempC);
|
||||
always_check(TempA <=> TempB == partial_ordering::unordered);
|
||||
}
|
||||
}
|
||||
|
||||
void TestTuple()
|
||||
|
Reference in New Issue
Block a user