aboutsummaryrefslogtreecommitdiff
path: root/EASTL/test/source/TestMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'EASTL/test/source/TestMap.cpp')
-rw-r--r--EASTL/test/source/TestMap.cpp305
1 files changed, 305 insertions, 0 deletions
diff --git a/EASTL/test/source/TestMap.cpp b/EASTL/test/source/TestMap.cpp
new file mode 100644
index 0000000..0df8c88
--- /dev/null
+++ b/EASTL/test/source/TestMap.cpp
@@ -0,0 +1,305 @@
+/////////////////////////////////////////////////////////////////////////////
+// Copyright (c) Electronic Arts Inc. All rights reserved.
+/////////////////////////////////////////////////////////////////////////////
+
+
+#include "TestMap.h"
+#include "EASTLTest.h"
+#include <EASTL/map.h>
+#include <EASTL/string.h>
+#include <EASTL/vector.h>
+
+EA_DISABLE_ALL_VC_WARNINGS()
+#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY
+ #include <map>
+#endif
+EA_RESTORE_ALL_VC_WARNINGS()
+
+using namespace eastl;
+
+
+// Template instantations.
+// These tell the compiler to compile all the functions for the given class.
+template class eastl::map<int, int>;
+template class eastl::multimap<int, int>;
+template class eastl::map<TestObject, TestObject>;
+template class eastl::multimap<TestObject, TestObject>;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// typedefs
+//
+typedef eastl::map<int, int> VM1;
+typedef eastl::map<TestObject, TestObject> VM4;
+typedef eastl::multimap<int, int> VMM1;
+typedef eastl::multimap<TestObject, TestObject> VMM4;
+
+#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY
+ typedef std::map<int, int> VM3;
+ typedef std::map<TestObject, TestObject> VM6;
+ typedef std::multimap<int, int> VMM3;
+ typedef std::multimap<TestObject, TestObject> VMM6;
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+int TestMap()
+{
+ int nErrorCount = 0;
+
+ #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY
+ { // Test construction
+ nErrorCount += TestMapConstruction<VM1, VM3, false>();
+ nErrorCount += TestMapConstruction<VM4, VM6, false>();
+
+ nErrorCount += TestMapConstruction<VMM1, VMM3, true>();
+ nErrorCount += TestMapConstruction<VMM4, VMM6, true>();
+ }
+
+
+ { // Test mutating functionality.
+ nErrorCount += TestMapMutation<VM1, VM3, false>();
+ nErrorCount += TestMapMutation<VM4, VM6, false>();
+
+ nErrorCount += TestMapMutation<VMM1, VMM3, true>();
+ nErrorCount += TestMapMutation<VMM4, VMM6, true>();
+ }
+ #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY
+
+
+ { // Test searching functionality.
+ nErrorCount += TestMapSearch<VM1, false>();
+ nErrorCount += TestMapSearch<VM4, false>();
+
+ nErrorCount += TestMapSearch<VMM1, true>();
+ nErrorCount += TestMapSearch<VMM4, true>();
+ }
+
+
+ {
+ // C++11 emplace and related functionality
+ nErrorCount += TestMapCpp11<eastl::map<int, TestObject>>();
+ nErrorCount += TestMultimapCpp11<eastl::multimap<int, TestObject>>();
+ nErrorCount += TestMapCpp11NonCopyable<eastl::map<int, NonCopyable>>();
+ }
+
+ {
+ // C++17 try_emplace and related functionality
+ nErrorCount += TestMapCpp17<eastl::map<int, TestObject>>();
+ }
+
+
+ { // Misc tests
+
+ // const key_compare& key_comp() const;
+ // key_compare& key_comp();
+ VM1 vm;
+ const VM1 vmc;
+
+ const VM1::key_compare& kc = vmc.key_comp();
+ vm.key_comp() = kc;
+ }
+
+
+ // Regressions against user bug reports.
+ {
+ // User reports that the following doesn't compile on GCC 4.1.1 due to unrecognized lower_bound.
+ eastl::map<int, int> m;
+ m[1] = 1;
+ EATEST_VERIFY(m.size() == 1);
+ m.erase(1);
+ EATEST_VERIFY(m.empty());
+ }
+
+ {
+ // User reports that EASTL_VALIDATE_COMPARE_ENABLED / EASTL_COMPARE_VALIDATE isn't compiling for this case.
+ eastl::map<eastl::u8string, int> m;
+ m.find_as(EA_CHAR8("some string"), eastl::equal_to_2<eastl::u8string, const char8_t*>());
+ }
+
+ {
+ eastl::map<int*, int> m;
+ int* ip = (int*)(uintptr_t)0xDEADC0DE;
+
+ m[ip] = 0;
+
+ auto it = m.find_as(ip, eastl::less_2<int*, int*>{});
+ EATEST_VERIFY(it != m.end());
+
+ it = m.find_as((int*)(uintptr_t)0xDEADC0DE, eastl::less_2<int*, int*>{});
+ EATEST_VERIFY(it != m.end());
+ }
+
+ {
+ // User reports that vector<map<enum,enum>> is crashing after the recent changes to add rvalue move and emplace support to rbtree.
+ typedef eastl::map<int, int> IntIntMap;
+ typedef eastl::vector<IntIntMap> IntIntMapArray;
+
+ IntIntMapArray v;
+ v.push_back(IntIntMap()); // This was calling the rbtree move constructor, which had a bug.
+ v[0][16] = 0; // The rbtree was in a bad internal state and so this line resulted in a crash.
+ EATEST_VERIFY(v[0].validate());
+ EATEST_VERIFY(v.validate());
+ }
+
+ {
+ typedef eastl::map<int, int> IntIntMap;
+ IntIntMap map1;
+ map1[1] = 1;
+ map1[3] = 3;
+
+ #if EASTL_EXCEPTIONS_ENABLED
+ EATEST_VERIFY_THROW(map1.at(0));
+ EATEST_VERIFY_THROW(map1.at(2));
+ EATEST_VERIFY_THROW(map1.at(4));
+ #endif
+ map1[0] = 1;
+ #if EASTL_EXCEPTIONS_ENABLED
+ EATEST_VERIFY_NOTHROW(map1.at(0));
+ EATEST_VERIFY_NOTHROW(map1.at(1));
+ EATEST_VERIFY_NOTHROW(map1.at(3));
+ #endif
+ EATEST_VERIFY(map1.at(0) == 1);
+ EATEST_VERIFY(map1.at(1) == 1);
+ EATEST_VERIFY(map1.at(3) == 3);
+
+ const IntIntMap map2;
+ const IntIntMap map3(map1);
+
+ #if EASTL_EXCEPTIONS_ENABLED
+ EATEST_VERIFY_THROW(map2.at(0));
+ EATEST_VERIFY_NOTHROW(map3.at(0));
+ #endif
+ EATEST_VERIFY(map3.at(0) == 1);
+ }
+
+ // User regression test
+ {
+ #if !EASTL_RBTREE_LEGACY_SWAP_BEHAVIOUR_REQUIRES_COPY_CTOR
+ typedef eastl::map<int, MoveOnlyTypeDefaultCtor> IntMOMap;
+
+ IntMOMap m1, m2;
+ m2[0] = MoveOnlyTypeDefaultCtor(0);
+ m2[1] = MoveOnlyTypeDefaultCtor(1);
+
+ EATEST_VERIFY( m1.empty());
+ EATEST_VERIFY(!m2.empty());
+
+ m1.swap(m2);
+
+ EATEST_VERIFY(!m1.empty());
+ EATEST_VERIFY( m2.empty());
+ #endif
+ }
+
+// todo: create a test case for this.
+// {
+// // User reports that an incorrectly wrapped pair key used to insert into an eastl map compiles when it should fire a compiler error about unconvertible types.
+// typedef eastl::pair<eastl::string, eastl::string> PairStringKey;
+// typedef eastl::map<PairStringKey, eastl::string> PairStringMap;
+//
+// PairStringMap p1, p2;
+//
+// p1.insert(PairStringMap::value_type(PairStringKey("key1", "key2"), "data")).first->second = "other_data";
+//
+// PairStringKey key("key1", "key2");
+// PairStringMap::value_type insert_me(key, "data");
+// p2.insert(insert_me).first->second = "other_data";
+//
+// for(auto& e : p1)
+// printf("%s,%s = %s\n", e.first.first.c_str(), e.first.second.c_str(), e.second.c_str());
+//
+// for(auto& e : p2)
+// printf("%s,%s = %s\n", e.first.first.c_str(), e.first.second.c_str(), e.second.c_str());
+//
+// EATEST_VERIFY(p1 == p2);
+// }
+
+ { // Test empty base-class optimization
+ struct UnemptyLess : eastl::less<int>
+ {
+ int foo;
+ };
+
+ typedef eastl::map<int, int, eastl::less<int>> VM1;
+ typedef eastl::map<int, int, UnemptyLess> VM2;
+
+ EATEST_VERIFY(sizeof(VM1) < sizeof(VM2));
+ }
+
+ { // Test erase_if
+ eastl::map<int, int> m = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}};
+ auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
+ VERIFY((m == eastl::map<int, int>{{1, 1},{3, 3}}));
+ VERIFY(numErased == 3);
+ }
+
+ { // Test erase_if
+ eastl::multimap<int, int> m = {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}};
+ auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; });
+ VERIFY((m == eastl::multimap<int, int>{{1, 1}, {1, 1}, {3, 3}}));;
+ VERIFY(numErased == 7);
+ }
+
+#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
+ { // Test map <=>
+ eastl::map<int, int> m1 = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}};
+ eastl::map<int, int> m2 = {{4, 4}, {3, 3}, {2, 2}, {1, 1}, {0, 0}};
+ eastl::map<int, int> m3 = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};
+ eastl::map<int, int> m4 = {{1, 0}, {3, 2}, {5, 4}, {7, 6}, {9, 8}};
+ eastl::map<int, int> m5 = {{0, 1}, {2, 3}, {4, 5}};
+
+ VERIFY(m1 == m2);
+ VERIFY(m1 != m3);
+ VERIFY(m3 != m4);
+ VERIFY(m3 < m4);
+ VERIFY(m5 < m4);
+ VERIFY(m5 < m3);
+
+
+ VERIFY((m1 <=> m2) == 0);
+ VERIFY((m1 <=> m3) != 0);
+ VERIFY((m3 <=> m4) != 0);
+ VERIFY((m3 <=> m4) < 0);
+ VERIFY((m5 <=> m4) < 0);
+ VERIFY((m5 <=> m3) < 0);
+ }
+
+ { // Test multimap <=>
+ eastl::multimap<int, int> m1 = {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {4, 4}, {4, 4}};
+ eastl::multimap<int, int> m2 = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {0, 0}};
+ eastl::multimap<int, int> m3 = {{0, 1}, {2, 3}, {4, 5}, {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};
+ eastl::multimap<int, int> m4 = {{1, 0}, {3, 2}, {5, 4}, {1, 0}, {3, 2}, {5, 4}, {7, 6}, {9, 8}};
+ eastl::multimap<int, int> m5 = {{10, 11}, {10, 11}};
+
+ VERIFY(m1 == m2);
+ VERIFY(m1 != m3);
+ VERIFY(m3 != m4);
+ VERIFY(m3 < m4);
+ VERIFY(m5 > m4);
+ VERIFY(m5 > m3);
+
+ VERIFY((m1 <=> m2) == 0);
+ VERIFY((m1 <=> m3) != 0);
+ VERIFY((m3 <=> m4) != 0);
+ VERIFY((m3 <=> m4) < 0);
+ VERIFY((m5 <=> m4) > 0);
+ VERIFY((m5 <=> m3) > 0);
+ }
+#endif
+
+ return nErrorCount;
+}
+
+
+
+
+
+
+
+
+
+
+