diff options
Diffstat (limited to 'EASTL/test/source/TestVariant.cpp')
-rw-r--r-- | EASTL/test/source/TestVariant.cpp | 1025 |
1 files changed, 979 insertions, 46 deletions
diff --git a/EASTL/test/source/TestVariant.cpp b/EASTL/test/source/TestVariant.cpp index 8c71eda..2a78a89 100644 --- a/EASTL/test/source/TestVariant.cpp +++ b/EASTL/test/source/TestVariant.cpp @@ -7,12 +7,34 @@ #include <EASTL/string.h> #include <EASTL/algorithm.h> #include <EASTL/sort.h> +#include <EASTL/bonus/overloaded.h> #ifdef EA_COMPILER_CPP14_ENABLED #include "ConceptImpls.h" #include <EASTL/variant.h> +#if EASTL_EXCEPTIONS_ENABLED + +// Intentionally Non-Trivial. +// There are optimizations we can make in variant if the types are trivial that we don't currently do but can do. +template <typename T> +struct valueless_struct +{ + valueless_struct() {} + + valueless_struct(const valueless_struct&) {} + + ~valueless_struct() {} + + struct exception_tag {}; + + operator T() const { throw exception_tag{}; } +}; + +#endif + + int TestVariantAlternative() { using namespace eastl; @@ -270,7 +292,7 @@ int TestVariantHoldsAlternative() VERIFY(!holds_alternative<long>(v)); // Verify that a query for a T not in the variant typelist returns false. VERIFY(!holds_alternative<string>(v)); // Verify that a query for a T not in the variant typelist returns false. - VERIFY(!holds_alternative<int>(v)); // variant does not hold an int + VERIFY(!holds_alternative<int>(v)); // variant does not hold an int VERIFY(!holds_alternative<short>(v)); // variant does not hold a short } @@ -356,7 +378,7 @@ int TestVariantValuelessByException() VERIFY(!v.valueless_by_exception()); } - // TODO(rparolin): review exception safety for variant types + // TODO(rparolin): review exception safety for variant types // // { // #if EASTL_EXCEPTIONS_ENABLED @@ -542,12 +564,12 @@ int TestVariantSwap() v1.swap(v2); - VERIFY(get<int>(v1) == 24); + VERIFY(get<int>(v1) == 24); VERIFY(get<int>(v2) == 42); v1.swap(v2); - VERIFY(get<int>(v1) == 42); + VERIFY(get<int>(v1) == 42); VERIFY(get<int>(v2) == 24); } @@ -555,13 +577,13 @@ int TestVariantSwap() variant<string> v1 = "Hello"; variant<string> v2 = "World"; - VERIFY(get<string>(v1) == "Hello"); + VERIFY(get<string>(v1) == "Hello"); VERIFY(get<string>(v2) == "World"); v1.swap(v2); VERIFY(get<string>(v1) == "World"); - VERIFY(get<string>(v2) == "Hello"); + VERIFY(get<string>(v2) == "Hello"); } return nErrorCount; @@ -625,32 +647,178 @@ int TestVariantInplaceCtors() return nErrorCount; } +// Many Compilers are smart and will fully inline the visitor in our unittests, +// Thereby not actually testing the recursive call. +EA_NO_INLINE int TestVariantVisitNoInline(const eastl::variant<int, bool, unsigned>& v) +{ + int nErrorCount = 0; + + bool bVisited = false; -int TestVariantVisitor() + struct MyVisitor + { + MyVisitor() = delete; + MyVisitor(bool& visited) : mVisited(visited) {}; + + void operator()(int) { mVisited = true; } + void operator()(bool) { mVisited = true; } + void operator()(unsigned) { mVisited = true; } + + bool& mVisited; + }; + + eastl::visit(MyVisitor(bVisited), v); + + EATEST_VERIFY(bVisited); + + return nErrorCount; +} + +EA_NO_INLINE int TestVariantVisit2NoInline(const eastl::variant<int, bool>& v0, const eastl::variant<int, bool>& v1) +{ + int nErrorCount = 0; + + bool bVisited = false; + + struct MyVisitor + { + MyVisitor() = delete; + MyVisitor(bool& visited) : mVisited(visited) {}; + + void operator()(int, int) { mVisited = true; } + void operator()(bool, int) { mVisited = true; } + void operator()(int, bool) { mVisited = true; } + void operator()(bool, bool) { mVisited = true; } + + bool& mVisited; + }; + + eastl::visit(MyVisitor(bVisited), v0, v1); + + EATEST_VERIFY(bVisited); + + return nErrorCount; +} + +EA_NO_INLINE int TestVariantVisit3tNoInline(const eastl::variant<int, bool>& v0, const eastl::variant<int, bool>& v1, const eastl::variant<int, bool>& v2) +{ + int nErrorCount = 0; + + bool bVisited = false; + + struct MyVisitor + { + MyVisitor() = delete; + MyVisitor(bool& visited) : mVisited(visited) {}; + + void operator()(int, int, int) { mVisited = true; } + void operator()(bool, int, int) { mVisited = true; } + void operator()(int, bool, int) { mVisited = true; } + void operator()(bool, bool, int) { mVisited = true; } + + void operator()(int, int, bool) { mVisited = true; } + void operator()(bool, int, bool) { mVisited = true; } + void operator()(int, bool, bool) { mVisited = true; } + void operator()(bool, bool, bool) { mVisited = true; } + + bool& mVisited; + }; + + eastl::visit(MyVisitor(bVisited), v0, v1, v2); + + EATEST_VERIFY(bVisited); + + return nErrorCount; +} + +int TestVariantVisitorOverloaded() { using namespace eastl; int nErrorCount = 0; using v_t = variant<int, string, double, long>; + v_t arr[] = {42, "jean", 42.0, 42L}; + v_t v{42.0}; + + + #ifdef __cpp_deduction_guides + { + int count = 0; + + for (auto& e : arr) + { + eastl::visit( + overloaded{ + [&](int) { count++; }, + [&](string) { count++; }, + [&](double) { count++; }, + [&](long) { count++; }}, + e + ); + } - // TODO(rparolin): When we have a C++17 compiler - // - // template deduction guides test - // template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; - // template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; + VERIFY(count == EAArrayCount(arr)); + } - // { - // v_t arr[] = {42, "rob", 42.0, 42L}; + { + double visitedValue = 0.0f; + + eastl::visit( + overloaded{ + [](int) { }, + [](string) { }, + [&](double d) { visitedValue = d; }, + [](long) { }}, + v + ); + + VERIFY(visitedValue == 42.0f); + } - // int count = 0; - // for (auto& e : arr) - // { - // eastl::visit(overloaded{[&](int) { count++; }, - // [&](string) { count++; }, - // [&](double) { count++; }, - // [&](long) { count++; }}, e); - // } - // } + #endif + + { + int count = 0; + + for (auto& e : arr) + { + eastl::visit( + eastl::make_overloaded( + [&](int) { count++; }, + [&](string) { count++; }, + [&](double) { count++; }, + [&](long) { count++; }), + e + ); + } + + VERIFY(count == EAArrayCount(arr)); + } + + { + double visitedValue = 0.0f; + + eastl::visit( + eastl::make_overloaded( + [](int) { }, + [](string) { }, + [&](double d) { visitedValue = d; }, + [](long) { }), + v + ); + + VERIFY(visitedValue == 42.0f); + } + + return nErrorCount; +} + +int TestVariantVisitor() +{ + using namespace eastl; + int nErrorCount = 0; + + using v_t = variant<int, string, double, long>; { v_t arr[] = {42, "hello", 42.0, 42L}; @@ -662,6 +830,14 @@ int TestVariantVisitor() } VERIFY(count == EAArrayCount(arr)); + + count = 0; + for (auto& e : arr) + { + eastl::visit<void>([&](auto){ count++; }, e); + } + + VERIFY(count == EAArrayCount(arr)); } { @@ -671,14 +847,171 @@ int TestVariantVisitor() struct MyVisitor { - MyVisitor& operator()(int) { bVisited = true; return *this; }; - MyVisitor& operator()(long) { return *this; }; - MyVisitor& operator()(string) { return *this; }; - MyVisitor& operator()(unsigned) { return *this; }; // not in variant + void operator()(int) { bVisited = true; }; + void operator()(long) { }; + void operator()(string) { }; + void operator()(unsigned) { }; // not in variant }; visit(MyVisitor{}, v); VERIFY(bVisited); + + bVisited = false; + + visit<void>(MyVisitor{}, v); + VERIFY(bVisited); + } + + { + static bool bVisited = false; + + variant<int, bool, unsigned> v = (int)1; + + struct MyVisitor + { + bool& operator()(int) { return bVisited; } + bool& operator()(bool) { return bVisited; } + bool& operator()(unsigned) { return bVisited; } + }; + + bool& ret = visit(MyVisitor{}, v); + ret = true; + VERIFY(bVisited); + + bVisited = false; + bool& ret2 = visit<bool&>(MyVisitor{}, v); + ret2 = true; + VERIFY(bVisited); + } + + { + variant<int, bool, unsigned> v = (int)1; + + struct MyVisitor + { + void operator()(int& i) { i = 2; } + void operator()(bool&) {} + void operator()(unsigned&) {} + }; + + visit(MyVisitor{}, v); + EATEST_VERIFY(get<0>(v) == (int)2); + + v = (int)1; + visit<void>(MyVisitor{}, v); + EATEST_VERIFY(get<0>(v) == (int)2); + } + + { + static bool bVisited = false; + + variant<int, bool, unsigned> v =(int)1; + + struct MyVisitor + { + void operator()(const int&) { bVisited = true; } + void operator()(const bool&) {} + void operator()(const unsigned&) {} + }; + + visit(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + + bVisited = false; + visit<void>(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + } + + { + static bool bVisited = false; + + const variant<int, bool, unsigned> v =(int)1; + + struct MyVisitor + { + void operator()(const int&) { bVisited = true; } + void operator()(const bool&) {} + void operator()(const unsigned&) {} + }; + + visit(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + + bVisited = false; + visit<void>(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + } + + { + static bool bVisited = false; + + struct MyVisitor + { + void operator()(int&&) { bVisited = true; } + void operator()(bool&&) {} + void operator()(unsigned&&) {} + }; + + visit(MyVisitor{}, variant<int, bool, unsigned>{(int)1}); + EATEST_VERIFY(bVisited); + + visit<void>(MyVisitor{}, variant<int, bool, unsigned>{(int)1}); + EATEST_VERIFY(bVisited); + } + + { + static bool bVisited = false; + + variant<int, bool, unsigned> v = (int)1; + + struct MyVisitor + { + bool&& operator()(int) { return eastl::move(bVisited); } + bool&& operator()(bool) { return eastl::move(bVisited); } + bool&& operator()(unsigned) { return eastl::move(bVisited); } + }; + + bool&& ret = visit(MyVisitor{}, v); + ret = true; + VERIFY(bVisited); + + bVisited = false; + bool&& ret2 = visit<bool&&>(MyVisitor{}, v); + ret2 = true; + VERIFY(bVisited); + } + + { + variant<int, bool, unsigned> v = (int)1; + + TestVariantVisitNoInline(v); + v = (bool)true; + TestVariantVisitNoInline(v); + v = (int)3; + TestVariantVisitNoInline(v); + } + + { + variant<int, bool> v0 = (int)1; + variant<int, bool> v1 = (bool)true; + + TestVariantVisit2NoInline(v0, v1); + v0 = (bool)false; + TestVariantVisit2NoInline(v0, v1); + v1 = (int)2; + TestVariantVisit2NoInline(v0, v1); + } + + { + variant<int, bool> v0 = (int)1; + variant<int, bool> v1 = (int)2; + variant<int, bool> v2 = (int)3; + + TestVariantVisit3tNoInline(v0, v1, v2); + v2 = (bool)false; + TestVariantVisit3tNoInline(v0, v1, v2); + v0 = (bool)true; + TestVariantVisit3tNoInline(v0, v1, v2); } { @@ -695,11 +1028,43 @@ int TestVariantVisitor() MultipleVisitor& operator()(string, string) { return *this; } }; - visit(MultipleVisitor{}, i, s); + MultipleVisitor& ret = visit(MultipleVisitor{}, i, s); + EA_UNUSED(ret); + VERIFY(bVisited); + + MultipleVisitor& ret2 = visit<MultipleVisitor&>(MultipleVisitor{}, i, s); + EA_UNUSED(ret2); VERIFY(bVisited); } { + bool bVisited = false; + + variant<int, bool> v0 = 0; + variant<int, bool> v1 = 1; + + struct MultipleVisitor + { + MultipleVisitor() = delete; + MultipleVisitor(bool& visited) : mVisited(visited) {}; + + void operator()(int, int) { mVisited = true; } + void operator()(int, bool) {} + void operator()(bool, int) {} + void operator()(bool, bool) {} + + bool& mVisited; + }; + + visit(MultipleVisitor(bVisited), v0, v1); + EATEST_VERIFY(bVisited); + + bVisited = false; + visit<void>(MultipleVisitor(bVisited), v0, v1); + EATEST_VERIFY(bVisited); + } + + { variant<int, string> v = 42; struct ModifyingVisitor @@ -724,24 +1089,128 @@ int TestVariantVisitor() VERIFY(visit(ReturningVisitor{}, v) == 42); } -#if !defined(EA_COMPILER_MSVC) + return nErrorCount; +} + +int TestVariantVisitorReturn() +{ + int nErrorCount = 0; + + { + static bool bVisited = false; + + eastl::variant<int, bool> v = (int)1; + + struct MyVisitor + { + bool operator()(int) { bVisited = true; return true; } + bool operator()(bool) { return false; } + }; + + eastl::visit<void>(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + } + { - variant<int, string> v = 42; + static bool bVisited = false; - struct ReturningDifferentTypesVisitor + eastl::variant<int, bool> v = (int)1; + + struct MyVisitor { - int operator()(int i) {return i;} - size_t operator()(string s) {return s.size();} + bool operator()(int) { bVisited = true; return true; } + bool operator()(bool) { return false; } }; - VERIFY(visit(ReturningDifferentTypesVisitor{}, v) == 42); + eastl::visit<const void>(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + } + + { + static bool bVisited = false; + + eastl::variant<int, bool> v = (int)1; + + struct MyVisitor + { + bool operator()(int) { bVisited = true; return true; } + bool operator()(bool) { return false; } + }; + + eastl::visit<volatile void>(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + } + + { + static bool bVisited = false; + + eastl::variant<int, bool> v = (int)1; + + struct MyVisitor + { + bool operator()(int) { bVisited = true; return true; } + bool operator()(bool) { return false; } + }; + + eastl::visit<const volatile void>(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + } + + { + static bool bVisited = false; + + eastl::variant<int, bool> v = (int)1; + + struct MyVisitor + { + bool operator()(int) { bVisited = true; return true; } + bool operator()(bool) { return false; } + }; + + int ret = eastl::visit<int>(MyVisitor{}, v); + EATEST_VERIFY(bVisited); + EATEST_VERIFY(ret); + } + + { + static bool bVisited = false; + + struct A {}; + struct B : public A {}; + struct C : public A {}; + + eastl::variant<int, bool> v = (int)1; + + struct MyVisitor + { + B operator()(int) { bVisited = true; return B{}; } + C operator()(bool) { return C{}; } + }; + + A ret = eastl::visit<A>(MyVisitor{}, v); + EA_UNUSED(ret); + EATEST_VERIFY(bVisited); + } + + { + static bool bVisited = false; + + eastl::variant<int, bool> v = (int)1; + + struct MyVisitor + { + MyVisitor operator()(int) { bVisited = true; return MyVisitor{}; } + MyVisitor operator()(bool) { return MyVisitor{}; } + }; + + MyVisitor ret = eastl::visit<MyVisitor>(MyVisitor{}, v); + EA_UNUSED(ret); + EATEST_VERIFY(bVisited); } -#endif return nErrorCount; } - int TestVariantAssignment() { using namespace eastl; @@ -825,6 +1294,328 @@ int TestVariantUserRegressionCopyMoveAssignmentOperatorLeak() return nErrorCount; } +int TestVariantRelationalOperators() +{ + int nErrorCount = 0; + + using VariantNoThrow = eastl::variant<int, bool, float>; + + // Equality + { + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ true }; + + EATEST_VERIFY((v1 == v2) == false); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 == v2) == true); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)0 }; + + EATEST_VERIFY((v1 == v2) == false); + } + } + + // Inequality + { + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ true }; + + EATEST_VERIFY((v1 != v2) == true); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 != v2) == false); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)0 }; + + EATEST_VERIFY((v1 != v2) == true); + } + } + + // Less Than + { + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ true }; + + EATEST_VERIFY((v1 < v2) == true); + } + + { + VariantNoThrow v1{ true }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 < v2) == false); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 < v2) == false); + } + + { + VariantNoThrow v1{ (int)0 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 < v2) == true); + } + } + + // Greater Than + { + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ true }; + + EATEST_VERIFY((v1 > v2) == false); + } + + { + VariantNoThrow v1{ true }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 > v2) == true); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 > v2) == false); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)0 }; + + EATEST_VERIFY((v1 > v2) == true); + } + } + + // Less Equal + { + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ true }; + + EATEST_VERIFY((v1 <= v2) == true); + } + + { + VariantNoThrow v1{ true }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 <= v2) == false); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 <= v2) == true); + } + + { + VariantNoThrow v1{ (int)0 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 <= v2) == true); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)0 }; + + EATEST_VERIFY((v1 <= v2) == false); + } + } + + // Greater Equal + { + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ true }; + + EATEST_VERIFY((v1 >= v2) == false); + } + + { + VariantNoThrow v1{ true }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 >= v2) == true); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 >= v2) == true); + } + + { + VariantNoThrow v1{ (int)0 }; + VariantNoThrow v2{ (int)1 }; + + EATEST_VERIFY((v1 >= v2) == false); + } + + { + VariantNoThrow v1{ (int)1 }; + VariantNoThrow v2{ (int)0 }; + + EATEST_VERIFY((v1 >= v2) == true); + } + } + +#if EASTL_EXCEPTIONS_ENABLED + + using VariantThrow = eastl::variant<int, bool, float>; + + auto make_variant_valueless = [](VariantThrow& v) + { + try + { + v.emplace<0>(valueless_struct<int>{}); + } + catch(const typename valueless_struct<int>::exception_tag &) + { + } + }; + + // Equality + { + { + VariantThrow v0{ (int)0 }; + VariantThrow v1{ (int)1 }; + + make_variant_valueless(v0); + make_variant_valueless(v1); + + EATEST_VERIFY((v0 == v1) == true); + } + } + + // Inequality + { + { + VariantThrow v0{ (int)0 }; + VariantThrow v1{ (int)1 }; + + make_variant_valueless(v0); + make_variant_valueless(v1); + + EATEST_VERIFY((v0 != v1) == false); + } + } + + // Less Than + { + { + VariantThrow v0{ (int)0 }; + VariantThrow v1{ (int)1 }; + + make_variant_valueless(v0); + + EATEST_VERIFY((v0 < v1) == true); + } + + { + VariantThrow v0{ (int)0 }; + VariantThrow v1{ (int)1 }; + + make_variant_valueless(v1); + + EATEST_VERIFY((v0 < v1) == false); + } + } + + // Greater Than + { + { + VariantThrow v0{ (int)1 }; + VariantThrow v1{ (int)0 }; + + make_variant_valueless(v0); + + EATEST_VERIFY((v0 > v1) == false); + } + + { + VariantThrow v0{ (int)1 }; + VariantThrow v1{ (int)0 }; + + make_variant_valueless(v1); + + EATEST_VERIFY((v0 > v1) == true); + } + } + + // Less Equal + { + { + VariantThrow v0{ (int)1 }; + VariantThrow v1{ (int)1 }; + + make_variant_valueless(v0); + + EATEST_VERIFY((v0 <= v1) == true); + } + + { + VariantThrow v0{ (int)1 }; + VariantThrow v1{ (int)0 }; + + make_variant_valueless(v1); + + EATEST_VERIFY((v0 <= v1) == false); + } + } + + // Greater Equal + { + { + VariantThrow v0{ (int)1 }; + VariantThrow v1{ (int)1 }; + + make_variant_valueless(v0); + + EATEST_VERIFY((v0 >= v1) == false); + } + + { + VariantThrow v0{ (int)1 }; + VariantThrow v1{ (int)0 }; + + make_variant_valueless(v1); + + EATEST_VERIFY((v0 >= v1) == true); + } + } + +#endif + + return nErrorCount; +} + int TestVariantUserRegressionIncompleteType() { @@ -848,6 +1639,155 @@ int TestVariantUserRegressionIncompleteType() return nErrorCount; } +#define EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(Type, VarName) \ + bool operator==(const Type & rhs) const { return VarName == rhs.VarName; } \ + bool operator!=(const Type & rhs) const { return VarName != rhs.VarName; } \ + bool operator<(const Type & rhs) const { return VarName < rhs.VarName; } \ + bool operator>(const Type & rhs) const { return VarName > rhs.VarName; } \ + bool operator<=(const Type & rhs) const { return VarName <= rhs.VarName; } \ + bool operator>=(const Type & rhs) const { return VarName >= rhs.VarName; } + +int TestBigVariantComparison() +{ + int nErrorCount = 0; + + struct A; + struct B; + struct C; + struct D; + struct E; + struct F; + struct G; + struct H; + struct I; + struct J; + struct K; + struct L; + struct M; + struct N; + struct O; + struct P; + struct Q; + struct R; + struct S; + struct T; + struct U; + struct V; + struct W; + struct X; + struct Y; + struct Z; + + using BigVariant = eastl::variant<A, B, C, D, E, F, G, H, I, J, K, L, M, N, + O, P, Q, R, S, T, U, V, W, X, Y, Z>; + + struct A { int a; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(A, a) }; + struct B { int b; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(B, b) }; + struct C { int c; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(C, c) }; + struct D { int d; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(D, d) }; + struct E { int e; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(E, e) }; + struct F { int f; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(F, f) }; + struct G { int g; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(G, g) }; + struct H { int h; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(H, h) }; + struct I { int i; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(I, i) }; + struct J { int j; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(J, j) }; + struct K { int k; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(K, k) }; + struct L { int l; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(L, l) }; + struct M { int m; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(M, m) }; + struct N { int n; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(N, n) }; + struct O { int o; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(O, o) }; + struct P { int p; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(P, p) }; + struct Q { int q; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(Q, q) }; + struct R { int r; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(R, r) }; + struct S { int s; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(S, s) }; + struct T { int t; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(T, t) }; + struct U { int u; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(U, u) }; + struct V { int v; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(V, v) }; + struct W { int w; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(W, w) }; + struct X { int x; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(X, x) }; + struct Y { int y; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(Y, y) }; + struct Z { int z; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(Z, z) }; + + { + BigVariant v0{ A{0} }; + BigVariant v1{ A{1} }; + + VERIFY(v0 != v1); + } + + { + BigVariant v0{ A{0} }; + BigVariant v1{ A{1} }; + + VERIFY(v0 < v1); + } + + { + BigVariant v0{ A{0} }; + BigVariant v1{ A{0} }; + + VERIFY(v0 == v1); + } + + { + BigVariant v0{ A{1} }; + BigVariant v1{ A{0} }; + + VERIFY(v0 > v1); + } + + { + BigVariant v0{ A{0} }; + BigVariant v1{ A{1} }; + + VERIFY(v0 <= v1); + } + + { + BigVariant v0{ A{0} }; + BigVariant v1{ A{0} }; + + VERIFY(v0 <= v1); + } + + { + BigVariant v0{ A{0} }; + BigVariant v1{ A{0} }; + + VERIFY(v0 >= v1); + } + + { + BigVariant v0{ A{1} }; + BigVariant v1{ A{0} }; + + VERIFY(v0 >= v1); + } + + { + BigVariant v0{ A{0} }; + BigVariant v1{ B{0} }; + + VERIFY(v0 != v1); + } + + { + BigVariant v0{ A{0} }; + BigVariant v1{ B{0} }; + + VERIFY(v0 < v1); + } + + { + BigVariant v0{ A{0} }; + BigVariant v1{ B{0} }; + + VERIFY(v1 > v0); + } + + return nErrorCount; +} + int TestVariantGeneratingComparisonOverloads(); int TestVariant() @@ -866,25 +1806,18 @@ int TestVariant() nErrorCount += TestVariantEmplace(); nErrorCount += TestVariantRelOps(); nErrorCount += TestVariantInplaceCtors(); + nErrorCount += TestVariantVisitorOverloaded(); nErrorCount += TestVariantVisitor(); nErrorCount += TestVariantAssignment(); nErrorCount += TestVariantMoveOnly(); nErrorCount += TestVariantUserRegressionCopyMoveAssignmentOperatorLeak(); nErrorCount += TestVariantUserRegressionIncompleteType(); nErrorCount += TestVariantGeneratingComparisonOverloads(); + nErrorCount += TestBigVariantComparison(); + nErrorCount += TestVariantRelationalOperators(); return nErrorCount; } #else int TestVariant() { return 0; } #endif - - - - - - - - - - |