1 /////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) Electronic Arts Inc. All rights reserved.
3 /////////////////////////////////////////////////////////////////////////////
4
5 #include "EASTLTest.h"
6 #include <EASTL/utility.h>
7 #include <EAStdC/EAString.h>
8
9 struct BasicObject
10 {
11 int mX;
BasicObjectBasicObject12 BasicObject(int x) : mX(x) {}
13 };
14
operator ==(const BasicObject & t1,const BasicObject & t2)15 inline bool operator==(const BasicObject& t1, const BasicObject& t2) { return t1.mX == t2.mX; }
16
operator <(const BasicObject & t1,const BasicObject & t2)17 inline bool operator<(const BasicObject& t1, const BasicObject& t2) { return t1.mX < t2.mX; }
18
19 ///////////////////////////////////////////////////////////////////////////////
20 // TestUtilityPair
21 //
TestUtilityPair()22 static int TestUtilityPair()
23 {
24 using namespace eastl;
25
26 int nErrorCount = 0;
27
28 {
29 int _0 = 0, _2 = 2, _3 = 3;
30 float _1f = 1.f;
31
32 // pair();
33 pair<int, float> ifPair1;
34 EATEST_VERIFY((ifPair1.first == 0) && (ifPair1.second == 0.f));
35
36 // pair(const T1& x, const T2& y);
37 pair<int, float> ifPair2(_0, _1f);
38 EATEST_VERIFY((ifPair2.first == 0) && (ifPair2.second == 1.f));
39
40 // template <typename U, typename V>
41 // pair(U&& u, V&& v);
42 pair<int, float> ifPair3(int(0), float(1.f));
43 EATEST_VERIFY((ifPair3.first == 0) && (ifPair3.second == 1.f));
44
45 // template <typename U>
46 // pair(U&& x, const T2& y);
47 const float fConst1 = 1.f;
48 pair<int, float> ifPair4(int(0), fConst1);
49 EATEST_VERIFY((ifPair4.first == 0) && (ifPair4.second == 1.f));
50
51 // template <typename V>
52 // pair(const T1& x, V&& y);
53 const int intConst0 = 0;
54 pair<int, float> ifPair5(intConst0, float(1.f));
55 EATEST_VERIFY((ifPair5.first == 0) && (ifPair5.second == 1.f));
56
57 pair<const int, const int> constIntPair(_2, _3);
58 EATEST_VERIFY((constIntPair.first == 2) && (constIntPair.second == 3));
59
60 // pair(const pair&) = default;
61 pair<int, float> ifPair2Copy(ifPair2);
62 EATEST_VERIFY((ifPair2Copy.first == 0) && (ifPair2Copy.second == 1.f));
63
64 pair<const int, const int> constIntPairCopy(constIntPair);
65 EATEST_VERIFY((constIntPairCopy.first == 2) && (constIntPairCopy.second == 3));
66
67 // template<typename U, typename V>
68 // pair(const pair<U, V>& p);
69 pair<long, double> idPair2(ifPair2);
70 EATEST_VERIFY((idPair2.first == 0) && (idPair2.second == 1.0));
71
72 // pair(pair&& p);
73
74 // template<typename U, typename V>
75 // pair(pair<U, V>&& p);
76
77 // pair& operator=(const pair& p);
78
79 // template<typename U, typename V>
80 // pair& operator=(const pair<U, V>& p);
81
82 // pair& operator=(pair&& p);
83
84 // template<typename U, typename V>
85 // pair& operator=(pair<U, V>&& p);
86
87 // void swap(pair& p);
88
89 // use_self, use_first, use_second
90 use_self<pair<int, float> > usIFPair;
91 use_first<pair<int, float> > u1IFPair;
92 use_second<pair<int, float> > u2IFPair;
93
94 ifPair2 = usIFPair(ifPair2);
95 EATEST_VERIFY((ifPair2.first == 0) && (ifPair2.second == 1));
96
97 int first = u1IFPair(ifPair2);
98 EATEST_VERIFY(first == 0);
99
100 float second = u2IFPair(ifPair2);
101 EATEST_VERIFY(second == 1);
102
103 // make_pair
104 pair<int, float> p1 = make_pair(int(0), float(1));
105 EATEST_VERIFY((p1.first == 0) && (p1.second == 1.f));
106
107 pair<int, float> p2 = make_pair_ref(int(0), float(1));
108 EATEST_VERIFY((p2.first == 0) && (p2.second == 1.f));
109
110 pair<const char*, int> p3 = eastl::make_pair("a", 1);
111 EATEST_VERIFY((EA::StdC::Strcmp(p3.first, "a") == 0) && (p2.second == 1));
112
113 pair<const char*, int> p4 = eastl::make_pair<const char*, int>("a", 1);
114 EATEST_VERIFY((EA::StdC::Strcmp(p4.first, "a") == 0) && (p4.second == 1));
115
116 pair<int, const char*> p5 = eastl::make_pair<int, const char*>(1, "b");
117 EATEST_VERIFY((p5.first == 1) && (EA::StdC::Strcmp(p5.second, "b") == 0));
118
119 #if !defined(EA_COMPILER_NO_AUTO)
120 auto p60 = eastl::make_pair("a", "b"); // Different strings of same length of 1.
121 EATEST_VERIFY((EA::StdC::Strcmp(p60.first, "a") == 0) && (EA::StdC::Strcmp(p60.second, "b") == 0));
122
123 auto p61 = eastl::make_pair("ab", "cd"); // Different strings of same length > 1.
124 EATEST_VERIFY((EA::StdC::Strcmp(p61.first, "ab") == 0) && (EA::StdC::Strcmp(p61.second, "cd") == 0));
125
126 auto p62 = eastl::make_pair("abc", "bcdef"); // Different strings of different length.
127 EATEST_VERIFY((EA::StdC::Strcmp(p62.first, "abc") == 0) && (EA::StdC::Strcmp(p62.second, "bcdef") == 0));
128
129 char strA[] = "a";
130 auto p70 = eastl::make_pair(strA, strA);
131 EATEST_VERIFY((EA::StdC::Strcmp(p70.first, "a") == 0) && (EA::StdC::Strcmp(p70.second, "a") == 0));
132
133 char strBC[] = "bc";
134 auto p71 = eastl::make_pair(strA, strBC);
135 EATEST_VERIFY((EA::StdC::Strcmp(p71.first, "a") == 0) && (EA::StdC::Strcmp(p71.second, "bc") == 0));
136
137 const char cstrA[] = "a";
138 auto p80 = eastl::make_pair(cstrA, cstrA);
139 EATEST_VERIFY((EA::StdC::Strcmp(p80.first, "a") == 0) && (EA::StdC::Strcmp(p80.second, "a") == 0));
140
141 const char cstrBC[] = "bc";
142 auto p81 = eastl::make_pair(cstrA, cstrBC);
143 EATEST_VERIFY((EA::StdC::Strcmp(p81.first, "a") == 0) && (EA::StdC::Strcmp(p81.second, "bc") == 0));
144 #endif
145 }
146
147 {
148 // One-off tests and regressions
149
150 #if EASTL_PAIR_CONFORMANCE // See http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#811
151 pair<char*, char*> zeroLiteralPair(0, 0);
152 EATEST_VERIFY((zeroLiteralPair.first == NULL) && (zeroLiteralPair.second == NULL));
153 #endif
154
155 // template<typename U>
156 // pair(U&& x, const T2& y)
157 typedef eastl::pair<uint16_t, const char8_t*> LCIDMapping;
158 LCIDMapping lcidMappingArray[1] = {LCIDMapping(0x0036, "af")}; // Note that 0x0036 is of type int.
159 EATEST_VERIFY((lcidMappingArray[0].first == 0x0036));
160
161 // template<typename V>
162 // pair(const T1& x, V&& y)
163 typedef eastl::pair<const char8_t*, uint16_t> LCIDMapping2;
164 LCIDMapping2 lcidMapping2Array[1] = {LCIDMapping2("af", 0x0036)};
165 EATEST_VERIFY((lcidMapping2Array[0].second == 0x0036));
166
167 // The following code was giving an EDG compiler:
168 // error 145: a value of type "int" cannot be used to initialize
169 // an entity of type "void *" second(eastl::forward<V>(v)) {}
170 // template <typename U, typename V>
171 // pair(U&& u, V&& v);
172 #if EASTL_PAIR_CONFORMANCE
173 typedef eastl::pair<float*, void*> TestPair1;
174 float fOne = 1.f;
175 TestPair1 testPair1(&fOne, NULL);
176 EATEST_VERIFY(*testPair1.first == 1.f);
177 #endif
178 }
179
180 return nErrorCount;
181 }
182
183 ///////////////////////////////////////////////////////////////////////////////
184 // TestUtilityRelops
185 //
TestUtilityRelops()186 static int TestUtilityRelops()
187 {
188 int nErrorCount = 0;
189
190 {
191 using namespace eastl::rel_ops; // Defines default versions of operators !=, <, >, <=, >= based on == and <.
192
193 BasicObject bo1(1), bo2(2);
194
195 EATEST_VERIFY(!(bo1 == bo2));
196 EATEST_VERIFY((bo1 != bo2));
197 EATEST_VERIFY((bo1 < bo2));
198 EATEST_VERIFY(!(bo1 > bo2));
199 EATEST_VERIFY((bo1 <= bo2));
200 EATEST_VERIFY(!(bo1 >= bo2));
201 }
202
203 return nErrorCount;
204 }
205
206 // ThrowSwappable
207 struct ThrowSwappable
208 {
209 };
210
swap(ThrowSwappable & x,ThrowSwappable & y)211 void swap(ThrowSwappable& x, ThrowSwappable& y) EA_NOEXCEPT_IF(false)
212 {
213 ThrowSwappable temp(x);
214 x = y;
215 y = temp;
216
217 #if EASTL_EXCEPTIONS_ENABLED
218 throw int();
219 #endif
220 }
221
222 #if EASTL_TYPE_TRAIT_is_nothrow_swappable_CONFORMANCE
223 // NoThrowSwappable
224 struct NoThrowSwappable
225 {
226 };
227
swap(NoThrowSwappable & x,NoThrowSwappable & y)228 void swap(NoThrowSwappable& x, NoThrowSwappable& y) EA_NOEXCEPT_IF(true)
229 {
230 NoThrowSwappable temp(x);
231 x = y;
232 y = temp;
233 }
234 #endif
235
236 struct Swappable1 {};
237 struct Swappable2 {};
238 struct Swappable3 {};
swap(Swappable1 &,Swappable2 &)239 void swap(Swappable1&, Swappable2&) {}
swap(Swappable2 &,Swappable1 &)240 void swap(Swappable2&, Swappable1&) {}
swap(Swappable1 &,Swappable3 &)241 void swap(Swappable1&, Swappable3&) {} // intentionally missing 'swap(Swappable3, Swappable1)'
242
243
TestUtilitySwap()244 static int TestUtilitySwap()
245 {
246 int nErrorCount = 0;
247
248 // is_swappable
249 // is_nothrow_swappable
250 #if EASTL_TYPE_TRAIT_is_swappable_CONFORMANCE
251 static_assert((eastl::is_swappable<int>::value == true), "is_swappable failure");
252 static_assert((eastl::is_swappable<eastl::vector<int> >::value == true), "is_swappable failure");
253 static_assert((eastl::is_swappable<ThrowSwappable>::value == true), "is_swappable failure");
254 #if EASTL_VARIABLE_TEMPLATES_ENABLED
255 static_assert((eastl::is_swappable_v<int> == true), "is_swappable failure");
256 static_assert((eastl::is_swappable_v<eastl::vector<int> > == true), "is_swappable failure");
257 static_assert((eastl::is_swappable_v<ThrowSwappable> == true), "is_swappable failure");
258 #endif
259 // Need to come up with a class that's not swappable. How do we do that, given the universal swap template?
260 // static_assert((eastl::is_swappable<?>::value == false), "is_swappable failure");
261 #endif
262
263 #if EASTL_TYPE_TRAIT_is_nothrow_swappable_CONFORMANCE
264 static_assert((eastl::is_nothrow_swappable<int>::value == true), "is_nothrow_swappable failure"); // There currently isn't any specialization for swap of scalar types that's nothrow.
265 static_assert((eastl::is_nothrow_swappable<eastl::vector<int> >::value == false), "is_nothrow_swappable failure");
266 static_assert((eastl::is_nothrow_swappable<ThrowSwappable>::value == false), "is_nothrow_swappable failure");
267 static_assert((eastl::is_nothrow_swappable<NoThrowSwappable>::value == true), "is_nothrow_swappable failure");
268 #if EASTL_VARIABLE_TEMPLATES_ENABLED
269 static_assert((eastl::is_nothrow_swappable_v<int> == true), "is_nothrow_swappable failure"); // There currently isn't any specialization for swap of scalar types that's nothrow.
270 static_assert((eastl::is_nothrow_swappable_v<eastl::vector<int>> == false), "is_nothrow_swappable failure");
271 static_assert((eastl::is_nothrow_swappable_v<ThrowSwappable> == false), "is_nothrow_swappable failure");
272 static_assert((eastl::is_nothrow_swappable_v<NoThrowSwappable> == true), "is_nothrow_swappable failure");
273 #endif
274 #endif
275
276 #if EASTL_VARIADIC_TEMPLATES_ENABLED
277 // is_swappable_with
278 // is_nothrow_swappable_with
279 static_assert(eastl::is_swappable_with<int&, int&>::value, "is_swappable_with failure");
280 static_assert(!eastl::is_swappable_with<int, int>::value, "is_swappable_with failure");
281 static_assert(!eastl::is_swappable_with<int&, int>::value, "is_swappable_with failure");
282 static_assert(!eastl::is_swappable_with<int, int&>::value, "is_swappable_with failure");
283 static_assert(!eastl::is_swappable_with<int, short>::value, "is_swappable_with failure");
284 static_assert(!eastl::is_swappable_with<int, long>::value, "is_swappable_with failure");
285 static_assert(!eastl::is_swappable_with<int, eastl::vector<int>>::value, "is_swappable_with failure");
286 static_assert(!eastl::is_swappable_with<void, void>::value, "is_swappable_with failure");
287 static_assert(!eastl::is_swappable_with<int, void>::value, "is_swappable_with failure");
288 static_assert(!eastl::is_swappable_with<void, int>::value, "is_swappable_with failure");
289 static_assert(!eastl::is_swappable_with<ThrowSwappable, ThrowSwappable>::value, "is_swappable_with failure");
290 static_assert(eastl::is_swappable_with<ThrowSwappable&, ThrowSwappable&>::value, "is_swappable_with failure");
291 static_assert(eastl::is_swappable_with<Swappable1&, Swappable1&>::value, "is_swappable_with failure");
292 static_assert(eastl::is_swappable_with<Swappable1&, Swappable2&>::value, "is_swappable_with failure");
293 static_assert(eastl::is_swappable_with<Swappable2&, Swappable1&>::value, "is_swappable_with failure");
294
295 #if EASTL_VARIABLE_TEMPLATES_ENABLED
296 static_assert(eastl::is_swappable_with_v<int&, int&>, "is_swappable_with_v failure");
297 static_assert(!eastl::is_swappable_with_v<int, int>, "is_swappable_with_v failure");
298 static_assert(!eastl::is_swappable_with_v<int&, int>, "is_swappable_with_v failure");
299 static_assert(!eastl::is_swappable_with_v<int, int&>, "is_swappable_with_v failure");
300 static_assert(!eastl::is_swappable_with_v<int, short>, "is_swappable_with_v failure");
301 static_assert(!eastl::is_swappable_with_v<int, long>, "is_swappable_with_v failure");
302 static_assert(!eastl::is_swappable_with_v<int, eastl::vector<int>>, "is_swappable_with_v failure");
303 static_assert(!eastl::is_swappable_with_v<void, void>, "is_swappable_with_v failure");
304 static_assert(!eastl::is_swappable_with_v<int, void>, "is_swappable_with_v failure");
305 static_assert(!eastl::is_swappable_with_v<void, int>, "is_swappable_with_v failure");
306 static_assert(!eastl::is_swappable_with_v<ThrowSwappable, ThrowSwappable>, "is_swappable_with_v failure");
307 static_assert(eastl::is_swappable_with_v<ThrowSwappable&, ThrowSwappable&>, "is_swappable_with_v failure");
308 static_assert(eastl::is_swappable_with_v<Swappable1&, Swappable1&>, "is_swappable_with_v failure");
309 static_assert(eastl::is_swappable_with_v<Swappable1&, Swappable2&>, "is_swappable_with_v failure");
310 static_assert(eastl::is_swappable_with_v<Swappable2&, Swappable1&>, "is_swappable_with_v failure");
311 #endif // EASTL_VARIABLE_TEMPLATES_ENABLED
312
313 #if EASTL_TYPE_TRAIT_is_nothrow_swappable_with_CONFORMANCE
314 static_assert(eastl::is_nothrow_swappable_with<int&, int&>::value, "is_nothrow_swappable_with failure");
315 static_assert(!eastl::is_nothrow_swappable_with<int, int>::value, "is_nothrow_swappable_with failure");
316 static_assert(!eastl::is_nothrow_swappable_with<int&, int>::value, "is_nothrow_swappable_with failure");
317 static_assert(!eastl::is_nothrow_swappable_with<int, int&>::value, "is_nothrow_swappable_with failure");
318 static_assert(!eastl::is_nothrow_swappable_with<int, short>::value, "is_nothrow_swappable_with failure");
319 static_assert(!eastl::is_nothrow_swappable_with<int, long>::value, "is_nothrow_swappable_with failure");
320 static_assert(!eastl::is_nothrow_swappable_with<int, eastl::vector<int>>::value, "is_nothrow_swappable_with failure");
321 static_assert(!eastl::is_nothrow_swappable_with<void, void>::value, "is_nothrow_swappable_with failure");
322 static_assert(!eastl::is_nothrow_swappable_with<int, void>::value, "is_nothrow_swappable_with failure");
323 static_assert(!eastl::is_nothrow_swappable_with<void, int>::value, "is_nothrow_swappable_with failure");
324 static_assert(!eastl::is_nothrow_swappable_with<ThrowSwappable, ThrowSwappable>::value, "is_nothrow_swappable_with failure");
325 static_assert(!eastl::is_nothrow_swappable_with<ThrowSwappable&, ThrowSwappable&>::value, "is_nothrow_swappable_with failure");
326 static_assert(!eastl::is_nothrow_swappable_with<NoThrowSwappable, NoThrowSwappable>::value, "is_nothrow_swappable_with failure");
327 static_assert(eastl::is_nothrow_swappable_with<NoThrowSwappable&, NoThrowSwappable&>::value, "is_nothrow_swappable_with failure");
328
329 #if EASTL_VARIABLE_TEMPLATES_ENABLED
330 static_assert(eastl::is_nothrow_swappable_with_v<int&, int&>, "is_nothrow_swappable_with_v failure");
331 static_assert(!eastl::is_nothrow_swappable_with_v<int, int>, "is_nothrow_swappable_with_v failure");
332 static_assert(!eastl::is_nothrow_swappable_with_v<int&, int>, "is_nothrow_swappable_with_v failure");
333 static_assert(!eastl::is_nothrow_swappable_with_v<int, int&>, "is_nothrow_swappable_with_v failure");
334 static_assert(!eastl::is_nothrow_swappable_with_v<int, short>, "is_nothrow_swappable_with_v failure");
335 static_assert(!eastl::is_nothrow_swappable_with_v<int, long>, "is_nothrow_swappable_with_v failure");
336 static_assert(!eastl::is_nothrow_swappable_with_v<int, eastl::vector<int>>, "is_nothrow_swappable_with_v failure");
337 static_assert(!eastl::is_nothrow_swappable_with_v<void, void>, "is_nothrow_swappable_with_v failure");
338 static_assert(!eastl::is_nothrow_swappable_with_v<int, void>, "is_nothrow_swappable_with_v failure");
339 static_assert(!eastl::is_nothrow_swappable_with_v<void, int>, "is_nothrow_swappable_with_v failure");
340 static_assert(!eastl::is_nothrow_swappable_with_v<ThrowSwappable, ThrowSwappable>, "is_nothrow_swappable_with_v failure");
341 static_assert(!eastl::is_nothrow_swappable_with_v<ThrowSwappable&, ThrowSwappable&>, "is_nothrow_swappable_with_v failure");
342 static_assert(!eastl::is_nothrow_swappable_with_v<NoThrowSwappable, NoThrowSwappable>, "is_nothrow_swappable_with_v failure");
343 static_assert(eastl::is_nothrow_swappable_with_v<NoThrowSwappable&, NoThrowSwappable&>, "is_nothrow_swappable_with_v failure");
344 #endif // EASTL_VARIABLE_TEMPLATES_ENABLED
345 #endif
346 #endif // EASTL_VARIADIC_TEMPLATES_ENABLED
347
348 return nErrorCount;
349 }
350
351 #if !defined(EA_COMPILER_NO_NOEXCEPT)
352
353 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
354 // Warning C4626 warns against an implicitly deleted move assignment operator.
355 // This warning was disabled by default in VS2013. It was enabled by default in
356 // VS2015. Since the the tests below are explicitly testing move construction
357 // of the various classes explicitly deleting the move assignment to remove the
358 // warning is safe.
359 //
360 // https://msdn.microsoft.com/en-us/library/23k5d385.aspx
361
362 struct noexcept_move_copy
363 {
364 bool mStatus;
365
noexcept_move_copynoexcept_move_copy366 noexcept_move_copy() : mStatus(true) {}
367
368 noexcept_move_copy(const noexcept_move_copy&) = default;
369
noexcept_move_copynoexcept_move_copy370 noexcept_move_copy(noexcept_move_copy&& r) noexcept { r.mStatus = false; }
371
372 noexcept_move_copy& operator=(const noexcept_move_copy&) = delete; // required as VS2015 enabled C4626 by default.
373 };
374
375 struct noexcept_move_no_copy
376 {
377 bool mStatus;
378
noexcept_move_no_copynoexcept_move_no_copy379 noexcept_move_no_copy() : mStatus(true) {}
380
381 noexcept_move_no_copy(const noexcept_move_no_copy&) = delete;
382
noexcept_move_no_copynoexcept_move_no_copy383 noexcept_move_no_copy(noexcept_move_no_copy&& r) noexcept { r.mStatus = false; };
384
385 noexcept_move_no_copy& operator=(const noexcept_move_no_copy&) = delete; // required as VS2015 enabled C4626 by default.
386 };
387
388 struct except_move_copy
389 {
390 bool mStatus;
391
except_move_copyexcept_move_copy392 except_move_copy() : mStatus(true) {}
393
394 except_move_copy(const except_move_copy&) = default;
395
except_move_copyexcept_move_copy396 except_move_copy(except_move_copy&& r) noexcept(false) { r.mStatus = false; };
397
398 except_move_copy& operator=(const except_move_copy&) = delete; // required as VS2015 enabled C4626 by default.
399 };
400
401 struct except_move_no_copy
402 {
403 bool mStatus;
404
except_move_no_copyexcept_move_no_copy405 except_move_no_copy() : mStatus(true) {}
406
407 except_move_no_copy(const except_move_no_copy&) = delete;
408
except_move_no_copyexcept_move_no_copy409 except_move_no_copy(except_move_no_copy&& r) noexcept(false) { r.mStatus = false; };
410
411 except_move_no_copy& operator=(const except_move_no_copy&) = delete; // required as VS2015 enabled C4626 by default.
412 };
413 #endif
414
TestUtilityMove()415 static int TestUtilityMove()
416 {
417 int nErrorCount = 0;
418
419 // move_if_noexcept
420 #if !defined(EA_COMPILER_NO_NOEXCEPT)
421 noexcept_move_copy nemcA;
422 noexcept_move_copy nemcB =
423 eastl::move_if_noexcept(nemcA); // nemcB should be constructed via noexcept_move_copy(noexcept_move_copy&&)
424 EATEST_VERIFY(nemcA.mStatus == false);
425 EA_UNUSED(nemcB);
426
427 noexcept_move_no_copy nemncA;
428 noexcept_move_no_copy nemncB = eastl::move_if_noexcept(
429 nemncA); // nemncB should be constructed via noexcept_move_no_copy(noexcept_move_no_copy&&)
430 EATEST_VERIFY(nemncA.mStatus == false);
431 EA_UNUSED(nemncB);
432
433 except_move_copy emcA;
434 except_move_copy emcB = eastl::move_if_noexcept(
435 emcA); // emcB should be constructed via except_move_copy(const except_move_copy&) if exceptions are enabled.
436 #if EASTL_EXCEPTIONS_ENABLED
437 EATEST_VERIFY(emcA.mStatus == true);
438 #else
439 EATEST_VERIFY(emcA.mStatus == false);
440 #endif
441 EA_UNUSED(emcB);
442
443 except_move_no_copy emncA;
444 except_move_no_copy emncB =
445 eastl::move_if_noexcept(emncA); // emncB should be constructed via except_move_no_copy(except_move_no_copy&&)
446 EATEST_VERIFY(emncA.mStatus == false);
447 EA_UNUSED(emncB);
448 #endif
449
450 return nErrorCount;
451 }
452
TestUtilityIntegerSequence()453 static int TestUtilityIntegerSequence()
454 {
455 using namespace eastl;
456 int nErrorCount = 0;
457 #if EASTL_VARIADIC_TEMPLATES_ENABLED
458 // Android clang chokes with an internal compiler error on make_integer_sequence
459 #if !defined(EA_PLATFORM_ANDROID)
460 EATEST_VERIFY((integer_sequence<int, 0, 1, 2, 3, 4>::size() == 5));
461 EATEST_VERIFY((make_integer_sequence<int, 5>::size() == 5));
462 #endif
463 EATEST_VERIFY((index_sequence<0, 1, 2, 3, 4>::size() == 5));
464 EATEST_VERIFY((make_index_sequence<5>::size() == 5));
465 #endif // EASTL_VARIADIC_TEMPLATES_ENABLED
466
467 return nErrorCount;
468 }
469
TestUtilityExchange()470 static int TestUtilityExchange()
471 {
472 int nErrorCount = 0;
473
474 {
475 int a = 0;
476 auto r = eastl::exchange(a, 1);
477
478 EATEST_VERIFY(r == 0);
479 EATEST_VERIFY(a == 1);
480 }
481
482 {
483 int a = 0;
484 auto r = eastl::exchange(a, 1.78);
485
486 EATEST_VERIFY(r == 0);
487 EATEST_VERIFY(a == 1);
488 }
489
490 {
491 int a = 0;
492 auto r = eastl::exchange(a, 1.78f);
493
494 EATEST_VERIFY(r == 0);
495 EATEST_VERIFY(a == 1);
496 }
497
498 {
499 int a = 0, b = 1;
500 auto r = eastl::exchange(a, b);
501
502 EATEST_VERIFY(r == 0);
503 EATEST_VERIFY(a == 1);
504 EATEST_VERIFY(b == 1);
505 }
506
507 {
508 bool b = true;
509
510 auto r = eastl::exchange(b, true);
511 EATEST_VERIFY(r);
512
513 r = eastl::exchange(b, false);
514 EATEST_VERIFY(r);
515 EATEST_VERIFY(!b);
516
517 r = eastl::exchange(b, true);
518 EATEST_VERIFY(!r);
519 EATEST_VERIFY(b);
520 }
521
522 {
523 TestObject::Reset();
524
525 TestObject a(42);
526 auto r = eastl::exchange(a, TestObject(24));
527
528 EATEST_VERIFY(r.mX == 42);
529 EATEST_VERIFY(a.mX == 24);
530 }
531
532 {
533 const char* const pElectronicArts = "Electronic Arts";
534 const char* const pEAVancouver = "EA Vancouver";
535
536 eastl::string a(pElectronicArts);
537 auto r = eastl::exchange(a, pEAVancouver);
538
539 EATEST_VERIFY(r == pElectronicArts);
540 EATEST_VERIFY(a == pEAVancouver);
541
542 r = eastl::exchange(a, "EA Standard Template Library");
543 EATEST_VERIFY(a == "EA Standard Template Library");
544 }
545
546 // Construct pair using single move constructor
547 {
548 struct TestPairSingleMoveConstructor
549 {
550 void test(int&& val)
551 {
552 eastl::pair<int,int> p(eastl::pair_first_construct, eastl::move(val));
553 }
554 };
555
556 int i1 = 1;
557 TestPairSingleMoveConstructor test;
558 test.test(eastl::move(i1));
559 }
560
561 return nErrorCount;
562 }
563
564 ///////////////////////////////////////////////////////////////////////////////
565 // TestUtility
566 //
TestUtility()567 int TestUtility()
568 {
569 int nErrorCount = 0;
570
571 nErrorCount += TestUtilityPair();
572 nErrorCount += TestUtilityRelops();
573 nErrorCount += TestUtilitySwap();
574 nErrorCount += TestUtilityMove();
575 nErrorCount += TestUtilityIntegerSequence();
576 nErrorCount += TestUtilityExchange();
577
578 return nErrorCount;
579 }
580