Nugget
EASTLTest.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
5 
6 #ifndef EASTLTEST_H
7 #define EASTLTEST_H
8 
9 
10 #include <EABase/eabase.h>
11 #include <EATest/EATest.h>
12 
13 EA_DISABLE_ALL_VC_WARNINGS()
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <stdarg.h>
17 #include <vector> // For the STD_STL_TYPE defines below.
18 #if EASTL_EXCEPTIONS_ENABLED
19  #include <stdexcept>
20  #include <new>
21 #endif
22 EA_RESTORE_ALL_VC_WARNINGS();
23 
24 
25 int TestAlgorithm();
26 int TestAllocator();
27 int TestAny();
28 int TestArray();
29 int TestBitVector();
30 int TestBitset();
31 int TestCharTraits();
32 int TestChrono();
33 int TestCppCXTypeTraits();
34 int TestDeque();
35 int TestExtra();
36 int TestFinally();
37 int TestFixedFunction();
38 int TestFixedHash();
39 int TestFixedList();
40 int TestFixedMap();
41 int TestFixedSList();
42 int TestFixedSet();
43 int TestFixedString();
44 int TestFixedTupleVector();
45 int TestFixedVector();
46 int TestFunctional();
47 int TestHash();
48 int TestHeap();
49 int TestIntrusiveHash();
50 int TestIntrusiveList();
51 int TestIntrusiveSDList();
52 int TestIntrusiveSList();
53 int TestIterator();
54 int TestList();
55 int TestListMap();
56 int TestLruCache();
57 int TestMap();
58 int TestMemory();
59 int TestMeta();
60 int TestNumericLimits();
61 int TestOptional();
62 int TestRandom();
63 int TestRatio();
64 int TestRingBuffer();
65 int TestSList();
66 int TestSegmentedVector();
67 int TestSet();
68 int TestSmartPtr();
69 int TestSort();
70 int TestSpan();
71 int TestString();
72 int TestStringHashMap();
73 int TestStringMap();
74 int TestStringView();
75 int TestTuple();
76 int TestTupleVector();
77 int TestTypeTraits();
78 int TestUtility();
79 int TestVariant();
80 int TestVector();
81 int TestVectorMap();
82 int TestVectorSet();
83 int TestAtomicBasic();
84 int TestAtomicAsm();
85 int TestBitcast();
86 
87 
88 // Now enable warnings as desired.
89 #ifdef _MSC_VER
90  #pragma warning(disable: 4324) // 'struct_name' : structure was padded due to __declspec(align())
91  //#pragma warning(disable: 4512) // 'class' : assignment operator could not be generated
92  //#pragma warning(disable: 4100) // 'identifier' : unreferenced formal parameter
93  //#pragma warning(disable: 4706) // assignment within conditional expression
94 
95  #pragma warning(default: 4056) // Floating-point constant arithmetic generates a result that exceeds the maximum allowable value
96  #pragma warning(default: 4061) // The enumerate has no associated handler in a switch statement
97  #pragma warning(default: 4062) // The enumerate has no associated handler in a switch statement, and there is no default label
98  #pragma warning(default: 4191) // Calling this function through the result pointer may cause your program to crash
99  #pragma warning(default: 4217) // Member template functions cannot be used for copy-assignment or copy-construction
100  //#pragma warning(default: 4242) // 'variable' : conversion from 'type' to 'type', possible loss of data
101  #pragma warning(default: 4254) // 'operator' : conversion from 'type1' to 'type2', possible loss of data
102  #pragma warning(default: 4255) // 'function' : no function prototype given: converting '()' to '(void)'
103  #pragma warning(default: 4263) // 'function' : member function does not override any base class virtual member function
104  #pragma warning(default: 4264) // 'virtual_function' : no override available for virtual member function from base 'class'; function is hidden
105  #pragma warning(default: 4287) // 'operator' : unsigned/negative constant mismatch
106  #pragma warning(default: 4289) // Nonstandard extension used : 'var' : loop control variable declared in the for-loop is used outside the for-loop scope
107  #pragma warning(default: 4296) // 'operator' : expression is always false
108  #pragma warning(default: 4302) // 'conversion' : truncation from 'type 1' to 'type 2'
109  #pragma warning(default: 4339) // 'type' : use of undefined type detected in CLR meta-data - use of this type may lead to a runtime exception
110  #pragma warning(default: 4347) // Behavior change: 'function template' is called instead of 'function'
111  //#pragma warning(default: 4514) // unreferenced inline/local function has been removed
112  #pragma warning(default: 4529) // 'member_name' : forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name
113  #pragma warning(default: 4545) // Expression before comma evaluates to a function which is missing an argument list
114  #pragma warning(default: 4546) // Function call before comma missing argument list
115  #pragma warning(default: 4547) // 'operator' : operator before comma has no effect; expected operator with side-effect
116  //#pragma warning(default: 4548) // expression before comma has no effect; expected expression with side-effect
117  #pragma warning(default: 4549) // 'operator' : operator before comma has no effect; did you intend 'operator'?
118  #pragma warning(default: 4536) // 'type name' : type-name exceeds meta-data limit of 'limit' characters
119  #pragma warning(default: 4555) // Expression has no effect; expected expression with side-effect
120  #pragma warning(default: 4557) // '__assume' contains effect 'effect'
121  //#pragma warning(default: 4619) // #pragma warning : there is no warning number 'number'
122  #pragma warning(default: 4623) // 'derived class' : default constructor could not be generated because a base class default constructor is inaccessible
123  //#pragma warning(default: 4625) // 'derived class' : copy constructor could not be generated because a base class copy constructor is inaccessible
124  //#pragma warning(default: 4626) // 'derived class' : assignment operator could not be generated because a base class assignment operator is inaccessible
125  #pragma warning(default: 4628) // Digraphs not supported with -Ze. Character sequence 'digraph' not interpreted as alternate token for 'char'
126  #pragma warning(default: 4640) // 'instance' : construction of local static object is not thread-safe
127  #pragma warning(default: 4668) // 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
128  #pragma warning(default: 4682) // 'parameter' : no directional parameter attribute specified, defaulting to [in]
129  #pragma warning(default: 4686) // 'user-defined type' : possible change in behavior, change in UDT return calling convention
130  //#pragma warning(default: 4710) // 'function' : function not inlined
131  //#pragma warning(default: 4786) // 'identifier' : identifier was truncated to 'number' characters in the debug information
132  #pragma warning(default: 4793) // Native code generated for function 'function': 'reason'
133  //#pragma warning(default: 4820) // 'bytes' bytes padding added after member 'member'
134  #pragma warning(default: 4905) // Wide string literal cast to 'LPSTR'
135  #pragma warning(default: 4906) // String literal cast to 'LPWSTR'
136  #pragma warning(default: 4917) // 'declarator' : a GUID cannot only be associated with a class, interface or namespace
137  #pragma warning(default: 4928) // Illegal copy-initialization; more than one user-defined conversion has been implicitly applied
138  #pragma warning(default: 4931) // We are assuming the type library was built for number-bit pointers
139  #pragma warning(default: 4946) // reinterpret_cast used between related classes: 'class1' and 'class2'
140 
141 #endif
142 
143 
145 // EASTL includes
146 //
147 // Intentionally keep these includes below the warning settings specified above.
148 //
149 #include <EASTL/iterator.h>
150 #include <EASTL/algorithm.h>
151 
152 
153 
154 
162 enum EASTL_TestLevel
163 {
164  kEASTL_TestLevelLow = 1,
165  kEASTL_TestLevelHigh = 10
166 };
167 
168 extern int gEASTL_TestLevel;
169 
170 
171 
180 int EASTLTest_CheckMemory_Imp(const char* pFile, int nLine);
181 #define EASTLTest_CheckMemory() EASTLTest_CheckMemory_Imp(__FILE__, __LINE__)
182 
183 
184 
185 // EASTLTEST_STD_STL_VER
186 //
187 #if defined(_STLPORT_VERSION)
188  #define EASTLTEST_STD_STL_VER_STLPORT
189 #elif defined(_RWSTD_VER_STR) || defined(_RWSTD_NAMESPACE_END)
190  #define EASTLTEST_STD_STL_VER_APACHE
191 #elif defined(_CPPLIB_VER)
192  #define EASTLTEST_STD_STL_VER_DINKUMWARE
193 #elif defined(__GNUC__) && defined(_CXXCONFIG)
194  #define EASTLTEST_STD_STL_VER_GCC
195 #else
196  #define EASTLTEST_STD_STL_VER_UNKNOWN
197 #endif
198 
199 
200 
203 enum StdSTLType
204 {
205  kSTLUnknown, // Unknown type
206  kSTLPort, // STLPort. Descendent of the old HP / SGI STL.
207  kSTLApache, // Apache stdcxx (previously RogueWave), which is a descendent of the old HP / SGI STL.
208  kSTLClang, // Clang native. a.k.a. libc++
209  kSTLGCC, // GCC native. a.k.a. libstdc++
210  kSTLMS, // Microsoft. Tweaked version of Dinkumware.
211  kSTLDinkumware // Generic Dinkumware
212 };
213 
214 StdSTLType GetStdSTLType();
215 
216 
217 
218 
226 // "Apache" // Previously RogueWave
228 const char* GetStdSTLName();
229 
230 
233 extern int gEASTLTest_AllocationCount;
234 extern int gEASTLTest_TotalAllocationCount;
235 
236 
237 
238 // For backwards compatibility:
239 #define EASTLTest_Printf EA::UnitTest::Report
240 #define VERIFY EATEST_VERIFY
241 
242 
262 {
263 public:
264  EASTLTest_Rand(eastl_size_t nSeed) // The user must supply a seed; we don't provide default values.
265  : mnSeed(nSeed) { }
266 
267  eastl_size_t Rand()
268  {
269  // This is not designed to be a high quality random number generator.
270  if(mnSeed == 0)
271  mnSeed = UINT64_C(0xfefefefefefefefe); // Can't have a seed of zero.
272 
273  const uint64_t nResult64A = ((mnSeed * UINT64_C(6364136223846793005)) + UINT64_C(1442695040888963407));
274  const uint64_t nResult64B = ((nResult64A * UINT64_C(6364136223846793005)) + UINT64_C(1442695040888963407));
275 
276  mnSeed = (nResult64A >> 32) ^ nResult64B;
277 
278  return (eastl_size_t)mnSeed; // For eastl_size_t == uint32_t, this is a chop.
279  }
280 
281  eastl_size_t operator()() // Returns a pseudorandom value in range of [0, 0xffffffffffffffff)] (i.e. generate any eastl_size_t)
282  { return Rand(); }
283 
284  eastl_size_t operator()(eastl_size_t n) // Returns a pseudorandom value in range of [0, n)
285  { return RandLimit(n); }
286 
287  eastl_size_t RandLimit(eastl_size_t nLimit) // Returns a pseudorandom value in range of [0, nLimit)
288  {
289  // Can't do the following correct solution because we don't have a portable int128_t to work with.
290  // We could implement a 128 bit multiply manually. See EAStdC/int128_t.cpp.
291  // return (eastl_size_t)((Rand() * (uint128_t)nLimit) >> 64);
292 
293  return (Rand() % nLimit); // This results in an imperfect distribution, especially for the case of nLimit being high relative to eastl_size_t.
294  }
295 
296  eastl_ssize_t RandRange(eastl_ssize_t nBegin, eastl_ssize_t nEnd) // Returns a pseudorandom value in range of [nBegin, nEnd)
297  { return nBegin + (eastl_ssize_t)RandLimit((eastl_size_t)(nEnd - nBegin)); }
298 
299 protected:
300  uint64_t mnSeed;
301 };
302 
303 
311 template <typename Integer>
312 struct RandGenT
313 {
314  RandGenT(eastl_size_t nSeed)
315  : mRand(nSeed) { }
316 
317  Integer operator()()
318  { return (Integer)mRand.Rand(); }
319 
320  Integer operator()(eastl_size_t n)
321  { return (Integer)mRand.RandLimit(n); }
322 
323  EASTLTest_Rand mRand;
324 };
325 
326 
327 
336 const uint32_t kMagicValue = 0x01f1cbe8;
337 
338 
348 {
349  int mX; // Value for the TestObject.
350  bool mbThrowOnCopy; // Throw an exception of this object is copied, moved, or assigned to another.
351  int64_t mId; // Unique id for each object, equal to its creation number. This value is not coped from other TestObjects during any operations, including moves.
352  uint32_t mMagicValue; // Used to verify that an instance is valid and that it is not corrupted. It should always be kMagicValue.
353  static int64_t sTOCount; // Count of all current existing TestObjects.
354  static int64_t sTOCtorCount; // Count of times any ctor was called.
355  static int64_t sTODtorCount; // Count of times dtor was called.
356  static int64_t sTODefaultCtorCount; // Count of times the default ctor was called.
357  static int64_t sTOArgCtorCount; // Count of times the x0,x1,x2 ctor was called.
358  static int64_t sTOCopyCtorCount; // Count of times copy ctor was called.
359  static int64_t sTOMoveCtorCount; // Count of times move ctor was called.
360  static int64_t sTOCopyAssignCount; // Count of times copy assignment was called.
361  static int64_t sTOMoveAssignCount; // Count of times move assignment was called.
362  static int sMagicErrorCount; // Number of magic number mismatch errors.
363 
364  explicit TestObject(int x = 0, bool bThrowOnCopy = false)
365  : mX(x), mbThrowOnCopy(bThrowOnCopy), mMagicValue(kMagicValue)
366  {
367  ++sTOCount;
368  ++sTOCtorCount;
369  ++sTODefaultCtorCount;
370  mId = sTOCtorCount;
371  }
372 
373  // This constructor exists for the purpose of testing variadiac template arguments, such as with the emplace container functions.
374  TestObject(int x0, int x1, int x2, bool bThrowOnCopy = false)
375  : mX(x0 + x1 + x2), mbThrowOnCopy(bThrowOnCopy), mMagicValue(kMagicValue)
376  {
377  ++sTOCount;
378  ++sTOCtorCount;
379  ++sTOArgCtorCount;
380  mId = sTOCtorCount;
381  }
382 
383  TestObject(const TestObject& testObject)
384  : mX(testObject.mX), mbThrowOnCopy(testObject.mbThrowOnCopy), mMagicValue(testObject.mMagicValue)
385  {
386  ++sTOCount;
387  ++sTOCtorCount;
388  ++sTOCopyCtorCount;
389  mId = sTOCtorCount;
390  if(mbThrowOnCopy)
391  {
392  #if EASTL_EXCEPTIONS_ENABLED
393  throw "Disallowed TestObject copy";
394  #endif
395  }
396  }
397 
398  // Due to the nature of TestObject, there isn't much special for us to
399  // do in our move constructor. A move constructor swaps its contents with
400  // the other object, whhich is often a default-constructed object.
401  TestObject(TestObject&& testObject)
402  : mX(testObject.mX), mbThrowOnCopy(testObject.mbThrowOnCopy), mMagicValue(testObject.mMagicValue)
403  {
404  ++sTOCount;
405  ++sTOCtorCount;
406  ++sTOMoveCtorCount;
407  mId = sTOCtorCount; // testObject keeps its mId, and we assign ours anew.
408  testObject.mX = 0; // We are swapping our contents with the TestObject, so give it our "previous" value.
409  if(mbThrowOnCopy)
410  {
411  #if EASTL_EXCEPTIONS_ENABLED
412  throw "Disallowed TestObject copy";
413  #endif
414  }
415  }
416 
417  TestObject& operator=(const TestObject& testObject)
418  {
419  ++sTOCopyAssignCount;
420 
421  if(&testObject != this)
422  {
423  mX = testObject.mX;
424  // Leave mId alone.
425  mMagicValue = testObject.mMagicValue;
426  mbThrowOnCopy = testObject.mbThrowOnCopy;
427  if(mbThrowOnCopy)
428  {
429  #if EASTL_EXCEPTIONS_ENABLED
430  throw "Disallowed TestObject copy";
431  #endif
432  }
433  }
434  return *this;
435  }
436 
437  TestObject& operator=(TestObject&& testObject)
438  {
439  ++sTOMoveAssignCount;
440 
441  if(&testObject != this)
442  {
443  eastl::swap(mX, testObject.mX);
444  // Leave mId alone.
445  eastl::swap(mMagicValue, testObject.mMagicValue);
446  eastl::swap(mbThrowOnCopy, testObject.mbThrowOnCopy);
447 
448  if(mbThrowOnCopy)
449  {
450  #if EASTL_EXCEPTIONS_ENABLED
451  throw "Disallowed TestObject copy";
452  #endif
453  }
454  }
455  return *this;
456  }
457 
458  ~TestObject()
459  {
460  if(mMagicValue != kMagicValue)
461  ++sMagicErrorCount;
462  mMagicValue = 0;
463  --sTOCount;
464  ++sTODtorCount;
465  }
466 
467  static void Reset()
468  {
469  sTOCount = 0;
470  sTOCtorCount = 0;
471  sTODtorCount = 0;
472  sTODefaultCtorCount = 0;
473  sTOArgCtorCount = 0;
474  sTOCopyCtorCount = 0;
475  sTOMoveCtorCount = 0;
476  sTOCopyAssignCount = 0;
477  sTOMoveAssignCount = 0;
478  sMagicErrorCount = 0;
479  }
480 
481  static bool IsClear() // Returns true if there are no existing TestObjects and the sanity checks related to that test OK.
482  {
483  return (sTOCount == 0) && (sTODtorCount == sTOCtorCount) && (sMagicErrorCount == 0);
484  }
485 };
486 
487 // Operators
488 // We specifically define only == and <, in order to verify that
489 // our containers and algorithms are not mistakenly expecting other
490 // operators for the contained and manipulated classes.
491 inline bool operator==(const TestObject& t1, const TestObject& t2)
492  { return t1.mX == t2.mX; }
493 
494 inline bool operator<(const TestObject& t1, const TestObject& t2)
495  { return t1.mX < t2.mX; }
496 
497 
498 // TestObject hash
499 // Normally you don't want to put your hash functions in the eastl namespace, as that namespace is owned by EASTL.
500 // However, these are the EASTL unit tests and we can say that they are also owned by EASTL.
501 namespace eastl
502 {
503  template <>
504  struct hash<TestObject>
505  {
506  size_t operator()(const TestObject& a) const
507  { return static_cast<size_t>(a.mX); }
508  };
509 }
510 
511 
512 // use_mX
513 // Used for printing TestObject contents via the PrintSequence function,
514 // which is defined below. See the PrintSequence function for documentation.
515 // This function is an analog of the eastl::use_self and use_first functions.
516 // We declare this all in one line because the user should never need to
517 // debug usage of this function.
518 template <typename T> struct use_mX { int operator()(const T& t) const { return t.mX; } };
519 
520 
521 
523 // SizedPOD
524 //
525 // Exists for the purpose testing PODs that are larger than built-in types.
526 //
527 template <size_t kSize>
528 struct SizedPOD
529 {
530  char memory[kSize];
531 };
532 
533 
534 
541 {
542 public:
543  ConstType(int value) : mDummy(value) {};
544  int mDummy;
545 };
546 
547 
548 
549 
556 {
557  size_t operator()(const TestObject& t) const
558  {
559  return (size_t)t.mX;
560  }
561 };
562 
563 
564 
565 
566 
570 
571 #if defined(EA_PROCESSOR_ARM)
572  #define kEASTLTestAlign16 8 //ARM processors can only align to 8
573 #else
574  #define kEASTLTestAlign16 16
575 #endif
576 
577 
578 EA_PREFIX_ALIGN(kEASTLTestAlign16)
579 struct Align16
580 {
581  explicit Align16(int x = 0) : mX(x) {}
582  int mX;
583 } EA_POSTFIX_ALIGN(kEASTLTestAlign16);
584 
585 inline bool operator==(const Align16& a, const Align16& b)
586  { return (a.mX == b.mX); }
587 
588 inline bool operator<(const Align16& a, const Align16& b)
589  { return (a.mX < b.mX); }
590 
591 
592 
596 #if defined(EA_PROCESSOR_ARM)
597  #define kEASTLTestAlign32 8 //ARM processors can only align to 8
598 #elif defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) < 400) // GCC 2.x, 3.x
599  #define kEASTLTestAlign32 16 // Some versions of GCC fail to support any alignment beyond 16.
600 #else
601  #define kEASTLTestAlign32 32
602 #endif
603 
604 EA_PREFIX_ALIGN(kEASTLTestAlign32)
605 struct Align32
606 {
607  explicit Align32(int x = 0) : mX(x) {}
608  int mX;
609 } EA_POSTFIX_ALIGN(kEASTLTestAlign32);
610 
611 inline bool operator==(const Align32& a, const Align32& b)
612  { return (a.mX == b.mX); }
613 
614 inline bool operator<(const Align32& a, const Align32& b)
615  { return (a.mX < b.mX); }
616 
617 
618 
624 #if defined(EA_PROCESSOR_ARM)
625  #define kEASTLTestAlign64 8
626 #elif defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) < 400) // GCC 2.x, 3.x
627  #define kEASTLTestAlign64 16 // Some versions of GCC fail to support any alignment beyond 16.
628 #else
629  #define kEASTLTestAlign64 64
630 #endif
631 
632 EA_PREFIX_ALIGN(kEASTLTestAlign64)
633 struct Align64
634 {
635  explicit Align64(int x = 0) : mX(x) {}
636  int mX;
637 } EA_POSTFIX_ALIGN(kEASTLTestAlign64);
638 
639 inline bool operator==(const Align64& a, const Align64& b)
640  { return (a.mX == b.mX); }
641 
642 inline bool operator<(const Align64& a, const Align64& b)
643  { return (a.mX < b.mX); }
644 
645 namespace eastl
646 {
647  template <>
648  struct hash < Align64 >
649  {
650  size_t operator()(const Align64& a) const
651  {
652  return static_cast<size_t>(a.mX);
653  }
654  };
655 }
656 
657 
658 
659 
660 
665 template <typename T>
667 {
668  const T& operator()(const T& x) const
669  { return x; }
670 };
671 
672 
673 
690 template <typename T>
692 {
693  int mX;
694 
695  GenerateIncrementalIntegers(int x = 0)
696  : mX(x) { }
697 
698  void reset(int x = 0)
699  { mX = x; }
700 
701  T operator()()
702  { return T(mX++); }
703 };
704 
705 
706 
716 template <typename T>
718 {
719  int mX;
720 
721  SetIncrementalIntegers(int x = 0)
722  : mX(x) { }
723 
724  void reset(int x = 0)
725  { mX = x; }
726 
727  void operator()(T& t)
728  { t = T(mX++); }
729 };
730 
731 
732 
742 template <typename T1, typename T2, typename ExtractValue1, typename ExtractValue2>
743 int CompareContainers(const T1& t1, const T2& t2, const char* ppName,
744  ExtractValue1 ev1 = test_use_self<T1>(), ExtractValue2 ev2 = test_use_self<T2>())
745 {
746  int nErrorCount = 0;
747 
748  // Compare emptiness.
749  VERIFY(t1.empty() == t2.empty());
750 
751  // Compare sizes.
752  const size_t nSize1 = t1.size();
753  const size_t nSize2 = t2.size();
754 
755  VERIFY(nSize1 == nSize2);
756  if(nSize1 != nSize2)
757  EASTLTest_Printf("%s: Container size difference: %u, %u\n", ppName, (unsigned)nSize1, (unsigned)nSize2);
758 
759  // Compare values.
760  if(nSize1 == nSize2)
761  {
762  // Test iteration
763  typename T1::const_iterator it1 = t1.begin();
764  typename T2::const_iterator it2 = t2.begin();
765 
766  for(unsigned j = 0; it1 != t1.end(); ++it1, ++it2, ++j)
767  {
768  const typename T1::value_type& v1 = *it1;
769  const typename T2::value_type& v2 = *it2;
770 
771  VERIFY(ev1(v1) == ev2(v2));
772  if(!(ev1(v1) == ev2(v2)))
773  {
774  EASTLTest_Printf("%s: Container iterator difference at index %d\n", ppName, j);
775  break;
776  }
777  }
778 
779  VERIFY(it1 == t1.end());
780  VERIFY(it2 == t2.end());
781  }
782 
783  return nErrorCount;
784 }
785 
786 
787 
788 
789 
802 template <typename InputIterator, typename StackValue>
803 bool VerifySequence(InputIterator first, InputIterator last, StackValue /*unused*/, const char* pName, ...)
804 {
805  typedef typename eastl::iterator_traits<InputIterator>::value_type value_type;
806 
807  int argIndex = 0;
808  int seqIndex = 0;
809  bool bReturnValue = true;
810  StackValue next;
811 
812  va_list args;
813  va_start(args, pName);
814 
815  for( ; first != last; ++first, ++argIndex, ++seqIndex)
816  {
817  next = va_arg(args, StackValue);
818 
819  if((next == StackValue(-1)) || !(value_type(next) == *first))
820  {
821  if(pName)
822  EASTLTest_Printf("[%s] Mismatch at index %d\n", pName, argIndex);
823  else
824  EASTLTest_Printf("Mismatch at index %d\n", argIndex);
825  bReturnValue = false;
826  }
827  }
828 
829  for(; first != last; ++first)
830  ++seqIndex;
831 
832  if(bReturnValue)
833  {
834  next = va_arg(args, StackValue);
835 
836  if(!(next == StackValue(-1)))
837  {
838  do {
839  ++argIndex;
840  next = va_arg(args, StackValue);
841  } while(!(next == StackValue(-1)));
842 
843  if(pName)
844  EASTLTest_Printf("[%s] Too many elements: expected %d, found %d\n", pName, argIndex, seqIndex);
845  else
846  EASTLTest_Printf("Too many elements: expected %d, found %d\n", argIndex, seqIndex);
847  bReturnValue = false;
848  }
849  }
850 
851  va_end(args);
852 
853  return bReturnValue;
854 }
855 
856 
857 
858 
872 template <typename InputIterator, typename ExtractInt>
873 void PrintSequence(InputIterator first, InputIterator last, ExtractInt extractInt, int nMaxCount, const char* pName, ...)
874 {
875  if(pName)
876  EASTLTest_Printf("[%s]", pName);
877 
878  for(int i = 0; (i < nMaxCount) && (first != last); ++i, ++first)
879  {
880  EASTLTest_Printf("%d ", (int)extractInt(*first));
881  }
882 
883  EASTLTest_Printf("\n");
884 }
885 
886 
887 
888 
918 template <typename Iterator, typename IteratorCategory>
920 {
921 protected:
922  Iterator mIterator;
923 
924 public:
926  typedef Iterator iterator_type;
927  typedef IteratorCategory iterator_category;
928  typedef typename eastl::iterator_traits<Iterator>::value_type value_type;
929  typedef typename eastl::iterator_traits<Iterator>::difference_type difference_type;
930  typedef typename eastl::iterator_traits<Iterator>::reference reference;
931  typedef typename eastl::iterator_traits<Iterator>::pointer pointer;
932 
934  : mIterator() { }
935 
936  explicit demoted_iterator(const Iterator& i)
937  : mIterator(i) { }
938 
939  demoted_iterator(const this_type& x)
940  : mIterator(x.mIterator) { }
941 
942  this_type& operator=(const Iterator& i)
943  { mIterator = i; return *this; }
944 
945  this_type& operator=(const this_type& x)
946  { mIterator = x.mIterator; return *this; }
947 
948  reference operator*() const
949  { return *mIterator; }
950 
951  pointer operator->() const
952  { return mIterator; }
953 
954  this_type& operator++()
955  { ++mIterator; return *this; }
956 
957  this_type operator++(int)
958  { return this_type(mIterator++); }
959 
960  this_type& operator--()
961  { --mIterator; return *this; }
962 
963  this_type operator--(int)
964  { return this_type(mIterator--); }
965 
966  reference operator[](const difference_type& n) const
967  { return mIterator[n]; }
968 
969  this_type& operator+=(const difference_type& n)
970  { mIterator += n; return *this; }
971 
972  this_type operator+(const difference_type& n) const
973  { return this_type(mIterator + n); }
974 
975  this_type& operator-=(const difference_type& n)
976  { mIterator -= n; return *this; }
977 
978  this_type operator-(const difference_type& n) const
979  { return this_type(mIterator - n); }
980 
981  const iterator_type& base() const
982  { return mIterator; }
983 
984 }; // class demoted_iterator
985 
986 template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
987 inline bool
989  { return a.base() == b.base(); }
990 
991 template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
992 inline bool
994  { return !(a == b); }
995 
996 template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
997 inline bool
999  { return a.base() < b.base(); }
1000 
1001 template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
1002 inline bool
1004  { return !(b < a); }
1005 
1006 template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
1007 inline bool
1009  { return b < a; }
1010 
1011 template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
1012 inline bool
1014  { return !(a < b); }
1015 
1016 template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
1019  { return demoted_iterator<Iterator1, IteratorCategory1>(a.base() - b.base()); }
1020 
1021 template<typename Iterator1, typename IteratorCategory1>
1023 operator+(typename demoted_iterator<Iterator1, IteratorCategory1>::difference_type n, const demoted_iterator<Iterator1, IteratorCategory1>& a)
1024  { return a + n; }
1025 
1026 
1027 // to_xxx_iterator
1028 //
1029 // Returns a demoted iterator
1030 //
1031 template <typename Iterator>
1033 to_input_iterator(const Iterator& i)
1035 
1036 template <typename Iterator>
1038 to_forward_iterator(const Iterator& i)
1040 
1041 template <typename Iterator>
1043 to_bidirectional_iterator(const Iterator& i)
1045 
1046 template <typename Iterator>
1048 to_random_access_iterator(const Iterator& i)
1050 
1051 
1052 
1053 
1054 
1055 
1057 // MallocAllocator
1058 //
1059 // Implements an EASTL allocator that uses malloc/free as opposed to
1060 // new/delete or PPMalloc Malloc/Free. This is useful for testing
1061 // allocator behaviour of code.
1062 //
1063 // Example usage:
1064 // vector<int, MallocAllocator> intVector;
1065 //
1067 {
1068 public:
1069  MallocAllocator(const char* = EASTL_NAME_VAL("MallocAllocator"))
1070  : mAllocCount(0), mFreeCount(0), mAllocVolume(0) {}
1071 
1073  : mAllocCount(x.mAllocCount), mFreeCount(x.mFreeCount), mAllocVolume(x.mAllocVolume) {}
1074 
1075  MallocAllocator(const MallocAllocator& x, const char*) : MallocAllocator(x) {}
1076 
1077  MallocAllocator& operator=(const MallocAllocator& x)
1078  {
1079  mAllocCount = x.mAllocCount;
1080  mFreeCount = x.mFreeCount;
1081  mAllocVolume = x.mAllocVolume;
1082  return *this;
1083  }
1084 
1085  void* allocate(size_t n, int = 0);
1086  void* allocate(size_t n, size_t, size_t, int = 0); // We don't support alignment, so you can't use this class where alignment is required.
1087  void deallocate(void* p, size_t n);
1088 
1089  const char* get_name() const { return "MallocAllocator"; }
1090  void set_name(const char*) {}
1091 
1092  static void reset_all()
1093  {
1094  mAllocCountAll = 0;
1095  mFreeCountAll = 0;
1096  mAllocVolumeAll = 0;
1097  mpLastAllocation = NULL;
1098  }
1099 
1100 public:
1101  int mAllocCount;
1102  int mFreeCount;
1103  size_t mAllocVolume;
1104 
1105  static int mAllocCountAll;
1106  static int mFreeCountAll;
1107  static size_t mAllocVolumeAll;
1108  static void* mpLastAllocation;
1109 };
1110 
1111 inline bool operator==(const MallocAllocator&, const MallocAllocator&) { return true; }
1112 inline bool operator!=(const MallocAllocator&, const MallocAllocator&) { return false; }
1113 
1114 
1116 // CustomAllocator
1117 //
1118 // Implements an allocator that works just like eastl::allocator but is defined
1119 // within this test as opposed to within EASTL.
1120 //
1121 // Example usage:
1122 // vector<int, CustomAllocator> intVector;
1123 //
1125 {
1126 public:
1127  CustomAllocator(const char* = NULL) {}
1128  CustomAllocator(const CustomAllocator&) {}
1129  CustomAllocator(const CustomAllocator&, const char*) {}
1130  CustomAllocator& operator=(const CustomAllocator&) { return *this; }
1131 
1132  void* allocate(size_t n, int flags = 0);
1133  void* allocate(size_t n, size_t, size_t, int flags = 0);
1134  void deallocate(void* p, size_t n);
1135 
1136  const char* get_name() const { return "CustomAllocator"; }
1137  void set_name(const char*) {}
1138 };
1139 
1140 inline bool operator==(const CustomAllocator&, const CustomAllocator&) { return true; }
1141 inline bool operator!=(const CustomAllocator&, const CustomAllocator&) { return false; }
1142 
1143 
1151 {
1152 public:
1153  EASTL_ALLOCATOR_EXPLICIT UnequalAllocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME))
1154  : mAllocator(pName) {}
1155 
1156  UnequalAllocator(const UnequalAllocator& x) : mAllocator(x.mAllocator) {}
1157  UnequalAllocator(const UnequalAllocator& x, const char* pName) : mAllocator(x.mAllocator) { set_name(pName); }
1158  UnequalAllocator& operator=(const UnequalAllocator& x)
1159  {
1160  mAllocator = x.mAllocator;
1161  return *this;
1162  }
1163 
1164  void* allocate(size_t n, int flags = 0) { return mAllocator.allocate(n, flags); }
1165  void* allocate(size_t n, size_t alignment, size_t offset, int flags = 0) { return mAllocator.allocate(n, alignment, offset, flags); }
1166  void deallocate(void* p, size_t n) { return mAllocator.deallocate(p, n); }
1167 
1168  const char* get_name() const { return mAllocator.get_name(); }
1169  void set_name(const char* pName) { mAllocator.set_name(pName); }
1170 
1171 protected:
1172  eastl::allocator mAllocator;
1173 };
1174 
1175 inline bool operator==(const UnequalAllocator&, const UnequalAllocator&) { return false; }
1176 inline bool operator!=(const UnequalAllocator&, const UnequalAllocator&) { return true; }
1177 
1178 
1185 {
1186 public:
1187  using base_type = eastl::allocator;
1188 
1189  EASTL_ALLOCATOR_EXPLICIT CountingAllocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME))
1190  : base_type(pName)
1191  {
1192  totalCtorCount++;
1193  defaultCtorCount++;
1194  }
1195 
1197  {
1198  totalCtorCount++;
1199  copyCtorCount++;
1200  }
1201 
1202  CountingAllocator(const CountingAllocator& x, const char* pName) : base_type(x)
1203  {
1204  totalCtorCount++;
1205  copyCtorCount++;
1206  set_name(pName);
1207  }
1208 
1209  CountingAllocator& operator=(const CountingAllocator& x)
1210  {
1211  base_type::operator=(x);
1212  assignOpCount++;
1213  return *this;
1214  }
1215 
1216  virtual void* allocate(size_t n, int flags = 0)
1217  {
1218  activeAllocCount++;
1219  totalAllocCount++;
1220  totalAllocatedMemory += n;
1221  activeAllocatedMemory += n;
1222  return base_type::allocate(n, flags);
1223  }
1224 
1225  virtual void* allocate(size_t n, size_t alignment, size_t offset, int flags = 0)
1226  {
1227  activeAllocCount++;
1228  totalAllocCount++;
1229  totalAllocatedMemory += n;
1230  activeAllocatedMemory += n;
1231  return base_type::allocate(n, alignment, offset, flags);
1232  }
1233 
1234  void deallocate(void* p, size_t n)
1235  {
1236  activeAllocCount--;
1237  totalDeallocCount--;
1238  activeAllocatedMemory -= n;
1239  return base_type::deallocate(p, n);
1240  }
1241 
1242  const char* get_name() const { return base_type::get_name(); }
1243  void set_name(const char* pName) { base_type::set_name(pName); }
1244 
1245  static auto getTotalAllocationCount() { return totalAllocCount; }
1246  static auto getTotalAllocationSize() { return totalAllocatedMemory; }
1247  static auto getActiveAllocationSize() { return activeAllocatedMemory; }
1248  static auto getActiveAllocationCount() { return activeAllocCount; }
1249  static auto neverUsed() { return totalAllocCount == 0; }
1250 
1251  static void resetCount()
1252  {
1253  activeAllocCount = 0;
1254  totalAllocCount = 0;
1255  totalDeallocCount = 0;
1256  totalCtorCount = 0;
1257  defaultCtorCount = 0;
1258  copyCtorCount = 0;
1259  assignOpCount = 0;
1260  totalAllocatedMemory = 0;
1261  activeAllocatedMemory = 0;
1262  }
1263 
1264  static uint64_t activeAllocCount;
1265  static uint64_t totalAllocCount;
1266  static uint64_t totalDeallocCount;
1267  static uint64_t totalCtorCount;
1268  static uint64_t defaultCtorCount;
1269  static uint64_t copyCtorCount;
1270  static uint64_t assignOpCount;
1271  static uint64_t totalAllocatedMemory; // the total amount of memory allocated
1272  static uint64_t activeAllocatedMemory; // currently allocated memory by allocator
1273 };
1274 
1275 inline bool operator==(const CountingAllocator& rhs, const CountingAllocator& lhs) { return operator==(CountingAllocator::base_type(rhs), CountingAllocator::base_type(lhs)); }
1276 inline bool operator!=(const CountingAllocator& rhs, const CountingAllocator& lhs) { return !(rhs == lhs); }
1277 
1278 
1279 
1280 
1282 // InstanceAllocator
1283 //
1284 // Implements an allocator which has a instance id that makes it different
1285 // from other InstanceAllocators of a different id. Allocations between
1286 // InstanceAllocators of different ids are incompatible. An allocation done
1287 // by an InstanceAllocator of id=0 cannot be freed by an InstanceAllocator
1288 // of id=1.
1289 //
1290 // Example usage:
1291 // InstanceAllocator ia0((uint8_t)0);
1292 // InstanceAllocator ia1((uint8_t)1);
1293 //
1294 // eastl::list<int, InstanceAllocator> list0(1, ia0);
1295 // eastl::list<int, InstanceAllocator> list1(1, ia1);
1296 //
1297 // list0 = list1; // list0 cannot free it's current contents with list1's allocator, and InstanceAllocator's purpose is to detect if it mistakenly does so.
1298 //
1300 {
1301 public:
1302  enum
1303  {
1304  kMultiplier = 16
1305  }; // Use 16 because it's the highest currently known platform alignment requirement.
1306 
1307  InstanceAllocator(const char* = NULL, uint8_t instanceId = 0) : mInstanceId(instanceId) {}
1308  InstanceAllocator(uint8_t instanceId) : mInstanceId(instanceId) {}
1309  InstanceAllocator(const InstanceAllocator& x) : mInstanceId(x.mInstanceId) {}
1310  InstanceAllocator(const InstanceAllocator& x, const char*) : mInstanceId(x.mInstanceId) {}
1311 
1312  InstanceAllocator& operator=(const InstanceAllocator& x)
1313  {
1314  mInstanceId = x.mInstanceId;
1315  return *this;
1316  }
1317 
1318  void* allocate(size_t n, int = 0)
1319  { // +1 so that we always have space to write mInstanceId.
1320  uint8_t* p8 =
1321  static_cast<uint8_t*>(malloc(n + (kMultiplier * (mInstanceId + 1)))); // We make allocations between
1322  // different instances incompatible by
1323  // tweaking their return values.
1324  eastl::fill(p8, p8 + kMultiplier, 0xff);
1325  EA_ANALYSIS_ASSUME(p8 != NULL);
1326  *p8 = mInstanceId;
1327  return p8 + (kMultiplier * (mInstanceId + 1));
1328  }
1329 
1330  void* allocate(size_t n, size_t, size_t, int = 0)
1331  { // +1 so that we always have space to write mInstanceId.
1332  uint8_t* p8 =
1333  static_cast<uint8_t*>(malloc(n + (kMultiplier * (mInstanceId + 1)))); // We make allocations between
1334  // different instances incompatible by
1335  // tweaking their return values.
1336  eastl::fill(p8, p8 + kMultiplier, 0xff);
1337  EA_ANALYSIS_ASSUME(p8 != NULL);
1338  *p8 = mInstanceId;
1339  return p8 + (kMultiplier * (mInstanceId + 1));
1340  }
1341 
1342  void deallocate(void* p, size_t /*n*/)
1343  {
1344  uint8_t* p8 = static_cast<uint8_t*>(p) - (kMultiplier * (mInstanceId + 1));
1345  EASTL_ASSERT(*p8 == mInstanceId); // mInstanceId must match the id used in allocate(), otherwise the behavior is
1346  // undefined (probably a heap assert).
1347  if (*p8 == mInstanceId) // It's possible that *p8 coincidentally matches mInstanceId if p8 is offset into memory
1348  // we don't control.
1349  free(p8);
1350  else
1351  ++mMismatchCount;
1352  }
1353 
1354  const char* get_name()
1355  {
1356  sprintf(mName, "InstanceAllocator %u", mInstanceId);
1357  return mName;
1358  }
1359 
1360  void set_name(const char*) {}
1361 
1362  static void reset_all() { mMismatchCount = 0; }
1363 
1364 public:
1365  uint8_t mInstanceId;
1366  char mName[32];
1367 
1368  static int mMismatchCount;
1369 };
1370 
1371 inline bool operator==(const InstanceAllocator& a, const InstanceAllocator& b) { return (a.mInstanceId == b.mInstanceId); }
1372 inline bool operator!=(const InstanceAllocator& a, const InstanceAllocator& b) { return (a.mInstanceId != b.mInstanceId); }
1373 
1374 
1376 // ThrowingAllocator
1377 //
1378 // Implements an EASTL allocator that uses malloc/free as opposed to
1379 // new/delete or PPMalloc Malloc/Free. This is useful for testing
1380 // allocator behaviour of code.
1381 //
1382 // Example usage:
1383 // vector<int, ThrowingAllocator< false<> > intVector;
1384 //
1385 template <bool initialShouldThrow = true>
1387 {
1388 public:
1389  ThrowingAllocator(const char* = EASTL_NAME_VAL("ThrowingAllocator")) : mbShouldThrow(initialShouldThrow) {}
1390  ThrowingAllocator(const ThrowingAllocator& x) : mbShouldThrow(x.mbShouldThrow) {}
1391  ThrowingAllocator(const ThrowingAllocator& x, const char*) : mbShouldThrow(x.mbShouldThrow) {}
1392 
1393  ThrowingAllocator& operator=(const ThrowingAllocator& x)
1394  {
1395  mbShouldThrow = x.mbShouldThrow;
1396  return *this;
1397  }
1398 
1399  void* allocate(size_t n, int = 0)
1400  {
1401 #if EASTL_EXCEPTIONS_ENABLED
1402  if (mbShouldThrow)
1403  throw std::bad_alloc();
1404 #endif
1405  return malloc(n);
1406  }
1407 
1408  void* allocate(size_t n, size_t, size_t, int = 0)
1409  {
1410 #if EASTL_EXCEPTIONS_ENABLED
1411  if (mbShouldThrow)
1412  throw std::bad_alloc();
1413 #endif
1414  return malloc(n); // We don't support alignment, so you can't use this class where alignment is required.
1415  }
1416 
1417  void deallocate(void* p, size_t) { free(p); }
1418 
1419  const char* get_name() const { return "ThrowingAllocator"; }
1420  void set_name(const char*) {}
1421 
1422  void set_should_throw(bool shouldThrow) { mbShouldThrow = shouldThrow; }
1423  bool get_should_throw() const { return mbShouldThrow; }
1424 
1425 protected:
1426  bool mbShouldThrow;
1427 };
1428 
1429 template <bool initialShouldThrow>
1431 {
1432  return true;
1433 }
1434 
1435 template <bool initialShouldThrow>
1437 {
1438  return false;
1439 }
1440 
1441 
1443 // Helper utility that does a case insensitive string comparsion with two sets of overloads
1444 //
1446 {
1447  bool operator()(const char* pCStr, const eastl::string& str) const { return str.comparei(pCStr) == 0; }
1448  bool operator()(const eastl::string& str, const char* pCStr) const { return str.comparei(pCStr) == 0; }
1449 };
1450 
1451 
1453 // StompDetectAllocator
1454 //
1455 // An allocator that has sentinal values surrounding its allocator in an
1456 // effort to detected if its internal memory has been stomped.
1457 //
1458 static uint64_t STOMP_MAGIC_V1 = 0x0101DEC1A551F1ED;
1459 static uint64_t STOMP_MAGIC_V2 = 0x12345C1A551F1ED5;
1460 
1462 {
1463  StompDetectAllocator() { Validate(); }
1464  ~StompDetectAllocator() { Validate(); }
1465 
1466  StompDetectAllocator(const char*) { Validate(); }
1467 
1468  void* allocate(size_t n, int = 0) { return mMallocAllocator.allocate(n); }
1469  void* allocate(size_t n, size_t, size_t, int = 0) { return mMallocAllocator.allocate(n); }
1470  void deallocate(void* p, size_t n) { mMallocAllocator.deallocate(p, n); }
1471 
1472  const char* get_name() const { return "FatAllocator"; }
1473  void set_name(const char*) {}
1474 
1475  void Validate() const
1476  {
1477  EASTL_ASSERT(mSentinal1 == STOMP_MAGIC_V1);
1478  EASTL_ASSERT(mSentinal2 == STOMP_MAGIC_V2);
1479  }
1480 
1481  uint64_t mSentinal1 = STOMP_MAGIC_V1;
1482  MallocAllocator mMallocAllocator;
1483  uint64_t mSentinal2 = STOMP_MAGIC_V2;
1484 };
1485 
1486 inline bool operator==(const StompDetectAllocator& a, const StompDetectAllocator& b)
1487 {
1488  a.Validate();
1489  b.Validate();
1490 
1491  return (a.mMallocAllocator == b.mMallocAllocator);
1492 }
1493 
1494 inline bool operator!=(const StompDetectAllocator& a, const StompDetectAllocator& b)
1495 {
1496  a.Validate();
1497  b.Validate();
1498 
1499  return (a.mMallocAllocator != b.mMallocAllocator);
1500 }
1501 
1502 
1503 // Commonly used free-standing functions to test callables
1504 inline int ReturnVal(int param) { return param; }
1505 inline int ReturnZero() { return 0; }
1506 inline int ReturnOne() { return 1; }
1507 
1508 
1509 // ValueInit
1510 template<class T>
1512 {
1513  ValueInitOf() : mV() {}
1514  ~ValueInitOf() = default;
1515 
1516  ValueInitOf(const ValueInitOf&) = default;
1517  ValueInitOf(ValueInitOf&&) = default;
1518 
1519  ValueInitOf& operator=(const ValueInitOf&) = default;
1520  ValueInitOf& operator=(ValueInitOf&&) = default;
1521 
1522  T get() { return mV; }
1523 
1524  T mV;
1525 };
1526 
1527 // MoveOnlyType - useful for verifying containers that may hold, e.g., unique_ptrs to make sure move ops are implemented
1529 {
1530  MoveOnlyType() = delete;
1531  MoveOnlyType(int val) : mVal(val) {}
1532  MoveOnlyType(const MoveOnlyType&) = delete;
1533  MoveOnlyType(MoveOnlyType&& x) : mVal(x.mVal) { x.mVal = 0; }
1534  MoveOnlyType& operator=(const MoveOnlyType&) = delete;
1535  MoveOnlyType& operator=(MoveOnlyType&& x)
1536  {
1537  mVal = x.mVal;
1538  x.mVal = 0;
1539  return *this;
1540  }
1541  bool operator==(const MoveOnlyType& o) const { return mVal == o.mVal; }
1542 
1543  int mVal;
1544 };
1545 
1546 // MoveOnlyTypeDefaultCtor - useful for verifying containers that may hold, e.g., unique_ptrs to make sure move ops are implemented
1548 {
1549  MoveOnlyTypeDefaultCtor() = default;
1550  MoveOnlyTypeDefaultCtor(int val) : mVal(val) {}
1552  MoveOnlyTypeDefaultCtor(MoveOnlyTypeDefaultCtor&& x) : mVal(x.mVal) { x.mVal = 0; }
1553  MoveOnlyTypeDefaultCtor& operator=(const MoveOnlyTypeDefaultCtor&) = delete;
1555  {
1556  mVal = x.mVal;
1557  x.mVal = 0;
1558  return *this;
1559  }
1560  bool operator==(const MoveOnlyTypeDefaultCtor& o) const { return mVal == o.mVal; }
1561 
1562  int mVal;
1563 };
1564 
1565 
1566 
1568 // Utility RAII class that sets a new default allocator for the scope
1569 //
1571 {
1572  eastl::allocator* mPrevAllocator = nullptr;
1573 
1574  AutoDefaultAllocator(eastl::allocator* nextAllocator) { mPrevAllocator = SetDefaultAllocator(nextAllocator); }
1575  ~AutoDefaultAllocator() { SetDefaultAllocator(mPrevAllocator); }
1576 };
1577 
1578 
1579 #endif // Header include guard
1580 
1581 
1582 
1583 
1584 
1585 
1586 
Definition: EASTLTest.h:541
Definition: EASTLTest.h:1185
Definition: EASTLTest.h:1125
Definition: EASTLTest.h:262
Definition: EASTLTest.h:1300
Definition: EASTLTest.h:1067
Definition: rand.hh:33
Definition: EASTLTest.h:1387
Definition: EASTLTest.h:1151
Definition: EASTLTest.h:920
Definition: allocator.h:52
Definition: string.h:280
EA Standard Template Library.
Definition: algorithm.h:288
void fill(ForwardIterator first, ForwardIterator last, const T &value)
Definition: fill_help.h:75
Definition: EASTLTest.h:580
Definition: EASTLTest.h:606
Definition: EASTLTest.h:634
Definition: EASTLTest.h:1571
Definition: EASTLTest.h:692
Definition: EASTLTest.h:1548
Definition: EASTLTest.h:1529
Definition: EASTLTest.h:313
Definition: EASTLTest.h:718
Definition: EASTLTest.h:529
Definition: EASTLTest.h:1462
Definition: EASTLTest.h:556
Definition: EASTLTest.h:348
Definition: EASTLTest.h:1446
Definition: EASTLTest.h:1512
Definition: functional.h:1015
Definition: EASTLTest.h:667
Definition: EASTLTest.h:518