1 /////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) Electronic Arts Inc. All rights reserved.
3 /////////////////////////////////////////////////////////////////////////////
4 
5 
6 #include "EASTLTest.h"
7 #include <EASTL/string_map.h>
8 #include <EAStdC/EAString.h>
9 
10 using namespace eastl;
11 
12 
13 // Template instantations.
14 // These tell the compiler to compile all the functions for the given class.
15 template class eastl::string_map<int>;
16 template class eastl::string_map<Align32>;
17 
18 static const char* strings[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t" };
19 static const size_t kStringCount = 10; // This is intentionally half the length of strings, so that we can test with strings that are not inserted to the map.
20 
21 
TestStringMap()22 int TestStringMap()
23 {
24 	int nErrorCount = 0;
25 
26 	{  // Test declarations
27 		string_map<int>	stringMap;
28 
29 		string_map<int> stringMap2(stringMap);
30 		EATEST_VERIFY(stringMap2.size() == stringMap.size());
31 		EATEST_VERIFY(stringMap2 == stringMap);
32 
33 
34 		// allocator_type& get_allocator();
35 		// void            set_allocator(const allocator_type& allocator);
36 		string_map<int>::allocator_type& allocator = stringMap.get_allocator();
37 		stringMap.set_allocator(EASTLAllocatorType());
38 		stringMap.set_allocator(allocator);
39 		// To do: Try to find something better to test here.
40 
41 
42 		// const char*     get_name() const;
43 		// void            set_name(const char* pName);
44 #if EASTL_NAME_ENABLED
45 		stringMap.get_allocator().set_name("test");
46 		const char* pName = stringMap.get_allocator().get_name();
47 		EATEST_VERIFY(equal(pName, pName + 5, "test"));
48 #endif
49 	}
50 
51 
52 	{
53 		string_map<int> stringMap;
54 
55 		// Clear a newly constructed, already empty container.
56 		stringMap.clear();
57 		EATEST_VERIFY(stringMap.validate());
58 		EATEST_VERIFY(stringMap.size() == 0);
59 
60 		for (int i = 0; i < (int)kStringCount; i++)
61 			stringMap.insert(strings[i], i);
62 
63 		EATEST_VERIFY(stringMap.validate());
64 		EATEST_VERIFY(stringMap.size() == kStringCount);
65 
66 		stringMap.clear();
67 		EATEST_VERIFY(stringMap.validate());
68 		EATEST_VERIFY(stringMap.size() == 0);
69 
70 		for (int i = 0; i < (int)kStringCount; i++)
71 			stringMap.insert(strings[i], i);
72 		EATEST_VERIFY(stringMap.validate());
73 		EATEST_VERIFY(stringMap.size() == kStringCount);
74 
75 		stringMap.clear();
76 		EATEST_VERIFY(stringMap.validate());
77 		EATEST_VERIFY(stringMap.size() == 0);
78 	}
79 
80 
81 	{   // Test string_map
82 
83 		// size_type          size() const
84 		// bool               empty() const
85 		// insert_return_type insert(const value_type& value);
86 		// insert_return_type insert(const value_type& value, hash_code_t c, node_type* pNodeNew = NULL);
87 		// iterator           insert(const_iterator, const value_type& value);
88 		// iterator           find(const key_type& k);
89 		// const_iterator     find(const key_type& k) const;
90 		// size_type          count(const key_type& k) const;
91 
92 		typedef string_map<int> StringMapInt;
93 
94 		StringMapInt stringMap;
95 
96 		EATEST_VERIFY(stringMap.empty());
97 		EATEST_VERIFY(stringMap.size() == 0);
98 		EATEST_VERIFY(stringMap.count(strings[0]) == 0);
99 
100 		for (int i = 0; i < (int)kStringCount; i++)
101 			stringMap.insert(strings[i], i);
102 
103 		EATEST_VERIFY(!stringMap.empty());
104 		EATEST_VERIFY(stringMap.size() == kStringCount);
105 		EATEST_VERIFY(stringMap.count(strings[0]) == 1);
106 
107 		int j = 0;
108 		for (StringMapInt::iterator it = stringMap.begin(); it != stringMap.end(); ++it, ++j)
109 		{
110 			int value = (*it).second;
111 			EATEST_VERIFY(value < (int)kStringCount);
112 		}
113 
114 		for (int i = 0; i < (int)kStringCount * 2; i++)
115 		{
116 			StringMapInt::iterator it = stringMap.find(strings[i]);
117 
118 			if (i < (int)kStringCount)
119 			{
120 				EATEST_VERIFY(it != stringMap.end());
121 				const char* k = (*it).first;
122 				int v = (*it).second;
123 				EATEST_VERIFY(EA::StdC::Strcmp(k, strings[i]) == 0);
124 				EATEST_VERIFY(v == i);
125 			}
126 			else
127 				EATEST_VERIFY(it == stringMap.end());
128 		}
129 
130 		StringMapInt::insert_return_type result = stringMap.insert("EASTLTEST");
131 		EATEST_VERIFY(result.second == true);
132 		result = stringMap.insert("EASTLTEST");
133 		EATEST_VERIFY(result.second == false);
134 		result.first->second = 0;
135 
136 		// iterator erase(const_iterator);
137 		size_t nExpectedSize = stringMap.size();
138 
139 		StringMapInt::iterator itD = stringMap.find("d");
140 		EATEST_VERIFY(itD != stringMap.end());
141 
142 		// erase the element and verify that the size has decreased
143 		stringMap.erase(itD);
144 		nExpectedSize--;
145 		EATEST_VERIFY(stringMap.size() == nExpectedSize);
146 
147 		// verify that erased element is gone
148 		itD = stringMap.find(strings[3]);
149 		EATEST_VERIFY(itD == stringMap.end());
150 
151 		// iterator erase(const char*)
152 		StringMapInt::size_type n = stringMap.erase(strings[4]);
153 		nExpectedSize--;
154 		EATEST_VERIFY(n == 1);
155 		EATEST_VERIFY(stringMap.size() == nExpectedSize);
156 
157 
158 		// mapped_type& operator[](const key_type& key)
159 		stringMap.clear();
160 
161 		int x = stringMap["A"]; // A default-constructed int (i.e. 0) should be returned.
162 		EATEST_VERIFY(x == 0);
163 
164 		stringMap["B"] = 1;
165 		x = stringMap["B"];
166 		EATEST_VERIFY(x == 1);     // Verify that the value we assigned is returned and a default-constructed value is not returned.
167 
168 		stringMap["A"] = 10;    // Overwrite our previous 0 with 10.
169 		stringMap["B"] = 11;
170 		x = stringMap["A"];
171 		EATEST_VERIFY(x == 10);    // Verify the value is as expected.
172 		x = stringMap["B"];
173 		EATEST_VERIFY(x == 11);
174 
175 	}
176 
177 
178 	{
179 		// string_map(const allocator_type& allocator);
180 		// string_map& operator=(const this_type& x);
181 		// bool validate() const;
182 
183 		string_map<int> stringMap1(EASTLAllocatorType("TestStringMap"));
184 		string_map<int> stringMap2(stringMap1);
185 
186 		for (int i = 0; i < (int)kStringCount; i++)
187 		{
188 			stringMap1.insert(strings[i], i);
189 		}
190 
191 		stringMap2 = stringMap1;
192 		string_map<int> stringMap3(stringMap1);
193 
194 		EATEST_VERIFY(stringMap1.validate());
195 		EATEST_VERIFY(stringMap2.validate());
196 		EATEST_VERIFY(stringMap3.validate());
197 
198 		for (int i = 0; i < (int)kStringCount; i++)
199 		{
200 			EATEST_VERIFY(stringMap1[strings[i]] == stringMap2[strings[i]]);
201 			EATEST_VERIFY(stringMap1[strings[i]] == stringMap3[strings[i]]);
202 		}
203 
204 	}
205 
206 	return nErrorCount;
207 }
208