aboutsummaryrefslogtreecommitdiff
path: root/test/source/EASTLTest.h
diff options
context:
space:
mode:
Diffstat (limited to 'test/source/EASTLTest.h')
-rw-r--r--test/source/EASTLTest.h1588
1 files changed, 0 insertions, 1588 deletions
diff --git a/test/source/EASTLTest.h b/test/source/EASTLTest.h
deleted file mode 100644
index fca6b2c..0000000
--- a/test/source/EASTLTest.h
+++ /dev/null
@@ -1,1588 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Copyright (c) Electronic Arts Inc. All rights reserved.
-/////////////////////////////////////////////////////////////////////////////
-
-
-#ifndef EASTLTEST_H
-#define EASTLTEST_H
-
-
-#include <EABase/eabase.h>
-#include <EATest/EATest.h>
-
-EA_DISABLE_ALL_VC_WARNINGS()
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <vector> // For the STD_STL_TYPE defines below.
-#if EASTL_EXCEPTIONS_ENABLED
- #include <stdexcept>
- #include <new>
-#endif
-EA_RESTORE_ALL_VC_WARNINGS();
-
-
-int TestAlgorithm();
-int TestAllocator();
-int TestAny();
-int TestArray();
-int TestBitVector();
-int TestBitset();
-int TestCharTraits();
-int TestChrono();
-int TestCppCXTypeTraits();
-int TestDeque();
-int TestExtra();
-int TestFinally();
-int TestFixedFunction();
-int TestFixedHash();
-int TestFixedList();
-int TestFixedMap();
-int TestFixedSList();
-int TestFixedSet();
-int TestFixedString();
-int TestFixedTupleVector();
-int TestFixedVector();
-int TestFunctional();
-int TestHash();
-int TestHeap();
-int TestIntrusiveHash();
-int TestIntrusiveList();
-int TestIntrusiveSDList();
-int TestIntrusiveSList();
-int TestIterator();
-int TestList();
-int TestListMap();
-int TestLruCache();
-int TestMap();
-int TestMemory();
-int TestMeta();
-int TestNumericLimits();
-int TestOptional();
-int TestRandom();
-int TestRatio();
-int TestRingBuffer();
-int TestSList();
-int TestSegmentedVector();
-int TestSet();
-int TestSmartPtr();
-int TestSort();
-int TestSpan();
-int TestString();
-int TestStringHashMap();
-int TestStringMap();
-int TestStringView();
-int TestTuple();
-int TestTupleVector();
-int TestTypeTraits();
-int TestUtility();
-int TestVariant();
-int TestVector();
-int TestVectorMap();
-int TestVectorSet();
-int TestAtomicBasic();
-int TestAtomicAsm();
-int TestBitcast();
-
-
-// Now enable warnings as desired.
-#ifdef _MSC_VER
- #pragma warning(disable: 4324) // 'struct_name' : structure was padded due to __declspec(align())
- //#pragma warning(disable: 4512) // 'class' : assignment operator could not be generated
- //#pragma warning(disable: 4100) // 'identifier' : unreferenced formal parameter
- //#pragma warning(disable: 4706) // assignment within conditional expression
-
- #pragma warning(default: 4056) // Floating-point constant arithmetic generates a result that exceeds the maximum allowable value
- #pragma warning(default: 4061) // The enumerate has no associated handler in a switch statement
- #pragma warning(default: 4062) // The enumerate has no associated handler in a switch statement, and there is no default label
- #pragma warning(default: 4191) // Calling this function through the result pointer may cause your program to crash
- #pragma warning(default: 4217) // Member template functions cannot be used for copy-assignment or copy-construction
- //#pragma warning(default: 4242) // 'variable' : conversion from 'type' to 'type', possible loss of data
- #pragma warning(default: 4254) // 'operator' : conversion from 'type1' to 'type2', possible loss of data
- #pragma warning(default: 4255) // 'function' : no function prototype given: converting '()' to '(void)'
- #pragma warning(default: 4263) // 'function' : member function does not override any base class virtual member function
- #pragma warning(default: 4264) // 'virtual_function' : no override available for virtual member function from base 'class'; function is hidden
- #pragma warning(default: 4287) // 'operator' : unsigned/negative constant mismatch
- #pragma warning(default: 4289) // Nonstandard extension used : 'var' : loop control variable declared in the for-loop is used outside the for-loop scope
- #pragma warning(default: 4296) // 'operator' : expression is always false
- #pragma warning(default: 4302) // 'conversion' : truncation from 'type 1' to 'type 2'
- #pragma warning(default: 4339) // 'type' : use of undefined type detected in CLR meta-data - use of this type may lead to a runtime exception
- #pragma warning(default: 4347) // Behavior change: 'function template' is called instead of 'function'
- //#pragma warning(default: 4514) // unreferenced inline/local function has been removed
- #pragma warning(default: 4529) // 'member_name' : forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name
- #pragma warning(default: 4545) // Expression before comma evaluates to a function which is missing an argument list
- #pragma warning(default: 4546) // Function call before comma missing argument list
- #pragma warning(default: 4547) // 'operator' : operator before comma has no effect; expected operator with side-effect
- //#pragma warning(default: 4548) // expression before comma has no effect; expected expression with side-effect
- #pragma warning(default: 4549) // 'operator' : operator before comma has no effect; did you intend 'operator'?
- #pragma warning(default: 4536) // 'type name' : type-name exceeds meta-data limit of 'limit' characters
- #pragma warning(default: 4555) // Expression has no effect; expected expression with side-effect
- #pragma warning(default: 4557) // '__assume' contains effect 'effect'
- //#pragma warning(default: 4619) // #pragma warning : there is no warning number 'number'
- #pragma warning(default: 4623) // 'derived class' : default constructor could not be generated because a base class default constructor is inaccessible
- //#pragma warning(default: 4625) // 'derived class' : copy constructor could not be generated because a base class copy constructor is inaccessible
- //#pragma warning(default: 4626) // 'derived class' : assignment operator could not be generated because a base class assignment operator is inaccessible
- #pragma warning(default: 4628) // Digraphs not supported with -Ze. Character sequence 'digraph' not interpreted as alternate token for 'char'
- #pragma warning(default: 4640) // 'instance' : construction of local static object is not thread-safe
- #pragma warning(default: 4668) // 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
- #pragma warning(default: 4682) // 'parameter' : no directional parameter attribute specified, defaulting to [in]
- #pragma warning(default: 4686) // 'user-defined type' : possible change in behavior, change in UDT return calling convention
- //#pragma warning(default: 4710) // 'function' : function not inlined
- //#pragma warning(default: 4786) // 'identifier' : identifier was truncated to 'number' characters in the debug information
- #pragma warning(default: 4793) // Native code generated for function 'function': 'reason'
- //#pragma warning(default: 4820) // 'bytes' bytes padding added after member 'member'
- #pragma warning(default: 4905) // Wide string literal cast to 'LPSTR'
- #pragma warning(default: 4906) // String literal cast to 'LPWSTR'
- #pragma warning(default: 4917) // 'declarator' : a GUID cannot only be associated with a class, interface or namespace
- #pragma warning(default: 4928) // Illegal copy-initialization; more than one user-defined conversion has been implicitly applied
- #pragma warning(default: 4931) // We are assuming the type library was built for number-bit pointers
- #pragma warning(default: 4946) // reinterpret_cast used between related classes: 'class1' and 'class2'
-
-#endif
-
-
-///////////////////////////////////////////////////////////////////////////////
-// EASTL includes
-//
-// Intentionally keep these includes below the warning settings specified above.
-//
-#include <EASTL/iterator.h>
-#include <EASTL/algorithm.h>
-
-
-
-
-/// EASTL_TestLevel
-///
-/// Defines how extensive our testing is. A low level is for a desktop or
-/// nightly build in which the test can run quickly but still hit the
-/// majority of functionality. High level is for heavy testing and internal
-/// validation which may take numerous hours to run.
-///
-enum EASTL_TestLevel
-{
- kEASTL_TestLevelLow = 1, /// ~10 seconds for test completion.
- kEASTL_TestLevelHigh = 10 /// Numerous hours for test completion.
-};
-
-extern int gEASTL_TestLevel;
-
-
-
-/// EASTLTest_CheckMemory
-///
-/// Does a global memory heap validation check. Returns 0 if OK and
-/// an error count if there is a problem.
-///
-/// Example usage:
-/// EASTLTest_CheckMemory();
-///
-int EASTLTest_CheckMemory_Imp(const char* pFile, int nLine);
-#define EASTLTest_CheckMemory() EASTLTest_CheckMemory_Imp(__FILE__, __LINE__)
-
-
-
-// EASTLTEST_STD_STL_VER
-//
-#if defined(_STLPORT_VERSION)
- #define EASTLTEST_STD_STL_VER_STLPORT
-#elif defined(_RWSTD_VER_STR) || defined(_RWSTD_NAMESPACE_END)
- #define EASTLTEST_STD_STL_VER_APACHE
-#elif defined(_CPPLIB_VER)
- #define EASTLTEST_STD_STL_VER_DINKUMWARE
-#elif defined(__GNUC__) && defined(_CXXCONFIG)
- #define EASTLTEST_STD_STL_VER_GCC
-#else
- #define EASTLTEST_STD_STL_VER_UNKNOWN
-#endif
-
-
-
-/// StdSTLType
-///
-enum StdSTLType
-{
- kSTLUnknown, // Unknown type
- kSTLPort, // STLPort. Descendent of the old HP / SGI STL.
- kSTLApache, // Apache stdcxx (previously RogueWave), which is a descendent of the old HP / SGI STL.
- kSTLClang, // Clang native. a.k.a. libc++
- kSTLGCC, // GCC native. a.k.a. libstdc++
- kSTLMS, // Microsoft. Tweaked version of Dinkumware.
- kSTLDinkumware // Generic Dinkumware
-};
-
-StdSTLType GetStdSTLType();
-
-
-
-
-/// GetStdSTLName
-///
-/// Returns the name of the std C++ STL available to the current build.
-/// The returned value will be one of:
-/// "STLPort"
-/// "GCC"
-/// "VC++"
-// "Apache" // Previously RogueWave
-///
-const char* GetStdSTLName();
-
-
-/// gEASTLTest_AllocationCount
-///
-extern int gEASTLTest_AllocationCount;
-extern int gEASTLTest_TotalAllocationCount;
-
-
-
-// For backwards compatibility:
-#define EASTLTest_Printf EA::UnitTest::Report
-#define VERIFY EATEST_VERIFY
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// EASTLTest_Rand
-///
-/// Implements a basic random number generator for EASTL unit tests. It's not
-/// intended to be a robust random number generator (though it is decent),
-/// but rather is present so the unit tests can have a portable random number
-/// generator they can rely on being present.
-///
-/// Example usage:
-/// EASTLTest_Rand rng;
-/// eastl_size_t x = rng(); // Generate value in range of [0, 0xffffffff] (i.e. generate any uint32_t)
-/// eastl_ssize_t y = rng.Rand(1000); // Generate value in range of [0, 1000)
-/// eastl_ssize_t z = rng.RandRange(-50, +30); // Generate value in range of [-50, +30)
-///
-/// Example usage in the random_shuffle algorithm:
-/// EASTLTest_Rand rng;
-/// random_shuffle(first, last, rnd);
-///
-class EASTLTest_Rand
-{
-public:
- EASTLTest_Rand(eastl_size_t nSeed) // The user must supply a seed; we don't provide default values.
- : mnSeed(nSeed) { }
-
- eastl_size_t Rand()
- {
- // This is not designed to be a high quality random number generator.
- if(mnSeed == 0)
- mnSeed = UINT64_C(0xfefefefefefefefe); // Can't have a seed of zero.
-
- const uint64_t nResult64A = ((mnSeed * UINT64_C(6364136223846793005)) + UINT64_C(1442695040888963407));
- const uint64_t nResult64B = ((nResult64A * UINT64_C(6364136223846793005)) + UINT64_C(1442695040888963407));
-
- mnSeed = (nResult64A >> 32) ^ nResult64B;
-
- return (eastl_size_t)mnSeed; // For eastl_size_t == uint32_t, this is a chop.
- }
-
- eastl_size_t operator()() // Returns a pseudorandom value in range of [0, 0xffffffffffffffff)] (i.e. generate any eastl_size_t)
- { return Rand(); }
-
- eastl_size_t operator()(eastl_size_t n) // Returns a pseudorandom value in range of [0, n)
- { return RandLimit(n); }
-
- eastl_size_t RandLimit(eastl_size_t nLimit) // Returns a pseudorandom value in range of [0, nLimit)
- {
- // Can't do the following correct solution because we don't have a portable int128_t to work with.
- // We could implement a 128 bit multiply manually. See EAStdC/int128_t.cpp.
- // return (eastl_size_t)((Rand() * (uint128_t)nLimit) >> 64);
-
- return (Rand() % nLimit); // This results in an imperfect distribution, especially for the case of nLimit being high relative to eastl_size_t.
- }
-
- eastl_ssize_t RandRange(eastl_ssize_t nBegin, eastl_ssize_t nEnd) // Returns a pseudorandom value in range of [nBegin, nEnd)
- { return nBegin + (eastl_ssize_t)RandLimit((eastl_size_t)(nEnd - nBegin)); }
-
-protected:
- uint64_t mnSeed;
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// RandGenT
-///
-/// A wrapper for EASTLTest_Rand which generates values of the given integral
-/// data type. This is mostly useful for clearnly avoiding compiler warnings,
-/// as we intentionally enable the highest warning levels in these tests.
-///
-template <typename Integer>
-struct RandGenT
-{
- RandGenT(eastl_size_t nSeed)
- : mRand(nSeed) { }
-
- Integer operator()()
- { return (Integer)mRand.Rand(); }
-
- Integer operator()(eastl_size_t n)
- { return (Integer)mRand.RandLimit(n); }
-
- EASTLTest_Rand mRand;
-};
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// kMagicValue
-///
-/// Used as a unique integer. We assign this to TestObject in its constructor
-/// and verify in the TestObject destructor that the value is unchanged.
-/// This can be used to tell, for example, if an invalid object is being
-/// destroyed.
-///
-const uint32_t kMagicValue = 0x01f1cbe8;
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// TestObject
-///
-/// Implements a generic object that is suitable for use in container tests.
-/// Note that we choose a very restricted set of functions that are available
-/// for this class. Do not add any additional functions, as that would
-/// compromise the intentions of the unit tests.
-///
-struct TestObject
-{
- int mX; // Value for the TestObject.
- bool mbThrowOnCopy; // Throw an exception of this object is copied, moved, or assigned to another.
- 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.
- uint32_t mMagicValue; // Used to verify that an instance is valid and that it is not corrupted. It should always be kMagicValue.
- static int64_t sTOCount; // Count of all current existing TestObjects.
- static int64_t sTOCtorCount; // Count of times any ctor was called.
- static int64_t sTODtorCount; // Count of times dtor was called.
- static int64_t sTODefaultCtorCount; // Count of times the default ctor was called.
- static int64_t sTOArgCtorCount; // Count of times the x0,x1,x2 ctor was called.
- static int64_t sTOCopyCtorCount; // Count of times copy ctor was called.
- static int64_t sTOMoveCtorCount; // Count of times move ctor was called.
- static int64_t sTOCopyAssignCount; // Count of times copy assignment was called.
- static int64_t sTOMoveAssignCount; // Count of times move assignment was called.
- static int sMagicErrorCount; // Number of magic number mismatch errors.
-
- explicit TestObject(int x = 0, bool bThrowOnCopy = false)
- : mX(x), mbThrowOnCopy(bThrowOnCopy), mMagicValue(kMagicValue)
- {
- ++sTOCount;
- ++sTOCtorCount;
- ++sTODefaultCtorCount;
- mId = sTOCtorCount;
- }
-
- // This constructor exists for the purpose of testing variadiac template arguments, such as with the emplace container functions.
- TestObject(int x0, int x1, int x2, bool bThrowOnCopy = false)
- : mX(x0 + x1 + x2), mbThrowOnCopy(bThrowOnCopy), mMagicValue(kMagicValue)
- {
- ++sTOCount;
- ++sTOCtorCount;
- ++sTOArgCtorCount;
- mId = sTOCtorCount;
- }
-
- TestObject(const TestObject& testObject)
- : mX(testObject.mX), mbThrowOnCopy(testObject.mbThrowOnCopy), mMagicValue(testObject.mMagicValue)
- {
- ++sTOCount;
- ++sTOCtorCount;
- ++sTOCopyCtorCount;
- mId = sTOCtorCount;
- if(mbThrowOnCopy)
- {
- #if EASTL_EXCEPTIONS_ENABLED
- throw "Disallowed TestObject copy";
- #endif
- }
- }
-
- // Due to the nature of TestObject, there isn't much special for us to
- // do in our move constructor. A move constructor swaps its contents with
- // the other object, whhich is often a default-constructed object.
- TestObject(TestObject&& testObject)
- : mX(testObject.mX), mbThrowOnCopy(testObject.mbThrowOnCopy), mMagicValue(testObject.mMagicValue)
- {
- ++sTOCount;
- ++sTOCtorCount;
- ++sTOMoveCtorCount;
- mId = sTOCtorCount; // testObject keeps its mId, and we assign ours anew.
- testObject.mX = 0; // We are swapping our contents with the TestObject, so give it our "previous" value.
- if(mbThrowOnCopy)
- {
- #if EASTL_EXCEPTIONS_ENABLED
- throw "Disallowed TestObject copy";
- #endif
- }
- }
-
- TestObject& operator=(const TestObject& testObject)
- {
- ++sTOCopyAssignCount;
-
- if(&testObject != this)
- {
- mX = testObject.mX;
- // Leave mId alone.
- mMagicValue = testObject.mMagicValue;
- mbThrowOnCopy = testObject.mbThrowOnCopy;
- if(mbThrowOnCopy)
- {
- #if EASTL_EXCEPTIONS_ENABLED
- throw "Disallowed TestObject copy";
- #endif
- }
- }
- return *this;
- }
-
- TestObject& operator=(TestObject&& testObject)
- {
- ++sTOMoveAssignCount;
-
- if(&testObject != this)
- {
- eastl::swap(mX, testObject.mX);
- // Leave mId alone.
- eastl::swap(mMagicValue, testObject.mMagicValue);
- eastl::swap(mbThrowOnCopy, testObject.mbThrowOnCopy);
-
- if(mbThrowOnCopy)
- {
- #if EASTL_EXCEPTIONS_ENABLED
- throw "Disallowed TestObject copy";
- #endif
- }
- }
- return *this;
- }
-
- ~TestObject()
- {
- if(mMagicValue != kMagicValue)
- ++sMagicErrorCount;
- mMagicValue = 0;
- --sTOCount;
- ++sTODtorCount;
- }
-
- static void Reset()
- {
- sTOCount = 0;
- sTOCtorCount = 0;
- sTODtorCount = 0;
- sTODefaultCtorCount = 0;
- sTOArgCtorCount = 0;
- sTOCopyCtorCount = 0;
- sTOMoveCtorCount = 0;
- sTOCopyAssignCount = 0;
- sTOMoveAssignCount = 0;
- sMagicErrorCount = 0;
- }
-
- static bool IsClear() // Returns true if there are no existing TestObjects and the sanity checks related to that test OK.
- {
- return (sTOCount == 0) && (sTODtorCount == sTOCtorCount) && (sMagicErrorCount == 0);
- }
-};
-
-// Operators
-// We specifically define only == and <, in order to verify that
-// our containers and algorithms are not mistakenly expecting other
-// operators for the contained and manipulated classes.
-inline bool operator==(const TestObject& t1, const TestObject& t2)
- { return t1.mX == t2.mX; }
-
-inline bool operator<(const TestObject& t1, const TestObject& t2)
- { return t1.mX < t2.mX; }
-
-
-// TestObject hash
-// Normally you don't want to put your hash functions in the eastl namespace, as that namespace is owned by EASTL.
-// However, these are the EASTL unit tests and we can say that they are also owned by EASTL.
-namespace eastl
-{
- template <>
- struct hash<TestObject>
- {
- size_t operator()(const TestObject& a) const
- { return static_cast<size_t>(a.mX); }
- };
-}
-
-
-// use_mX
-// Used for printing TestObject contents via the PrintSequence function,
-// which is defined below. See the PrintSequence function for documentation.
-// This function is an analog of the eastl::use_self and use_first functions.
-// We declare this all in one line because the user should never need to
-// debug usage of this function.
-template <typename T> struct use_mX { int operator()(const T& t) const { return t.mX; } };
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// SizedPOD
-//
-// Exists for the purpose testing PODs that are larger than built-in types.
-//
-template <size_t kSize>
-struct SizedPOD
-{
- char memory[kSize];
-};
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// ConstType
-///
-/// Used to test const type containers (e.g. vector<const ConstType>).
-///
-class ConstType
-{
-public:
- ConstType(int value) : mDummy(value) {};
- int mDummy;
-};
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// TestObjectHash
-///
-/// Implements a manually specified hash function for TestObjects.
-///
-struct TestObjectHash
-{
- size_t operator()(const TestObject& t) const
- {
- return (size_t)t.mX;
- }
-};
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// Align16
-///
-
-#if defined(EA_PROCESSOR_ARM)
- #define kEASTLTestAlign16 8 //ARM processors can only align to 8
-#else
- #define kEASTLTestAlign16 16
-#endif
-
-
-EA_PREFIX_ALIGN(kEASTLTestAlign16)
-struct Align16
-{
- explicit Align16(int x = 0) : mX(x) {}
- int mX;
-} EA_POSTFIX_ALIGN(kEASTLTestAlign16);
-
-inline bool operator==(const Align16& a, const Align16& b)
- { return (a.mX == b.mX); }
-
-inline bool operator<(const Align16& a, const Align16& b)
- { return (a.mX < b.mX); }
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// Align32
-///
-#if defined(EA_PROCESSOR_ARM)
- #define kEASTLTestAlign32 8 //ARM processors can only align to 8
-#elif defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) < 400) // GCC 2.x, 3.x
- #define kEASTLTestAlign32 16 // Some versions of GCC fail to support any alignment beyond 16.
-#else
- #define kEASTLTestAlign32 32
-#endif
-
-EA_PREFIX_ALIGN(kEASTLTestAlign32)
-struct Align32
-{
- explicit Align32(int x = 0) : mX(x) {}
- int mX;
-} EA_POSTFIX_ALIGN(kEASTLTestAlign32);
-
-inline bool operator==(const Align32& a, const Align32& b)
- { return (a.mX == b.mX); }
-
-inline bool operator<(const Align32& a, const Align32& b)
- { return (a.mX < b.mX); }
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// Align64
-///
-/// Used for testing of alignment.
-///
-#if defined(EA_PROCESSOR_ARM)
- #define kEASTLTestAlign64 8
-#elif defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) < 400) // GCC 2.x, 3.x
- #define kEASTLTestAlign64 16 // Some versions of GCC fail to support any alignment beyond 16.
-#else
- #define kEASTLTestAlign64 64
-#endif
-
-EA_PREFIX_ALIGN(kEASTLTestAlign64)
-struct Align64
-{
- explicit Align64(int x = 0) : mX(x) {}
- int mX;
-} EA_POSTFIX_ALIGN(kEASTLTestAlign64);
-
-inline bool operator==(const Align64& a, const Align64& b)
- { return (a.mX == b.mX); }
-
-inline bool operator<(const Align64& a, const Align64& b)
- { return (a.mX < b.mX); }
-
-namespace eastl
-{
- template <>
- struct hash < Align64 >
- {
- size_t operator()(const Align64& a) const
- {
- return static_cast<size_t>(a.mX);
- }
- };
-}
-
-
-
-
-
-/// test_use_self
-///
-/// Intentionally avoiding a dependency on eastl::use_self.
-///
-template <typename T>
-struct test_use_self
-{
- const T& operator()(const T& x) const
- { return x; }
-};
-
-
-
-/// GenerateIncrementalIntegers
-///
-/// Used to seed containers with incremental values based on integers.
-///
-/// Example usage:
-/// vector<int> v(10, 0);
-/// generate(v.begin(), v.end(), GenerateIncrementalIntegers<int>());
-/// // v will now have 0, 1, 2, ... 8, 9.
-///
-/// generate_n(intArray.begin(), 10, GenerateIncrementalIntegers<int>());
-/// // v will now have 0, 1, 2, ... 8, 9.
-///
-/// vector<TestObject> vTO(10, 0);
-/// generate(vTO.begin(), vTO.end(), GenerateIncrementalIntegers<TestObject>());
-/// // vTO will now have 0, 1, 2, ... 8, 9.
-///
-template <typename T>
-struct GenerateIncrementalIntegers
-{
- int mX;
-
- GenerateIncrementalIntegers(int x = 0)
- : mX(x) { }
-
- void reset(int x = 0)
- { mX = x; }
-
- T operator()()
- { return T(mX++); }
-};
-
-
-
-/// SetIncrementalIntegers
-///
-/// Used to seed containers with incremental values based on integers.
-///
-/// Example usage:
-/// vector<int> v(10, 0);
-/// for_each(v.begin(), v.end(), SetIncrementalIntegers<int>());
-/// // v will now have 0, 1, 2, ... 8, 9.
-///
-template <typename T>
-struct SetIncrementalIntegers
-{
- int mX;
-
- SetIncrementalIntegers(int x = 0)
- : mX(x) { }
-
- void reset(int x = 0)
- { mX = x; }
-
- void operator()(T& t)
- { t = T(mX++); }
-};
-
-
-
-/// CompareContainers
-///
-/// Does a comparison between the contents of two containers.
-///
-/// Specifically tests for the following properties:
-/// empty() is the same for both
-/// size() is the same for both
-/// iteration through both element by element yields equal values.
-///
-template <typename T1, typename T2, typename ExtractValue1, typename ExtractValue2>
-int CompareContainers(const T1& t1, const T2& t2, const char* ppName,
- ExtractValue1 ev1 = test_use_self<T1>(), ExtractValue2 ev2 = test_use_self<T2>())
-{
- int nErrorCount = 0;
-
- // Compare emptiness.
- VERIFY(t1.empty() == t2.empty());
-
- // Compare sizes.
- const size_t nSize1 = t1.size();
- const size_t nSize2 = t2.size();
-
- VERIFY(nSize1 == nSize2);
- if(nSize1 != nSize2)
- EASTLTest_Printf("%s: Container size difference: %u, %u\n", ppName, (unsigned)nSize1, (unsigned)nSize2);
-
- // Compare values.
- if(nSize1 == nSize2)
- {
- // Test iteration
- typename T1::const_iterator it1 = t1.begin();
- typename T2::const_iterator it2 = t2.begin();
-
- for(unsigned j = 0; it1 != t1.end(); ++it1, ++it2, ++j)
- {
- const typename T1::value_type& v1 = *it1;
- const typename T2::value_type& v2 = *it2;
-
- VERIFY(ev1(v1) == ev2(v2));
- if(!(ev1(v1) == ev2(v2)))
- {
- EASTLTest_Printf("%s: Container iterator difference at index %d\n", ppName, j);
- break;
- }
- }
-
- VERIFY(it1 == t1.end());
- VERIFY(it2 == t2.end());
- }
-
- return nErrorCount;
-}
-
-
-
-
-
-/// VerifySequence
-///
-/// Allows the user to specify that a container has a given set of values.
-///
-/// Example usage:
-/// vector<int> v;
-/// v.push_back(1); v.push_back(3); v.push_back(5);
-/// VerifySequence(v.begin(), v.end(), int(), "v.push_back", 1, 3, 5, -1);
-///
-/// Note: The StackValue template argument is a hint to the compiler about what type
-/// the passed vararg sequence is.
-///
-template <typename InputIterator, typename StackValue>
-bool VerifySequence(InputIterator first, InputIterator last, StackValue /*unused*/, const char* pName, ...)
-{
- typedef typename eastl::iterator_traits<InputIterator>::value_type value_type;
-
- int argIndex = 0;
- int seqIndex = 0;
- bool bReturnValue = true;
- StackValue next;
-
- va_list args;
- va_start(args, pName);
-
- for( ; first != last; ++first, ++argIndex, ++seqIndex)
- {
- next = va_arg(args, StackValue);
-
- if((next == StackValue(-1)) || !(value_type(next) == *first))
- {
- if(pName)
- EASTLTest_Printf("[%s] Mismatch at index %d\n", pName, argIndex);
- else
- EASTLTest_Printf("Mismatch at index %d\n", argIndex);
- bReturnValue = false;
- }
- }
-
- for(; first != last; ++first)
- ++seqIndex;
-
- if(bReturnValue)
- {
- next = va_arg(args, StackValue);
-
- if(!(next == StackValue(-1)))
- {
- do {
- ++argIndex;
- next = va_arg(args, StackValue);
- } while(!(next == StackValue(-1)));
-
- if(pName)
- EASTLTest_Printf("[%s] Too many elements: expected %d, found %d\n", pName, argIndex, seqIndex);
- else
- EASTLTest_Printf("Too many elements: expected %d, found %d\n", argIndex, seqIndex);
- bReturnValue = false;
- }
- }
-
- va_end(args);
-
- return bReturnValue;
-}
-
-
-
-
-/// PrintSequence
-///
-/// Allows the user to print a sequence of values.
-///
-/// Example usage:
-/// vector<int> v;
-/// PrintSequence(v.begin(), v.end(), use_self<int>(), 100, "vector", 1, 3, 5, -1);
-///
-/// Example usage:
-/// template <typename T> struct use_mX { int operator()(const T& t) const { return t.mX; } };
-/// vector<TestObject> v;
-/// PrintSequence(v.begin(), v.end(), use_mX<TestObject>(), 100, "vector", 1, 3, 5, -1);
-///
-template <typename InputIterator, typename ExtractInt>
-void PrintSequence(InputIterator first, InputIterator last, ExtractInt extractInt, int nMaxCount, const char* pName, ...)
-{
- if(pName)
- EASTLTest_Printf("[%s]", pName);
-
- for(int i = 0; (i < nMaxCount) && (first != last); ++i, ++first)
- {
- EASTLTest_Printf("%d ", (int)extractInt(*first));
- }
-
- EASTLTest_Printf("\n");
-}
-
-
-
-
-/// demoted_iterator
-///
-/// Converts an iterator into a demoted category. For example, you can convert
-/// an iterator of type bidirectional_iterator_tag to forward_iterator_tag.
-/// The following is a list of iterator types. A demonted iterator can be demoted
-/// only to a lower iterator category (earlier in the following list):
-/// input_iterator_tag
-/// forward_iterator_tag
-/// bidirectional_iterator_tag
-/// random_access_iterator_tag
-/// contiguous_iterator_tag
-///
-/// Converts something which can be iterated into a formal input iterator.
-/// This class is useful for testing functions and algorithms that expect
-/// InputIterators, which are the lowest and 'weakest' form of iterators.
-///
-/// Key traits of InputIterators:
-/// Algorithms on input iterators should never attempt to pass
-/// through the same iterator twice. They should be single pass
-/// algorithms. value_type T is not required to be an lvalue type.
-///
-/// Example usage:
-/// typedef demoted_iterator<int*, eastl::bidirectional_iterator_tag> PointerAsBidirectionalIterator;
-/// typedef demoted_iterator<MyVector::iterator, eastl::forward_iterator_tag> VectorIteratorAsForwardIterator;
-///
-/// Example usage:
-/// IntVector v;
-/// comb_sort(to_forward_iterator(v.begin()), to_forward_iterator(v.end()));
-///
-template <typename Iterator, typename IteratorCategory>
-class demoted_iterator
-{
-protected:
- Iterator mIterator;
-
-public:
- typedef demoted_iterator<Iterator, IteratorCategory> this_type;
- typedef Iterator iterator_type;
- typedef IteratorCategory iterator_category;
- typedef typename eastl::iterator_traits<Iterator>::value_type value_type;
- typedef typename eastl::iterator_traits<Iterator>::difference_type difference_type;
- typedef typename eastl::iterator_traits<Iterator>::reference reference;
- typedef typename eastl::iterator_traits<Iterator>::pointer pointer;
-
- demoted_iterator()
- : mIterator() { }
-
- explicit demoted_iterator(const Iterator& i)
- : mIterator(i) { }
-
- demoted_iterator(const this_type& x)
- : mIterator(x.mIterator) { }
-
- this_type& operator=(const Iterator& i)
- { mIterator = i; return *this; }
-
- this_type& operator=(const this_type& x)
- { mIterator = x.mIterator; return *this; }
-
- reference operator*() const
- { return *mIterator; }
-
- pointer operator->() const
- { return mIterator; }
-
- this_type& operator++()
- { ++mIterator; return *this; }
-
- this_type operator++(int)
- { return this_type(mIterator++); }
-
- this_type& operator--()
- { --mIterator; return *this; }
-
- this_type operator--(int)
- { return this_type(mIterator--); }
-
- reference operator[](const difference_type& n) const
- { return mIterator[n]; }
-
- this_type& operator+=(const difference_type& n)
- { mIterator += n; return *this; }
-
- this_type operator+(const difference_type& n) const
- { return this_type(mIterator + n); }
-
- this_type& operator-=(const difference_type& n)
- { mIterator -= n; return *this; }
-
- this_type operator-(const difference_type& n) const
- { return this_type(mIterator - n); }
-
- const iterator_type& base() const
- { return mIterator; }
-
-}; // class demoted_iterator
-
-template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
-inline bool
-operator==(const demoted_iterator<Iterator1, IteratorCategory1>& a, const demoted_iterator<Iterator2, IteratorCategory2>& b)
- { return a.base() == b.base(); }
-
-template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
-inline bool
-operator!=(const demoted_iterator<Iterator1, IteratorCategory1>& a, const demoted_iterator<Iterator2, IteratorCategory2>& b)
- { return !(a == b); }
-
-template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
-inline bool
-operator<(const demoted_iterator<Iterator1, IteratorCategory1>& a, const demoted_iterator<Iterator2, IteratorCategory2>& b)
- { return a.base() < b.base(); }
-
-template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
-inline bool
-operator<=(const demoted_iterator<Iterator1, IteratorCategory1>& a, const demoted_iterator<Iterator2, IteratorCategory2>& b)
- { return !(b < a); }
-
-template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
-inline bool
-operator>(const demoted_iterator<Iterator1, IteratorCategory1>& a, const demoted_iterator<Iterator2, IteratorCategory2>& b)
- { return b < a; }
-
-template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
-inline bool
-operator>=(const demoted_iterator<Iterator1, IteratorCategory1>& a, const demoted_iterator<Iterator2, IteratorCategory2>& b)
- { return !(a < b); }
-
-template<typename Iterator1, typename IteratorCategory1, typename Iterator2, typename IteratorCategory2>
-inline demoted_iterator<Iterator1, IteratorCategory1>
-operator-(const demoted_iterator<Iterator1, IteratorCategory1>& a, const demoted_iterator<Iterator2, IteratorCategory2>& b)
- { return demoted_iterator<Iterator1, IteratorCategory1>(a.base() - b.base()); }
-
-template<typename Iterator1, typename IteratorCategory1>
-inline demoted_iterator<Iterator1, IteratorCategory1>
-operator+(typename demoted_iterator<Iterator1, IteratorCategory1>::difference_type n, const demoted_iterator<Iterator1, IteratorCategory1>& a)
- { return a + n; }
-
-
-// to_xxx_iterator
-//
-// Returns a demoted iterator
-//
-template <typename Iterator>
-inline demoted_iterator<Iterator, EASTL_ITC_NS::input_iterator_tag>
-to_input_iterator(const Iterator& i)
- { return demoted_iterator<Iterator, EASTL_ITC_NS::input_iterator_tag>(i); }
-
-template <typename Iterator>
-inline demoted_iterator<Iterator, EASTL_ITC_NS::forward_iterator_tag>
-to_forward_iterator(const Iterator& i)
- { return demoted_iterator<Iterator, EASTL_ITC_NS::forward_iterator_tag>(i); }
-
-template <typename Iterator>
-inline demoted_iterator<Iterator, EASTL_ITC_NS::bidirectional_iterator_tag>
-to_bidirectional_iterator(const Iterator& i)
- { return demoted_iterator<Iterator, EASTL_ITC_NS::bidirectional_iterator_tag>(i); }
-
-template <typename Iterator>
-inline demoted_iterator<Iterator, EASTL_ITC_NS::random_access_iterator_tag>
-to_random_access_iterator(const Iterator& i)
- { return demoted_iterator<Iterator, EASTL_ITC_NS::random_access_iterator_tag>(i); }
-
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// MallocAllocator
-//
-// Implements an EASTL allocator that uses malloc/free as opposed to
-// new/delete or PPMalloc Malloc/Free. This is useful for testing
-// allocator behaviour of code.
-//
-// Example usage:
-// vector<int, MallocAllocator> intVector;
-//
-class MallocAllocator
-{
-public:
- MallocAllocator(const char* = EASTL_NAME_VAL("MallocAllocator"))
- : mAllocCount(0), mFreeCount(0), mAllocVolume(0) {}
-
- MallocAllocator(const MallocAllocator& x)
- : mAllocCount(x.mAllocCount), mFreeCount(x.mFreeCount), mAllocVolume(x.mAllocVolume) {}
-
- MallocAllocator(const MallocAllocator& x, const char*) : MallocAllocator(x) {}
-
- MallocAllocator& operator=(const MallocAllocator& x)
- {
- mAllocCount = x.mAllocCount;
- mFreeCount = x.mFreeCount;
- mAllocVolume = x.mAllocVolume;
- return *this;
- }
-
- void* allocate(size_t n, int = 0);
- 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.
- void deallocate(void* p, size_t n);
-
- const char* get_name() const { return "MallocAllocator"; }
- void set_name(const char*) {}
-
- static void reset_all()
- {
- mAllocCountAll = 0;
- mFreeCountAll = 0;
- mAllocVolumeAll = 0;
- mpLastAllocation = NULL;
- }
-
-public:
- int mAllocCount;
- int mFreeCount;
- size_t mAllocVolume;
-
- static int mAllocCountAll;
- static int mFreeCountAll;
- static size_t mAllocVolumeAll;
- static void* mpLastAllocation;
-};
-
-inline bool operator==(const MallocAllocator&, const MallocAllocator&) { return true; }
-inline bool operator!=(const MallocAllocator&, const MallocAllocator&) { return false; }
-
-
-///////////////////////////////////////////////////////////////////////////////
-// CustomAllocator
-//
-// Implements an allocator that works just like eastl::allocator but is defined
-// within this test as opposed to within EASTL.
-//
-// Example usage:
-// vector<int, CustomAllocator> intVector;
-//
-class CustomAllocator
-{
-public:
- CustomAllocator(const char* = NULL) {}
- CustomAllocator(const CustomAllocator&) {}
- CustomAllocator(const CustomAllocator&, const char*) {}
- CustomAllocator& operator=(const CustomAllocator&) { return *this; }
-
- void* allocate(size_t n, int flags = 0);
- void* allocate(size_t n, size_t, size_t, int flags = 0);
- void deallocate(void* p, size_t n);
-
- const char* get_name() const { return "CustomAllocator"; }
- void set_name(const char*) {}
-};
-
-inline bool operator==(const CustomAllocator&, const CustomAllocator&) { return true; }
-inline bool operator!=(const CustomAllocator&, const CustomAllocator&) { return false; }
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// UnequalAllocator
-///
-/// Acts the same as eastl::allocator, but always compares as unequal to an
-/// instance of itself.
-///
-class UnequalAllocator
-{
-public:
- EASTL_ALLOCATOR_EXPLICIT UnequalAllocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME))
- : mAllocator(pName) {}
-
- UnequalAllocator(const UnequalAllocator& x) : mAllocator(x.mAllocator) {}
- UnequalAllocator(const UnequalAllocator& x, const char* pName) : mAllocator(x.mAllocator) { set_name(pName); }
- UnequalAllocator& operator=(const UnequalAllocator& x)
- {
- mAllocator = x.mAllocator;
- return *this;
- }
-
- void* allocate(size_t n, int flags = 0) { return mAllocator.allocate(n, flags); }
- void* allocate(size_t n, size_t alignment, size_t offset, int flags = 0) { return mAllocator.allocate(n, alignment, offset, flags); }
- void deallocate(void* p, size_t n) { return mAllocator.deallocate(p, n); }
-
- const char* get_name() const { return mAllocator.get_name(); }
- void set_name(const char* pName) { mAllocator.set_name(pName); }
-
-protected:
- eastl::allocator mAllocator;
-};
-
-inline bool operator==(const UnequalAllocator&, const UnequalAllocator&) { return false; }
-inline bool operator!=(const UnequalAllocator&, const UnequalAllocator&) { return true; }
-
-
-///////////////////////////////////////////////////////////////////////////////
-/// CountingAllocator
-///
-/// Counts allocation events allowing unit tests to validate assumptions.
-///
-class CountingAllocator : public eastl::allocator
-{
-public:
- using base_type = eastl::allocator;
-
- EASTL_ALLOCATOR_EXPLICIT CountingAllocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME))
- : base_type(pName)
- {
- totalCtorCount++;
- defaultCtorCount++;
- }
-
- CountingAllocator(const CountingAllocator& x) : base_type(x)
- {
- totalCtorCount++;
- copyCtorCount++;
- }
-
- CountingAllocator(const CountingAllocator& x, const char* pName) : base_type(x)
- {
- totalCtorCount++;
- copyCtorCount++;
- set_name(pName);
- }
-
- CountingAllocator& operator=(const CountingAllocator& x)
- {
- base_type::operator=(x);
- assignOpCount++;
- return *this;
- }
-
- virtual void* allocate(size_t n, int flags = 0)
- {
- activeAllocCount++;
- totalAllocCount++;
- totalAllocatedMemory += n;
- activeAllocatedMemory += n;
- return base_type::allocate(n, flags);
- }
-
- virtual void* allocate(size_t n, size_t alignment, size_t offset, int flags = 0)
- {
- activeAllocCount++;
- totalAllocCount++;
- totalAllocatedMemory += n;
- activeAllocatedMemory += n;
- return base_type::allocate(n, alignment, offset, flags);
- }
-
- void deallocate(void* p, size_t n)
- {
- activeAllocCount--;
- totalDeallocCount--;
- activeAllocatedMemory -= n;
- return base_type::deallocate(p, n);
- }
-
- const char* get_name() const { return base_type::get_name(); }
- void set_name(const char* pName) { base_type::set_name(pName); }
-
- static auto getTotalAllocationCount() { return totalAllocCount; }
- static auto getTotalAllocationSize() { return totalAllocatedMemory; }
- static auto getActiveAllocationSize() { return activeAllocatedMemory; }
- static auto getActiveAllocationCount() { return activeAllocCount; }
- static auto neverUsed() { return totalAllocCount == 0; }
-
- static void resetCount()
- {
- activeAllocCount = 0;
- totalAllocCount = 0;
- totalDeallocCount = 0;
- totalCtorCount = 0;
- defaultCtorCount = 0;
- copyCtorCount = 0;
- assignOpCount = 0;
- totalAllocatedMemory = 0;
- activeAllocatedMemory = 0;
- }
-
- virtual ~CountingAllocator() = default;
-
- static uint64_t activeAllocCount;
- static uint64_t totalAllocCount;
- static uint64_t totalDeallocCount;
- static uint64_t totalCtorCount;
- static uint64_t defaultCtorCount;
- static uint64_t copyCtorCount;
- static uint64_t assignOpCount;
- static uint64_t totalAllocatedMemory; // the total amount of memory allocated
- static uint64_t activeAllocatedMemory; // currently allocated memory by allocator
-};
-
-inline bool operator==(const CountingAllocator& rhs, const CountingAllocator& lhs) { return operator==(CountingAllocator::base_type(rhs), CountingAllocator::base_type(lhs)); }
-inline bool operator!=(const CountingAllocator& rhs, const CountingAllocator& lhs) { return !(rhs == lhs); }
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// InstanceAllocator
-//
-// Implements an allocator which has a instance id that makes it different
-// from other InstanceAllocators of a different id. Allocations between
-// InstanceAllocators of different ids are incompatible. An allocation done
-// by an InstanceAllocator of id=0 cannot be freed by an InstanceAllocator
-// of id=1.
-//
-// Example usage:
-// InstanceAllocator ia0((uint8_t)0);
-// InstanceAllocator ia1((uint8_t)1);
-//
-// eastl::list<int, InstanceAllocator> list0(1, ia0);
-// eastl::list<int, InstanceAllocator> list1(1, ia1);
-//
-// 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.
-//
-class InstanceAllocator
-{
-public:
- enum
- {
- kMultiplier = 16
- }; // Use 16 because it's the highest currently known platform alignment requirement.
-
- InstanceAllocator(const char* = NULL, uint8_t instanceId = 0) : mInstanceId(instanceId) {}
- InstanceAllocator(uint8_t instanceId) : mInstanceId(instanceId) {}
- InstanceAllocator(const InstanceAllocator& x) : mInstanceId(x.mInstanceId) {}
- InstanceAllocator(const InstanceAllocator& x, const char*) : mInstanceId(x.mInstanceId) {}
-
- InstanceAllocator& operator=(const InstanceAllocator& x)
- {
- mInstanceId = x.mInstanceId;
- return *this;
- }
-
- void* allocate(size_t n, int = 0)
- { // +1 so that we always have space to write mInstanceId.
- uint8_t* p8 =
- static_cast<uint8_t*>(malloc(n + (kMultiplier * (mInstanceId + 1)))); // We make allocations between
- // different instances incompatible by
- // tweaking their return values.
- eastl::fill(p8, p8 + kMultiplier, 0xff);
- EA_ANALYSIS_ASSUME(p8 != NULL);
- *p8 = mInstanceId;
- return p8 + (kMultiplier * (mInstanceId + 1));
- }
-
- void* allocate(size_t n, size_t, size_t, int = 0)
- { // +1 so that we always have space to write mInstanceId.
- uint8_t* p8 =
- static_cast<uint8_t*>(malloc(n + (kMultiplier * (mInstanceId + 1)))); // We make allocations between
- // different instances incompatible by
- // tweaking their return values.
- eastl::fill(p8, p8 + kMultiplier, 0xff);
- EA_ANALYSIS_ASSUME(p8 != NULL);
- *p8 = mInstanceId;
- return p8 + (kMultiplier * (mInstanceId + 1));
- }
-
- void deallocate(void* p, size_t /*n*/)
- {
- uint8_t* p8 = static_cast<uint8_t*>(p) - (kMultiplier * (mInstanceId + 1));
- EASTL_ASSERT(*p8 == mInstanceId); // mInstanceId must match the id used in allocate(), otherwise the behavior is
- // undefined (probably a heap assert).
- if (*p8 == mInstanceId) // It's possible that *p8 coincidentally matches mInstanceId if p8 is offset into memory
- // we don't control.
- free(p8);
- else
- ++mMismatchCount;
- }
-
- const char* get_name()
- {
- sprintf(mName, "InstanceAllocator %u", mInstanceId);
- return mName;
- }
-
- void set_name(const char*) {}
-
- static void reset_all() { mMismatchCount = 0; }
-
-public:
- uint8_t mInstanceId;
- char mName[32];
-
- static int mMismatchCount;
-};
-
-inline bool operator==(const InstanceAllocator& a, const InstanceAllocator& b) { return (a.mInstanceId == b.mInstanceId); }
-inline bool operator!=(const InstanceAllocator& a, const InstanceAllocator& b) { return (a.mInstanceId != b.mInstanceId); }
-
-
-///////////////////////////////////////////////////////////////////////////////
-// ThrowingAllocator
-//
-// Implements an EASTL allocator that uses malloc/free as opposed to
-// new/delete or PPMalloc Malloc/Free. This is useful for testing
-// allocator behaviour of code.
-//
-// Example usage:
-// vector<int, ThrowingAllocator< false<> > intVector;
-//
-template <bool initialShouldThrow = true>
-class ThrowingAllocator
-{
-public:
- ThrowingAllocator(const char* = EASTL_NAME_VAL("ThrowingAllocator")) : mbShouldThrow(initialShouldThrow) {}
- ThrowingAllocator(const ThrowingAllocator& x) : mbShouldThrow(x.mbShouldThrow) {}
- ThrowingAllocator(const ThrowingAllocator& x, const char*) : mbShouldThrow(x.mbShouldThrow) {}
-
- ThrowingAllocator& operator=(const ThrowingAllocator& x)
- {
- mbShouldThrow = x.mbShouldThrow;
- return *this;
- }
-
- void* allocate(size_t n, int = 0)
- {
-#if EASTL_EXCEPTIONS_ENABLED
- if (mbShouldThrow)
- throw std::bad_alloc();
-#endif
- return malloc(n);
- }
-
- void* allocate(size_t n, size_t, size_t, int = 0)
- {
-#if EASTL_EXCEPTIONS_ENABLED
- if (mbShouldThrow)
- throw std::bad_alloc();
-#endif
- return malloc(n); // We don't support alignment, so you can't use this class where alignment is required.
- }
-
- void deallocate(void* p, size_t) { free(p); }
-
- const char* get_name() const { return "ThrowingAllocator"; }
- void set_name(const char*) {}
-
- void set_should_throw(bool shouldThrow) { mbShouldThrow = shouldThrow; }
- bool get_should_throw() const { return mbShouldThrow; }
-
-protected:
- bool mbShouldThrow;
-};
-
-template <bool initialShouldThrow>
-inline bool operator==(const ThrowingAllocator<initialShouldThrow>&, const ThrowingAllocator<initialShouldThrow>&)
-{
- return true;
-}
-
-template <bool initialShouldThrow>
-inline bool operator!=(const ThrowingAllocator<initialShouldThrow>&, const ThrowingAllocator<initialShouldThrow>&)
-{
- return false;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Helper utility that does a case insensitive string comparsion with two sets of overloads
-//
-struct TestStrCmpI_2
-{
- bool operator()(const char* pCStr, const eastl::string& str) const { return str.comparei(pCStr) == 0; }
- bool operator()(const eastl::string& str, const char* pCStr) const { return str.comparei(pCStr) == 0; }
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// StompDetectAllocator
-//
-// An allocator that has sentinal values surrounding its allocator in an
-// effort to detected if its internal memory has been stomped.
-//
-static uint64_t STOMP_MAGIC_V1 = 0x0101DEC1A551F1ED;
-static uint64_t STOMP_MAGIC_V2 = 0x12345C1A551F1ED5;
-
-struct StompDetectAllocator
-{
- StompDetectAllocator() { Validate(); }
- ~StompDetectAllocator() { Validate(); }
-
- StompDetectAllocator(const char*) { Validate(); }
-
- void* allocate(size_t n, int = 0) { return mMallocAllocator.allocate(n); }
- void* allocate(size_t n, size_t, size_t, int = 0) { return mMallocAllocator.allocate(n); }
- void deallocate(void* p, size_t n) { mMallocAllocator.deallocate(p, n); }
-
- const char* get_name() const { return "FatAllocator"; }
- void set_name(const char*) {}
-
- void Validate() const
- {
- EASTL_ASSERT(mSentinal1 == STOMP_MAGIC_V1);
- EASTL_ASSERT(mSentinal2 == STOMP_MAGIC_V2);
- }
-
- uint64_t mSentinal1 = STOMP_MAGIC_V1;
- MallocAllocator mMallocAllocator;
- uint64_t mSentinal2 = STOMP_MAGIC_V2;
-};
-
-inline bool operator==(const StompDetectAllocator& a, const StompDetectAllocator& b)
-{
- a.Validate();
- b.Validate();
-
- return (a.mMallocAllocator == b.mMallocAllocator);
-}
-
-inline bool operator!=(const StompDetectAllocator& a, const StompDetectAllocator& b)
-{
- a.Validate();
- b.Validate();
-
- return (a.mMallocAllocator != b.mMallocAllocator);
-}
-
-
-// Commonly used free-standing functions to test callables
-inline int ReturnVal(int param) { return param; }
-inline int ReturnZero() { return 0; }
-inline int ReturnOne() { return 1; }
-
-
-// ValueInit
-template<class T>
-struct ValueInitOf
-{
- ValueInitOf() : mV() {}
- ~ValueInitOf() = default;
-
- ValueInitOf(const ValueInitOf&) = default;
- ValueInitOf(ValueInitOf&&) = default;
-
- ValueInitOf& operator=(const ValueInitOf&) = default;
- ValueInitOf& operator=(ValueInitOf&&) = default;
-
- T get() { return mV; }
-
- T mV;
-};
-
-// MoveOnlyType - useful for verifying containers that may hold, e.g., unique_ptrs to make sure move ops are implemented
-struct MoveOnlyType
-{
- MoveOnlyType() = delete;
- MoveOnlyType(int val) : mVal(val) {}
- MoveOnlyType(const MoveOnlyType&) = delete;
- MoveOnlyType(MoveOnlyType&& x) : mVal(x.mVal) { x.mVal = 0; }
- MoveOnlyType& operator=(const MoveOnlyType&) = delete;
- MoveOnlyType& operator=(MoveOnlyType&& x)
- {
- mVal = x.mVal;
- x.mVal = 0;
- return *this;
- }
- bool operator==(const MoveOnlyType& o) const { return mVal == o.mVal; }
-
- int mVal;
-};
-
-// MoveOnlyTypeDefaultCtor - useful for verifying containers that may hold, e.g., unique_ptrs to make sure move ops are implemented
-struct MoveOnlyTypeDefaultCtor
-{
- MoveOnlyTypeDefaultCtor() = default;
- MoveOnlyTypeDefaultCtor(int val) : mVal(val) {}
- MoveOnlyTypeDefaultCtor(const MoveOnlyTypeDefaultCtor&) = delete;
- MoveOnlyTypeDefaultCtor(MoveOnlyTypeDefaultCtor&& x) : mVal(x.mVal) { x.mVal = 0; }
- MoveOnlyTypeDefaultCtor& operator=(const MoveOnlyTypeDefaultCtor&) = delete;
- MoveOnlyTypeDefaultCtor& operator=(MoveOnlyTypeDefaultCtor&& x)
- {
- mVal = x.mVal;
- x.mVal = 0;
- return *this;
- }
- bool operator==(const MoveOnlyTypeDefaultCtor& o) const { return mVal == o.mVal; }
-
- int mVal;
-};
-
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Utility RAII class that sets a new default allocator for the scope
-//
-struct AutoDefaultAllocator
-{
- eastl::allocator* mPrevAllocator = nullptr;
-
- AutoDefaultAllocator(eastl::allocator* nextAllocator) { mPrevAllocator = SetDefaultAllocator(nextAllocator); }
- ~AutoDefaultAllocator() { SetDefaultAllocator(mPrevAllocator); }
-};
-
-
-#endif // Header include guard
-
-
-
-
-
-
-