aboutsummaryrefslogtreecommitdiff
path: root/test/source/TestOptional.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/source/TestOptional.cpp')
-rw-r--r--test/source/TestOptional.cpp695
1 files changed, 0 insertions, 695 deletions
diff --git a/test/source/TestOptional.cpp b/test/source/TestOptional.cpp
deleted file mode 100644
index 36307ad..0000000
--- a/test/source/TestOptional.cpp
+++ /dev/null
@@ -1,695 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Copyright (c) Electronic Arts Inc. All rights reserved.
-/////////////////////////////////////////////////////////////////////////////
-
-#include "EASTLTest.h"
-#include <EASTL/type_traits.h>
-#include <EASTL/sort.h>
-#include <EASTL/vector.h>
-#include <EASTL/string.h>
-#include <EASTL/optional.h>
-#include <EASTL/unique_ptr.h>
-
-
-/////////////////////////////////////////////////////////////////////////////
-struct IntStruct
-{
- IntStruct(int in) : data(in) {}
- int data;
-};
-
-#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
-auto operator<=>(const IntStruct& lhs, const IntStruct& rhs) { return lhs.data <=> rhs.data; }
-#else
-bool operator<(const IntStruct& lhs, const IntStruct& rhs)
- { return lhs.data < rhs.data; }
-#endif
-bool operator==(const IntStruct& lhs, const IntStruct& rhs)
- { return lhs.data == rhs.data; }
-
-
-
-/////////////////////////////////////////////////////////////////////////////
-struct destructor_test
-{
- ~destructor_test() { destructor_ran = true; }
- static bool destructor_ran;
- static void reset() { destructor_ran = false; }
-};
-bool destructor_test::destructor_ran = false;
-
-/////////////////////////////////////////////////////////////////////////////
-struct move_test
-{
- move_test() = default;
- move_test(move_test&&) { was_moved = true; }
- move_test& operator=(move_test&&) { was_moved = true; return *this;}
-
- // issue a compiler error is container tries to copy
- move_test(move_test const&) = delete;
- move_test& operator=(const move_test&) = delete;
-
- static bool was_moved;
-};
-
-bool move_test::was_moved = false;
-
-/////////////////////////////////////////////////////////////////////////////
-template <typename T>
-class forwarding_test
-{
- eastl::optional<T> m_optional;
-
-public:
- forwarding_test() : m_optional() {}
- forwarding_test(T&& t) : m_optional(t) {}
- ~forwarding_test() { m_optional.reset(); }
-
- template <typename U>
- T GetValueOrDefault(U&& def) const
- {
- return m_optional.value_or(eastl::forward<U>(def));
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////
-struct assignment_test
-{
- assignment_test() { ++num_objects_inited; }
- assignment_test(assignment_test&&) { ++num_objects_inited; }
- assignment_test(const assignment_test&) { ++num_objects_inited; }
- assignment_test& operator=(assignment_test&&) { return *this; }
- assignment_test& operator=(const assignment_test&) { return *this; }
- ~assignment_test() { --num_objects_inited; }
-
- static int num_objects_inited;
-};
-
-int assignment_test::num_objects_inited = 0;
-
-
-/////////////////////////////////////////////////////////////////////////////
-// TestOptional
-//
-int TestOptional()
-{
- using namespace eastl;
- int nErrorCount = 0;
- #if defined(EASTL_OPTIONAL_ENABLED) && EASTL_OPTIONAL_ENABLED
- {
- {
- VERIFY( (is_same<optional<int>::value_type, int>::value));
- VERIFY( (is_same<optional<short>::value_type, short>::value));
- VERIFY(!(is_same<optional<short>::value_type, long>::value));
- VERIFY( (is_same<optional<const short>::value_type, const short>::value));
- VERIFY( (is_same<optional<volatile short>::value_type, volatile short>::value));
- VERIFY( (is_same<optional<const volatile short>::value_type, const volatile short>::value));
-
- VERIFY(is_empty<nullopt_t>::value);
- #if EASTL_TYPE_TRAIT_is_literal_type_CONFORMANCE
- VERIFY(is_literal_type<nullopt_t>::value);
- #endif
-
- #if EASTL_TYPE_TRAIT_is_trivially_destructible_CONFORMANCE
- VERIFY(is_trivially_destructible<int>::value);
- VERIFY(is_trivially_destructible<Internal::optional_storage<int>>::value);
- VERIFY(is_trivially_destructible<optional<int>>::value);
- VERIFY(is_trivially_destructible<optional<int>>::value == is_trivially_destructible<int>::value);
- #endif
-
- {
- struct NotTrivialDestructible { ~NotTrivialDestructible() {} };
- VERIFY(!is_trivially_destructible<NotTrivialDestructible>::value);
- VERIFY(!is_trivially_destructible<optional<NotTrivialDestructible>>::value);
- VERIFY(!is_trivially_destructible<Internal::optional_storage<NotTrivialDestructible>>::value);
- VERIFY(is_trivially_destructible<optional<NotTrivialDestructible>>::value == is_trivially_destructible<NotTrivialDestructible>::value);
- }
- }
-
- {
- optional<int> o;
- VERIFY(!o);
- VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D);
- o = 1024;
- VERIFY(static_cast<bool>(o));
- VERIFY(o.value_or(0x8BADF00D) == 1024);
- VERIFY(o.value() == 1024);
-
- // Test reset
- o.reset();
- VERIFY(!o);
- VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D);
- }
-
- {
- optional<int> o(nullopt);
- VERIFY(!o);
- VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D);
- }
-
- {
- optional<int> o = {};
- VERIFY(!o);
- VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D);
- }
-
- {
- optional<int> o(42);
- VERIFY(bool(o));
- VERIFY(o.value_or(0x8BADF00D) == 42);
- o = nullopt;
- VERIFY(!o);
- VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D);
- }
-
- {
- optional<int> o(42);
- VERIFY(static_cast<bool>(o));
- VERIFY(o.value_or(0x8BADF00D) == 42);
- VERIFY(o.value() == 42);
- }
-
- {
- auto o = make_optional(42);
- VERIFY((is_same<decltype(o), optional<int>>::value));
- VERIFY(static_cast<bool>(o));
- VERIFY(o.value_or(0x8BADF00D) == 42);
- VERIFY(o.value() == 42);
- }
-
- {
- int a = 42;
- auto o = make_optional(a);
- VERIFY((is_same<decltype(o)::value_type, int>::value));
- VERIFY(o.value() == 42);
- }
-
- {
- // test make_optional stripping refs/cv-qualifers
- int a = 42;
- const volatile int& intRef = a;
- auto o = make_optional(intRef);
- VERIFY((is_same<decltype(o)::value_type, int>::value));
- VERIFY(o.value() == 42);
- }
-
- {
- int a = 10;
- const volatile int& aRef = a;
- auto o = eastl::make_optional(aRef);
- VERIFY(o.value() == 10);
- }
-
- {
- {
- struct local { int payload1; };
- auto o = eastl::make_optional<local>(42);
- VERIFY(o.value().payload1 == 42);
- }
- {
- struct local { int payload1; int payload2; };
- auto o = eastl::make_optional<local>(42, 43);
- VERIFY(o.value().payload1 == 42);
- VERIFY(o.value().payload2 == 43);
- }
-
- {
- struct local
- {
- local(std::initializer_list<int> ilist)
- {
- payload1 = ilist.begin()[0];
- payload2 = ilist.begin()[1];
- }
-
- int payload1;
- int payload2;
- };
-
- auto o = eastl::make_optional<local>({42, 43});
- VERIFY(o.value().payload1 == 42);
- VERIFY(o.value().payload2 == 43);
- }
- }
-
- {
- optional<int> o1(42), o2(24);
- VERIFY(o1.value() == 42);
- VERIFY(o2.value() == 24);
- VERIFY(*o1 == 42);
- VERIFY(*o2 == 24);
- o1 = eastl::move(o2);
- VERIFY(*o2 == 24);
- VERIFY(*o1 == 24);
- VERIFY(o2.value() == 24);
- VERIFY(o1.value() == 24);
- VERIFY(bool(o1));
- VERIFY(bool(o2));
- }
-
- {
- struct local { int payload; };
- optional<local> o = local{ 42 };
- VERIFY(o->payload == 42);
- }
-
- {
- struct local
- {
- int test() const { return 42; }
- };
-
- {
- const optional<local> o = local{};
- VERIFY(o->test() == 42);
- VERIFY((*o).test() == 42);
- VERIFY(o.value().test() == 42);
- VERIFY(bool(o));
- }
-
- {
- optional<local> o = local{};
- VERIFY(bool(o));
- o = nullopt;
- VERIFY(!bool(o));
-
- VERIFY(o.value_or(local{}).test() == 42);
- VERIFY(!bool(o));
- }
- }
- }
-
- {
- move_test t;
- optional<move_test> o(eastl::move(t));
- VERIFY(move_test::was_moved);
- }
-
- {
- forwarding_test<float>ft(1.f);
- float val = ft.GetValueOrDefault(0.f);
- VERIFY(val == 1.f);
- }
-
- {
- assignment_test::num_objects_inited = 0;
- {
- optional<assignment_test> o1;
- optional<assignment_test> o2 = assignment_test();
- optional<assignment_test> o3(o2);
- VERIFY(assignment_test::num_objects_inited == 2);
- o1 = nullopt;
- VERIFY(assignment_test::num_objects_inited == 2);
- o1 = o2;
- VERIFY(assignment_test::num_objects_inited == 3);
- o1 = o2;
- VERIFY(assignment_test::num_objects_inited == 3);
- o1 = nullopt;
- VERIFY(assignment_test::num_objects_inited == 2);
- o2 = o1;
- VERIFY(assignment_test::num_objects_inited == 1);
- o1 = o2;
- VERIFY(assignment_test::num_objects_inited == 1);
- }
- VERIFY(assignment_test::num_objects_inited == 0);
-
- {
- optional<assignment_test> o1;
- VERIFY(assignment_test::num_objects_inited == 0);
- o1 = nullopt;
- VERIFY(assignment_test::num_objects_inited == 0);
- o1 = optional<assignment_test>(assignment_test());
- VERIFY(assignment_test::num_objects_inited == 1);
- o1 = optional<assignment_test>(assignment_test());
- VERIFY(assignment_test::num_objects_inited == 1);
- optional<assignment_test> o2(eastl::move(o1));
- VERIFY(assignment_test::num_objects_inited == 2);
- o1 = nullopt;
- VERIFY(assignment_test::num_objects_inited == 1);
- }
- VERIFY(assignment_test::num_objects_inited == 0);
- }
-
- #if EASTL_VARIADIC_TEMPLATES_ENABLED
- {
- struct vec3
- {
- vec3(std::initializer_list<float> ilist) { auto* p = ilist.begin(); x = *p++; y = *p++; z = *p++; }
- vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} // testing variadic template constructor overload
- float x = 0, y = 0, z = 0;
- };
-
- {
- optional<vec3> o{ in_place, 4.f, 5.f, 6.f };
- VERIFY(o->x == 4 && o->y == 5 && o->z == 6);
- }
-
- {
- optional<vec3> o{ in_place, {4.f, 5.f, 6.f} };
- VERIFY(o->x == 4 && o->y == 5 && o->z == 6);
- }
-
- {
- optional<string> o(in_place, {'a', 'b', 'c'});
- VERIFY(o == string("abc"));
- }
-
- // http://en.cppreference.com/w/cpp/utility/optional/emplace
- {
- optional<vec3> o;
- o.emplace(42.f, 42.f, 42.f);
- VERIFY(o->x == 42.f && o->y == 42.f && o->z == 42.f);
- }
-
- {
- optional<vec3> o;
- o.emplace({42.f, 42.f, 42.f});
- VERIFY(o->x == 42.f && o->y == 42.f && o->z == 42.f);
- }
-
- {
- optional<int> o;
- o.emplace(42);
- VERIFY(*o == 42);
- }
-
- struct nonCopyableNonMovable
- {
- nonCopyableNonMovable(int v) : val(v) {}
-
- nonCopyableNonMovable(const nonCopyableNonMovable&) = delete;
- nonCopyableNonMovable(nonCopyableNonMovable&&) = delete;
- nonCopyableNonMovable& operator=(const nonCopyableNonMovable&) = delete;
-
- int val = 0;
- };
-
- {
- optional<nonCopyableNonMovable> o;
- o.emplace(42);
- VERIFY(o->val == 42);
- }
-
- {
- // Verify emplace will destruct object if it has been engaged.
- destructor_test::reset();
- optional<destructor_test> o;
- o.emplace();
- VERIFY(!destructor_test::destructor_ran);
-
- destructor_test::reset();
- o.emplace();
- VERIFY(destructor_test::destructor_ran);
- }
- }
- #endif
-
-
- // swap
- {
- {
- optional<int> o1 = 42, o2 = 24;
- VERIFY(*o1 == 42);
- VERIFY(*o2 == 24);
- o1.swap(o2);
- VERIFY(*o1 == 24);
- VERIFY(*o2 == 42);
- }
-
- {
- optional<int> o1 = 42, o2 = 24;
- VERIFY(*o1 == 42);
- VERIFY(*o2 == 24);
- swap(o1, o2);
- VERIFY(*o1 == 24);
- VERIFY(*o2 == 42);
- }
-
- {
- optional<int> o1 = 42, o2;
- VERIFY(*o1 == 42);
- VERIFY(o2.has_value() == false);
- swap(o1, o2);
- VERIFY(o1.has_value() == false);
- VERIFY(*o2 == 42);
- }
-
- {
- optional<int> o1 = nullopt, o2 = 42;
- VERIFY(o1.has_value() == false);
- VERIFY(*o2 == 42);
- swap(o1, o2);
- VERIFY(*o1 == 42);
- VERIFY(o2.has_value() == false);
- }
- }
-
- {
- optional<IntStruct> o(in_place, 10);
- optional<IntStruct> e;
-
- VERIFY(o < IntStruct(42));
- VERIFY(!(o < IntStruct(2)));
- VERIFY(!(o < IntStruct(10)));
- VERIFY(e < o);
- VERIFY(e < IntStruct(10));
-
- VERIFY(o > IntStruct(4));
- VERIFY(!(o > IntStruct(42)));
-
- VERIFY(o >= IntStruct(4));
- VERIFY(o >= IntStruct(10));
- VERIFY(IntStruct(4) <= o);
- VERIFY(IntStruct(10) <= o);
-
- VERIFY(o == IntStruct(10));
- VERIFY(o->data == IntStruct(10).data);
-
- VERIFY(o != IntStruct(11));
- VERIFY(o->data != IntStruct(11).data);
-
- VERIFY(e == nullopt);
- VERIFY(nullopt == e);
-
- VERIFY(o != nullopt);
- VERIFY(nullopt != o);
- VERIFY(nullopt < o);
- VERIFY(o > nullopt);
- VERIFY(!(nullopt > o));
- VERIFY(!(o < nullopt));
- VERIFY(nullopt <= o);
- VERIFY(o >= nullopt);
- }
-
- #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
- {
- optional<IntStruct> o(in_place, 10);
- optional<IntStruct> e;
-
- VERIFY((o <=> IntStruct(42)) < 0);
- VERIFY((o <=> IntStruct(2)) >= 0);
- VERIFY((o <=> IntStruct(10)) >= 0);
- VERIFY((e <=> o) < 0);
- VERIFY((e <=> IntStruct(10)) < 0);
-
- VERIFY((o <=> IntStruct(4)) > 0);
- VERIFY(o <=> IntStruct(42) <= 0);
-
- VERIFY((o <=> IntStruct(4)) >= 0);
- VERIFY((o <=> IntStruct(10)) >= 0);
- VERIFY((IntStruct(4) <=> o) <= 0);
- VERIFY((IntStruct(10) <=> o) <= 0);
-
- VERIFY((o <=> IntStruct(10)) == 0);
- VERIFY((o->data <=> IntStruct(10).data) == 0);
-
- VERIFY((o <=> IntStruct(11)) != 0);
- VERIFY((o->data <=> IntStruct(11).data) != 0);
-
- VERIFY((e <=> nullopt) == 0);
- VERIFY((nullopt <=> e) == 0);
-
- VERIFY((o <=> nullopt) != 0);
- VERIFY((nullopt <=> o) != 0);
- VERIFY((nullopt <=> o) < 0);
- VERIFY((o <=> nullopt) > 0);
- VERIFY((nullopt <=> o) <= 0);
- VERIFY((o <=> nullopt) >= 0);
- }
- #endif
-
- // hash
- {
- {
- // verify that the hash an empty eastl::optional object is zero.
- typedef hash<optional<int>> hash_optional_t;
- optional<int> e;
- VERIFY(hash_optional_t{}(e) == 0);
- }
-
- {
- // verify that the hash is the same as the hash of the underlying type
- const char* const pMessage = "Electronic Arts Canada";
- typedef hash<optional<string>> hash_optional_t;
- optional<string> o = string(pMessage);
- VERIFY(hash_optional_t{}(o) == hash<string>{}(pMessage));
- }
- }
-
- // sorting
- {
- vector<optional<int>> v = {{122}, {115}, nullopt, {223}};
- sort(begin(v), end(v));
- vector<optional<int>> sorted = {nullopt, 115, 122, 223};
-
- VERIFY(v == sorted);
- }
-
- // test destructors being called.
- {
- destructor_test::reset();
- {
- optional<destructor_test> o = destructor_test{};
- }
- VERIFY(destructor_test::destructor_ran);
-
- destructor_test::reset();
- {
- optional<destructor_test> o;
- }
- // destructor shouldn't be called as object wasn't constructed.
- VERIFY(!destructor_test::destructor_ran);
-
-
- destructor_test::reset();
- {
- optional<destructor_test> o = {};
- }
- // destructor shouldn't be called as object wasn't constructed.
- VERIFY(!destructor_test::destructor_ran);
-
- destructor_test::reset();
- {
- optional<destructor_test> o = nullopt;
- }
- // destructor shouldn't be called as object wasn't constructed.
- VERIFY(!destructor_test::destructor_ran);
- }
-
- // optional rvalue tests
- {
- VERIFY(*optional<uint32_t>(1u) == 1u);
- VERIFY(optional<uint32_t>(1u).value() == 1u);
- VERIFY(optional<uint32_t>(1u).value_or(0xdeadf00d) == 1u);
- VERIFY(optional<uint32_t>().value_or(0xdeadf00d) == 0xdeadf00d);
- VERIFY(optional<uint32_t>(1u).has_value() == true);
- VERIFY(optional<uint32_t>().has_value() == false);
- VERIFY( optional<IntStruct>(in_place, 10)->data == 10);
-
- }
-
- // alignment type tests
- {
- static_assert(alignof(optional<Align16>) == alignof(Align16), "optional alignment failure");
- static_assert(alignof(optional<Align32>) == alignof(Align32), "optional alignment failure");
- static_assert(alignof(optional<Align64>) == alignof(Align64), "optional alignment failure");
- }
-
- {
- // user reported regression that failed to compile
- struct local_struct
- {
- local_struct() {}
- ~local_struct() {}
- };
- static_assert(!eastl::is_trivially_destructible_v<local_struct>, "");
-
- {
- local_struct ls;
- eastl::optional<local_struct> o{ls};
- }
- {
- const local_struct ls;
- eastl::optional<local_struct> o{ls};
- }
- }
-
- {
- {
- // user regression
- eastl::optional<eastl::string> o = eastl::string("Hello World");
- eastl::optional<eastl::string> co;
-
- co = o; // force copy-assignment
-
- VERIFY( o.value().data() != co.value().data());
- VERIFY( o.value().data() == eastl::string("Hello World"));
- VERIFY(co.value().data() == eastl::string("Hello World"));
- }
- {
- // user regression
- EA_DISABLE_VC_WARNING(4625 4626) // copy/assignment operator constructor was implicitly defined as deleted
- struct local
- {
- eastl::unique_ptr<int> ptr;
- };
- EA_RESTORE_VC_WARNING()
-
- eastl::optional<local> o1 = local{eastl::make_unique<int>(42)};
- eastl::optional<local> o2;
-
- o2 = eastl::move(o1);
-
- VERIFY(!!o1 == true);
- VERIFY(!!o2 == true);
- VERIFY(!!o1->ptr == false);
- VERIFY(!!o2->ptr == true);
- VERIFY(o2->ptr.get() != nullptr);
- }
- {
- // user regression
- static bool copyCtorCalledWithUninitializedValue;
- static bool moveCtorCalledWithUninitializedValue;
- copyCtorCalledWithUninitializedValue = moveCtorCalledWithUninitializedValue = false;
- struct local
- {
- uint32_t val;
- local()
- : val(0xabcdabcd)
- {}
- local(const local& other)
- : val(other.val)
- {
- if (other.val != 0xabcdabcd)
- copyCtorCalledWithUninitializedValue = true;
- }
- local(local&& other)
- : val(eastl::move(other.val))
- {
- if (other.val != 0xabcdabcd)
- moveCtorCalledWithUninitializedValue = true;
- }
- local& operator=(const local&) = delete;
- };
- eastl::optional<local> n;
- eastl::optional<local> o1(n);
- VERIFY(!copyCtorCalledWithUninitializedValue);
- eastl::optional<local> o2(eastl::move(n));
- VERIFY(!moveCtorCalledWithUninitializedValue);
- }
- }
-
- {
- auto testFn = []() -> optional<int>
- {
- return eastl::nullopt;
- };
-
- auto o = testFn();
- VERIFY(!!o == false);
- }
-
- #endif // EASTL_OPTIONAL_ENABLED
- return nErrorCount;
-}
-