diff options
Diffstat (limited to 'test')
80 files changed, 0 insertions, 57115 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index ff16189..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,102 +0,0 @@ -#------------------------------------------------------------------------------------------- -# Copyright (C) Electronic Arts Inc. All rights reserved. -#------------------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------------------- -# CMake info -#------------------------------------------------------------------------------------------- -cmake_minimum_required(VERSION 3.1) -project(EASTLTest CXX) -include(CTest) - -#------------------------------------------------------------------------------------------- -# Defines -#------------------------------------------------------------------------------------------- -add_definitions(-D_CRT_SECURE_NO_WARNINGS) -add_definitions(-D_SCL_SECURE_NO_WARNINGS) -add_definitions(-DEASTL_OPENSOURCE=1) -add_definitions(-D_CHAR16T) -add_definitions(-DEASTL_THREAD_SUPPORT_AVAILABLE=0) -if (EASTL_STD_ITERATOR_CATEGORY_ENABLED) - add_definitions(-DEASTL_STD_ITERATOR_CATEGORY_ENABLED=1) -endif() - -#------------------------------------------------------------------------------------------- -# Compiler Flags -#------------------------------------------------------------------------------------------- -set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/../scripts/CMake") -include(CommonCppFlags) - -if (MSVC) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") -endif() - -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-pointer-bool-conversion -Wno-unknown-warning-option") -endif() - -# Parts of the test suite fail to compile if char8_t is enabled, so we -# disable it and only enable for specific source files later on. -if (EASTL_NO_CHAR8T_FLAG) - add_compile_options(${EASTL_NO_CHAR8T_FLAG}) -endif() - -#------------------------------------------------------------------------------------------- -# Source files -#------------------------------------------------------------------------------------------- -file(GLOB EASTLTEST_SOURCES "source/*.cpp" "source/*.inl" "source/*.h") -set(SOURCES ${EASTLTEST_SOURCES}) - -# Compile a subset of tests with explicit char8_t support if available. -if (EASTL_CHAR8T_FLAG) - message(STATUS "Building with char8_t support in tests.") - set(EASTLTEST_CHAR8T_SOURCES "source/TestString.cpp" "source/TestStringView.cpp") - - set_source_files_properties(${EASTLTEST_CHAR8T_SOURCES} PROPERTIES - COMPILE_FLAGS ${EASTL_CHAR8T_FLAG} - COMPILE_DEFINITIONS "EASTL_EXPECT_CHAR8T_SUPPORT") -endif() - -#------------------------------------------------------------------------------------------- -# Executable definition -#------------------------------------------------------------------------------------------- -add_executable(EASTLTest ${SOURCES}) - -#------------------------------------------------------------------------------------------- -# Include directories -#------------------------------------------------------------------------------------------- -target_include_directories(EASTLTest PUBLIC include) - -#------------------------------------------------------------------------------------------- -# Dependencies -#------------------------------------------------------------------------------------------- -add_subdirectory(packages/EABase) -add_subdirectory(packages/EAAssert) -add_subdirectory(packages/EAStdC) -add_subdirectory(packages/EAMain) -add_subdirectory(packages/EATest) -add_subdirectory(packages/EAThread) - -target_link_libraries(EASTLTest EABase) -target_link_libraries(EASTLTest EAAssert) -target_link_libraries(EASTLTest EAMain) -target_link_libraries(EASTLTest EASTL) -target_link_libraries(EASTLTest EAStdC) -target_link_libraries(EASTLTest EATest) -target_link_libraries(EASTLTest EAThread) - -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) - -if((NOT APPLE) AND (NOT WIN32)) - target_link_libraries(EASTLTest ${EASTLTest_Libraries} Threads::Threads rt) -else() - target_link_libraries(EASTLTest ${EASTLTest_Libraries} Threads::Threads) -endif() - -#------------------------------------------------------------------------------------------- -# Run Unit tests and verify the results. -#------------------------------------------------------------------------------------------- -add_test(EASTLTestRuns EASTLTest) -set_tests_properties (EASTLTestRuns PROPERTIES PASS_REGULAR_EXPRESSION "RETURNCODE=0") - diff --git a/test/packages/EAAssert b/test/packages/EAAssert deleted file mode 160000 -Subproject e5e181255de2e883dd1f987c78ccc42ac81d3bc diff --git a/test/packages/EABase b/test/packages/EABase deleted file mode 160000 -Subproject af4ae274795f4c40829428a2c4058c6f512530f diff --git a/test/packages/EAMain b/test/packages/EAMain deleted file mode 160000 -Subproject 24ca8bf09e6b47b860286fc2f4c832f4009273d diff --git a/test/packages/EAStdC b/test/packages/EAStdC deleted file mode 160000 -Subproject 8dc9e314fdbe09d0627c613ae2eb6543859e995 diff --git a/test/packages/EATest b/test/packages/EATest deleted file mode 160000 -Subproject a59b372fc9cba517283ad6d060d2ab96e0ba34a diff --git a/test/packages/EAThread b/test/packages/EAThread deleted file mode 160000 -Subproject e4367a36f2e55d10b2b994bfbae8edf21f15baf diff --git a/test/source/ConceptImpls.h b/test/source/ConceptImpls.h deleted file mode 100644 index e6c20ef..0000000 --- a/test/source/ConceptImpls.h +++ /dev/null @@ -1,192 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#ifndef CONCEPTSIMPLS_H -#define CONCEPTSIMPLS_H - -#include <EASTL/type_traits.h> - -#if !defined(EA_COMPILER_NO_DEFAULTED_FUNCTIONS) && !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) - -#define EASTL_TEST_CONCEPT_IMPLS - -// This header provides a variety of helper classes that have interfaces corresponding to the concepts used to specify -// requirements of many STL containers and algorithms. These helper classes are used in tests to verify that containers -// and algorithms do not impose stricter requirements than specified by the standard on their arguments. - -// Destructible - only valid operation on this class is to destroy it. - -class Destructible -{ -public: - ~Destructible() = default; - - Destructible() = delete; - Destructible(const Destructible&) = delete; - Destructible(Destructible&&) = delete; - Destructible& operator=(const Destructible&) = delete; - Destructible& operator=(Destructible&&) = delete; -}; - -// Unfortunately not all compilers handle type_traits reliably correctly currently so we can't straightforwardly -// static_assert everything that should be true of this class -static_assert(eastl::is_destructible<Destructible>::value, "eastl::is_destructible<Destructible>::value"); -// static_assert(!eastl::is_default_constructible<Destructible>::value, -// "!eastl::is_default_constructible<Destructible>::value"); -// static_assert(!is_copy_constructible<Destructible>::value, "!eastl::is_copy_constructible<Destructible>::value"); -static_assert(!eastl::is_copy_assignable<Destructible>::value, "!eastl::is_copy_assignable<Destructible>::value"); -// static_assert(!eastl::is_move_constructible<Destructible>::value, -// "!eastl::is_move_constructible<Destructible>::value"); -static_assert(!eastl::is_move_assignable<Destructible>::value, "!eastl::is_move_assignable<Destructible>::value"); - -class DefaultConstructible -{ -public: - static const int defaultValue = 42; - - DefaultConstructible() : value(defaultValue) {} - ~DefaultConstructible() = default; - - DefaultConstructible(const DefaultConstructible&) = delete; - DefaultConstructible(DefaultConstructible&&) = delete; - DefaultConstructible& operator=(const DefaultConstructible&) = delete; - DefaultConstructible& operator=(DefaultConstructible&&) = delete; - - const int value; -}; - - -struct NotDefaultConstructible -{ - NotDefaultConstructible() = delete; -}; -static_assert(!eastl::is_default_constructible<NotDefaultConstructible>::value, "'NotDefaultConstructible' is default constructible."); - - -class CopyConstructible -{ -public: - static const int defaultValue = 42; - static CopyConstructible Create() - { - CopyConstructible x; - return x; - } - - CopyConstructible(const CopyConstructible&) = default; - ~CopyConstructible() = default; - - CopyConstructible& operator=(const CopyConstructible&) = delete; - CopyConstructible& operator=(CopyConstructible&&) = delete; - - const int value; - -private: - CopyConstructible() : value(defaultValue) {} -}; - -// Unfortunately not all compilers handle type_traits reliably correctly currently so we can't straightforwardly -// static_assert everything that should be true of this class -static_assert(eastl::is_destructible<CopyConstructible>::value, "eastl::is_destructible<CopyConstructible>::value"); -// static_assert(!eastl::is_default_constructible<CopyConstructible>::value, -// "!eastl::is_default_constructible<CopyConstructible>::value"); -// static_assert(is_copy_constructible<CopyConstructible>::value, "is_copy_constructible<CopyConstructible>::value"); -static_assert(eastl::is_copy_constructible<CopyConstructible>::value, - "eastl::is_copy_constructible<CopyConstructible>::value"); -static_assert(!eastl::is_copy_assignable<CopyConstructible>::value, - "!eastl::is_copy_assignable<CopyConstructible>::value"); -// static_assert(!eastl::is_move_constructible<CopyConstructible>::value, -// "!eastl::is_move_constructible<CopyConstructible>::value"); -static_assert(!eastl::is_move_assignable<CopyConstructible>::value, - "!eastl::is_move_assignable<CopyConstructible>::value"); - -class MoveConstructible -{ -public: - static const int defaultValue = 42; - static MoveConstructible Create() - { - return MoveConstructible{}; - } - - MoveConstructible(MoveConstructible&& x) : value(x.value) {} - ~MoveConstructible() = default; - - MoveConstructible(const MoveConstructible&) = delete; - MoveConstructible& operator=(const MoveConstructible&) = delete; - MoveConstructible& operator=(MoveConstructible&&) = delete; - - const int value; - -private: - MoveConstructible() : value(defaultValue) {} -}; - -class MoveAssignable -{ -public: - static const int defaultValue = 42; - static MoveAssignable Create() - { - return MoveAssignable{}; - } - - MoveAssignable(MoveAssignable&& x) : value(x.value) {} - MoveAssignable& operator=(MoveAssignable&& x) - { - value = x.value; - return *this; - } - ~MoveAssignable() = default; - - MoveAssignable(const MoveAssignable&) = delete; - MoveAssignable& operator=(const MoveAssignable&) = delete; - - int value; - -private: - MoveAssignable() : value(defaultValue) {} -}; - -struct MoveAndDefaultConstructible -{ - static const int defaultValue = 42; - - MoveAndDefaultConstructible() : value(defaultValue) {} - MoveAndDefaultConstructible(MoveAndDefaultConstructible&& x) : value(x.value) {} - ~MoveAndDefaultConstructible() = default; - - MoveAndDefaultConstructible(const MoveAndDefaultConstructible&) = delete; - MoveAndDefaultConstructible& operator=(const MoveAndDefaultConstructible&) = delete; - MoveAndDefaultConstructible& operator=(MoveAndDefaultConstructible&&) = delete; - - const int value; -}; - -struct MissingMoveConstructor -{ - MissingMoveConstructor() {} - MissingMoveConstructor(const MissingMoveConstructor&) {} - MissingMoveConstructor& operator=(MissingMoveConstructor&&) { return *this; } - MissingMoveConstructor& operator=(const MissingMoveConstructor&) { return *this; } - bool operator<(const MissingMoveConstructor&) const { return true; } -}; - -struct MissingMoveAssignable -{ - MissingMoveAssignable() {} - MissingMoveAssignable(const MissingMoveAssignable&) {} - MissingMoveAssignable(MissingMoveAssignable&&) {} - MissingMoveAssignable& operator=(const MissingMoveAssignable&) { return *this; } - bool operator<(const MissingMoveAssignable&) const { return true; } -}; - -struct MissingEquality -{ - MissingEquality& operator==(const MissingEquality&) = delete; -}; - -#endif // !defined(EA_COMPILER_NO_DEFAULTED_FUNCTIONS) && !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) - -#endif // CONCEPTSIMPLS_H diff --git a/test/source/EASTLTest.cpp b/test/source/EASTLTest.cpp deleted file mode 100644 index 389de4c..0000000 --- a/test/source/EASTLTest.cpp +++ /dev/null @@ -1,273 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include <EABase/eabase.h> -#include <EASTL/version.h> - -#ifdef _MSC_VER - #pragma warning(push, 0) -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <new> -#if !defined(EA_COMPILER_NO_STANDARD_CPP_LIBRARY) - #include <vector> // Used to detect the C++ Standard Library version. -#endif - -#ifndef EA_PLATFORM_PLAYSTSATION2 - #include <wchar.h> -#endif -#if defined(EA_PLATFORM_WINDOWS) - #include <Windows.h> -#elif defined(EA_PLATFORM_ANDROID) - #include <android/log.h> -#endif -#if defined(_MSC_VER) && defined(EA_PLATFORM_MICROSOFT) - #include <crtdbg.h> -#endif - - -#ifdef _MSC_VER - #pragma warning(pop) -#endif - - -#include "EASTLTestAllocator.h" -#include "EASTLTest.h" // Include this last, as it enables compiler warnings. - -/////////////////////////////////////////////////////////////////////////////// -// init_seg -// -#ifdef _MSC_VER - // Set initialization order between init_seg(compiler) (.CRT$XCC) and - // init_seg(lib) (.CRT$XCL). The linker sorts the .CRT sections - // alphabetically so we simply need to pick a name that is between - // XCC and XCL. - #pragma warning(disable: 4075) // warning C4075: initializers put in unrecognized initialization area - #pragma init_seg(".CRT$XCF") -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// EA_INIT_PRIORITY -// -// This is simply a wrapper for the GCC init_priority attribute that allows -// multiplatform code to be easier to read. -// -// Example usage: -// SomeClass gSomeClass EA_INIT_PRIORITY(2000); -// -#if !defined(EA_INIT_PRIORITY) - #if defined(__GNUC__) - #define EA_INIT_PRIORITY(x) __attribute__ ((init_priority (x))) - #else - #define EA_INIT_PRIORITY(x) - #endif -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// TestObject -// -int64_t TestObject::sTOCount = 0; -int64_t TestObject::sTOCtorCount = 0; -int64_t TestObject::sTODtorCount = 0; -int64_t TestObject::sTODefaultCtorCount = 0; -int64_t TestObject::sTOArgCtorCount = 0; -int64_t TestObject::sTOCopyCtorCount = 0; -int64_t TestObject::sTOMoveCtorCount = 0; -int64_t TestObject::sTOCopyAssignCount = 0; -int64_t TestObject::sTOMoveAssignCount = 0; -int TestObject::sMagicErrorCount = 0; - - -/////////////////////////////////////////////////////////////////////////////// -// MallocAllocator -// -int MallocAllocator::mAllocCountAll = 0; -int MallocAllocator::mFreeCountAll = 0; -size_t MallocAllocator::mAllocVolumeAll = 0; -void* MallocAllocator::mpLastAllocation = NULL; - - -/////////////////////////////////////////////////////////////////////////////// -// InstanceAllocator -// -int InstanceAllocator::mMismatchCount = 0; - - -/////////////////////////////////////////////////////////////////////////////// -// CountingAllocator -// -uint64_t CountingAllocator::activeAllocCount = 0; -uint64_t CountingAllocator::totalAllocCount = 0; -uint64_t CountingAllocator::totalDeallocCount = 0; -uint64_t CountingAllocator::totalCtorCount = 0; -uint64_t CountingAllocator::defaultCtorCount = 0; -uint64_t CountingAllocator::copyCtorCount = 0; -uint64_t CountingAllocator::assignOpCount = 0; -uint64_t CountingAllocator::totalAllocatedMemory = 0; -uint64_t CountingAllocator::activeAllocatedMemory = 0; - - -/////////////////////////////////////////////////////////////////////////////// -// gEASTL_TestLevel -// -int gEASTL_TestLevel = 0; - - -/////////////////////////////////////////////////////////////////////////////// -// EASTLTest_CheckMemory_Imp -// -int EASTLTest_CheckMemory_Imp(const char* pFile, int nLine) -{ - int nErrorCount(0); - bool bMemoryOK(true); - - #if defined(_DEBUG) && (defined(EA_COMPILER_MSVC) && defined(EA_PLATFORM_MICROSOFT)) - if(!_CrtCheckMemory()) - bMemoryOK = false; - #endif - - #ifdef EA_DEBUG - if(!EASTLTest_ValidateHeap()) - bMemoryOK = false; - #endif - - if(!bMemoryOK) - { - nErrorCount++; - EASTLTest_Printf("Memory check failure:\n%s: line %d\n\n", pFile, nLine); - } - - return nErrorCount; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// GetStdSTLType -// -StdSTLType GetStdSTLType() -{ - #if defined(_STLPORT_VERSION) - return kSTLPort; // Descendent of the old HP / SGI STL. - #elif defined(_RWSTD_VER_STR) - return kSTLApache; // a.k.a. Rogue Wave, which is a descendent of the old HP / SGI STL. - #elif defined(_CPPLIB_VER) - return kSTLDinkumware; // Indicated by the presence of the central yvals.h header. - #elif defined(_LIBCPP_VECTOR) - return kSTLClang; - #elif defined(_GLIBCXX_VECTOR) - return kSTLGCC; // a.k.a. libstdc++ - #elif defined(_MSC_VER) - return kSTLMS; // This is a tweaked version of Dinkumware. - #else - return kSTLUnknown; - #endif -} - - - -/////////////////////////////////////////////////////////////////////////////// -// GetStdSTLName -// -const char* GetStdSTLName() -{ - // We may need to tweak this function over time. - // Theoretically it is possible to have multiple standard - // STL versions active, as some of them have options to - // put themselves in different namespaces. - - // Tests for specific STL versions directly. - #if defined(_STLPORT_VERSION) - return "STLPort"; - #elif defined(__SGI_STL_VECTOR) - return "SGI"; - #elif defined(_RWSTD_VER_STR) - return "Apache"; - - // Tests for specific platforms that have specific STL versions. - #elif defined(EA_PLATFORM_SONY) - return "Sony Dinkumware"; - - // Special case for Dinkumware. - #elif defined(_CPPLIB_VER) - #if defined(_MSC_VER) - return "VC++ Dinkumware"; - #else - return "Dinkumware"; - #endif - - // Tests for specific compilers as a fallback. - #elif defined(_MSC_VER) - return "VC++ ???"; - #elif defined(_LIBCPP_VECTOR) - return "clang libc++"; - #elif defined(__GNUC__) || defined(_GLIBCXX_VECTOR) - return "GCC (or emulated GCC) libstdc++"; - #else - #error Need to be able to identify the standard STL version. - #endif -} - - - -/////////////////////////////////////////////////////////////////////////////// -// MallocAllocator -/////////////////////////////////////////////////////////////////////////////// - -// The following function is defined here instead of in the header because GCC -// generates a bogus warning about freeing a non-heap pointer when this function -// is declared inline. - -void MallocAllocator::deallocate(void *p, size_t n) -{ - ++mFreeCount; - mAllocVolume -= n; - ++mFreeCountAll; - mAllocVolumeAll -= n; - - return free(p); -} - -void* MallocAllocator::allocate(size_t n, int) -{ - ++mAllocCount; mAllocVolume += n; ++mAllocCountAll; mAllocVolumeAll += n; mpLastAllocation = malloc(n); return mpLastAllocation; -} - -void* MallocAllocator::allocate(size_t n, size_t, size_t, int) -{ - ++mAllocCount; mAllocVolume += n; ++mAllocCountAll; mAllocVolumeAll += n; mpLastAllocation = malloc(n); return mpLastAllocation; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// CustomAllocator -/////////////////////////////////////////////////////////////////////////////// - -void* CustomAllocator::allocate(size_t n, int flags) -{ - return ::operator new[](n, get_name(), flags, 0, __FILE__, __LINE__); -} - -void* CustomAllocator::allocate(size_t n, size_t alignment, size_t offset, int flags) -{ - return ::operator new[](n, alignment, offset, get_name(), flags, 0, __FILE__, __LINE__); -} - -void CustomAllocator::deallocate(void* p, size_t /*n*/) -{ - ::operator delete((char*)p); -} - - - - - - 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 - - - - - - - diff --git a/test/source/EASTLTestAllocator.cpp b/test/source/EASTLTestAllocator.cpp deleted file mode 100644 index 0f03d8a..0000000 --- a/test/source/EASTLTestAllocator.cpp +++ /dev/null @@ -1,492 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#ifndef EASTLTEST_ALLOCATOR_H -#define EASTLTEST_ALLOCATOR_H - -#include <EABase/eabase.h> -#include <EASTL/internal/config.h> -#include <new> -#include <stdio.h> - -#if !EASTL_OPENSOURCE - - #include <PPMalloc/EAGeneralAllocator.h> - #include <PPMalloc/EAGeneralAllocatorDebug.h> - - #include <coreallocator/icoreallocator_interface.h> - - #if defined(EA_COMPILER_MSVC) - #include <math.h> // VS2008 has an acknowledged bug that requires math.h (and possibly also string.h) to be #included before intrin.h. - #include <intrin.h> - #pragma intrinsic(_ReturnAddress) - #endif - - /////////////////////////////////////////////////////////////////////////////// - // EASTLTest_GetGeneralAllocator() - // - namespace EA - { - namespace Allocator - { - #ifdef EA_DEBUG - extern PPM_API GeneralAllocatorDebug* gpEAGeneralAllocatorDebug; - #else - extern PPM_API GeneralAllocator* gpEAGeneralAllocator; - #endif - - static inline auto& EASTLTest_GetGeneralAllocator() - { - #ifdef EA_DEBUG - using GeneralAllocatorType = GeneralAllocatorDebug; - #else - using GeneralAllocatorType = GeneralAllocator; - #endif - - static GeneralAllocatorType sGeneralAllocator; - return sGeneralAllocator; - } - } - } - - - /////////////////////////////////////////////////////////////////////////////// - // allocator counts for debugging purposes - // - int gEASTLTest_AllocationCount = 0; - int gEASTLTest_TotalAllocationCount = 0; - - - /////////////////////////////////////////////////////////////////////////////// - // EASTLTest_ValidateHeap - // - bool EASTLTest_ValidateHeap() - { - #ifdef EA_DEBUG - return EA::Allocator::EASTLTest_GetGeneralAllocator().ValidateHeap(EA::Allocator::GeneralAllocator::kHeapValidationLevelBasic); - #else - return true; - #endif - } - - - /////////////////////////////////////////////////////////////////////////////// - // Microsoft function parameter annotations - // https://msdn.microsoft.com/en-CA/library/hh916382.aspx - // - #ifndef _Ret_maybenull_ - #define _Ret_maybenull_ - #endif - - #ifndef _Post_writable_byte_size_ - #define _Post_writable_byte_size_(x) - #endif - - #ifndef _Ret_notnull_ - #define _Ret_notnull_ - #endif - - - /////////////////////////////////////////////////////////////////////////////// - // operator new extensions - // - namespace - { - #ifdef EA_DEBUG - const char gUnattributedNewTag[] = "Anonymous new"; - #endif - - #if defined(EA_COMPILER_MSVC) - #define UNATTRIBUTED_NEW_FILE "raw_return_address" - #define UNATTRIBUTED_NEW_LINE ((int)(uintptr_t)_ReturnAddress()) - #else - #define UNATTRIBUTED_NEW_FILE NULL - #define UNATTRIBUTED_NEW_LINE 0 - #endif - } - - /////////////////////////////////////////////////////////////////////////////// - // system memory allocation helpers - // - namespace - { - void* PlatformMalloc(size_t size, size_t alignment = 16) - { - #ifdef EA_PLATFORM_MICROSOFT - return _aligned_malloc(size, alignment); - #else - void *p = nullptr; - alignment = alignment < sizeof( void *) ? sizeof( void *) : alignment; - posix_memalign(&p, alignment, size); - return p; - #endif - } - - void PlatformFree(void* p) - { - #ifdef EA_PLATFORM_MICROSOFT - _aligned_free(p); - #else - free(p); - #endif - } - - void* InternalMalloc(size_t size) - { - void* mem = nullptr; - - auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator(); - - #ifdef EA_DEBUG - mem = allocator.MallocDebug(size, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE); - #else - mem = allocator.Malloc(size); - #endif - - if(mem == nullptr) - mem = PlatformMalloc(size); - - return mem; - } - - void* InternalMalloc(size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line) - { - void* mem = nullptr; - - auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator(); - - #ifdef EA_DEBUG - mem = allocator.MallocDebug(size, flags, debugFlags, name, file, line); - #else - mem = allocator.Malloc(size, flags); - EA_UNUSED(debugFlags); - EA_UNUSED(file); - EA_UNUSED(line); - EA_UNUSED(name); - #endif - - if(mem == nullptr) - mem = PlatformMalloc(size); - - return mem; - } - - void* InternalMalloc(size_t size, size_t alignment, const char* name, int flags, unsigned debugFlags, const char* file, int line) - { - void* mem = nullptr; - - auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator(); - - #ifdef EA_DEBUG - mem = allocator.MallocAlignedDebug(size, alignment, 0, flags, debugFlags, name, file, line); - #else - mem = allocator.MallocAligned(size, alignment, flags); - EA_UNUSED(debugFlags); - EA_UNUSED(file); - EA_UNUSED(line); - EA_UNUSED(name); - #endif - - if(mem == nullptr) - mem = PlatformMalloc(size, alignment); - - return mem; - } - - void* InternalMalloc(size_t size, size_t alignment) - { - void* mem = nullptr; - - auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator(); - - #ifdef EA_DEBUG - mem = allocator.MallocAlignedDebug(size, alignment, 0, 0, 0, gUnattributedNewTag, UNATTRIBUTED_NEW_FILE, UNATTRIBUTED_NEW_LINE); - #else - mem = allocator.MallocAligned(size, alignment); - #endif - - if(mem == nullptr) - mem = PlatformMalloc(size, alignment); - - return mem; - } - - void InternalFree(void* p) - { - auto& allocator = EA::Allocator::EASTLTest_GetGeneralAllocator(); - - if(allocator.ValidateAddress(p, EA::Allocator::GeneralAllocator::kAddressTypeOwned) == p) - { - allocator.Free(p); - } - else - { - PlatformFree(p); - } - } - } - - class EASTLTestICA : public EA::Allocator::ICoreAllocator - { - public: - EASTLTestICA() - { - } - - virtual ~EASTLTestICA() - { - } - - virtual void* Alloc(size_t size, const char* name, unsigned int flags) - { - return ::InternalMalloc(size, name, (int)flags, 0, NULL, 0); - } - - virtual void* Alloc(size_t size, const char* name, unsigned int flags, - unsigned int align, unsigned int) - { - return ::InternalMalloc(size, (size_t)align, name, (int)flags, 0, NULL, 0); - } - - virtual void Free(void* pData, size_t /*size*/) - { - return ::InternalFree(pData); - } - }; - - EA::Allocator::ICoreAllocator* EA::Allocator::ICoreAllocator::GetDefaultAllocator() - { - static EASTLTestICA sEASTLTestICA; - - return &sEASTLTestICA; - } - - /////////////////////////////////////////////////////////////////////////// - // operator new/delete implementations - // - _Ret_maybenull_ _Post_writable_byte_size_(size) void* operator new(size_t size, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE() - { - return InternalMalloc(size); - } - - - void operator delete(void* p, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE() - { - if(p) // The standard specifies that 'delete NULL' is a valid operation. - { - gEASTLTest_AllocationCount--; - InternalFree(p); - } - } - - - _Ret_maybenull_ _Post_writable_byte_size_(size) void* operator new[](size_t size, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE() - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - void* p = InternalMalloc(size); - return p; - } - - - void operator delete[](void* p, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE() - { - if(p) - { - gEASTLTest_AllocationCount--; - InternalFree(p); - } - } - - - _Ret_notnull_ _Post_writable_byte_size_(size) void* operator new(size_t size) - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - void* mem = InternalMalloc(size); - - #if !defined(EA_COMPILER_NO_EXCEPTIONS) - if (mem == NULL) - { - throw std::bad_alloc(); - } - #endif - - return mem; - } - - - _Ret_notnull_ _Post_writable_byte_size_(size) void* operator new[](size_t size) - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - void* mem = InternalMalloc(size); - - #if !defined(EA_COMPILER_NO_EXCEPTIONS) - if (mem == NULL) - { - throw std::bad_alloc(); - } - #endif - - return mem; - } - - - void* operator new[](size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line) - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - return InternalMalloc(size, name, flags, debugFlags, file, line); - } - - - void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* name, int flags, unsigned debugFlags, const char* file, int line) - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - return InternalMalloc(size, alignment, name, flags, debugFlags, file, line); - } - - // Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler). - void* operator new(size_t size, size_t alignment) - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - return InternalMalloc(size, alignment); - } - - // Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler). - void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE() - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - return InternalMalloc(size, alignment); - } - - // Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler). - void* operator new[](size_t size, size_t alignment) - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - return InternalMalloc(size, alignment); - } - - // Used by GCC when you make new objects of classes with >= N bit alignment (with N depending on the compiler). - void* operator new[](size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE() - { - gEASTLTest_AllocationCount++; - gEASTLTest_TotalAllocationCount++; - - return InternalMalloc(size, alignment); - } - - void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE() - { - if(p) // The standard specifies that 'delete NULL' is a valid operation. - { - gEASTLTest_AllocationCount--; - InternalFree(p); - } - } - - - void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE() - { - if(p) - { - gEASTLTest_AllocationCount--; - InternalFree(p); - } - } - - void EASTLTest_SetGeneralAllocator() - { - EA::Allocator::SetGeneralAllocator(&EA::Allocator::EASTLTest_GetGeneralAllocator()); - #ifdef EA_DEBUG - EA::Allocator::gpEAGeneralAllocatorDebug->SetDefaultDebugDataFlag(EA::Allocator::GeneralAllocatorDebug::kDebugDataIdGuard); - #endif - } - -#else - #if !defined(EA_PLATFORM_MICROSOFT) || defined(EA_PLATFORM_MINGW) - #include <stdlib.h> - #endif - - namespace Internal - { - void* EASTLAlignedAlloc(size_t size, size_t alignment) - { - #ifdef EA_PLATFORM_MICROSOFT - return _aligned_malloc(size, alignment); - #else - void *p = nullptr; - alignment = alignment < sizeof( void *) ? sizeof( void *) : alignment; - posix_memalign(&p, alignment, size); - return p; - #endif - } - - void EASTLAlignedFree(void* p) - { - #ifdef EA_PLATFORM_MICROSOFT - _aligned_free(p); - #else - free(p); - #endif - } - } - - void* operator new(size_t size) - { return Internal::EASTLAlignedAlloc(size, 16); } - - void* operator new[](size_t size) - { return Internal::EASTLAlignedAlloc(size, 16); } - - void* operator new[](size_t size, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/) - { return Internal::EASTLAlignedAlloc(size, 16); } - - void* operator new[](size_t size, size_t alignment, size_t /*alignmentOffset*/, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/) - { return Internal::EASTLAlignedAlloc(size, alignment); } - - void* operator new(size_t size, size_t alignment) - { return Internal::EASTLAlignedAlloc(size, alignment); } - - void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE() - { return Internal::EASTLAlignedAlloc(size, alignment); } - - void* operator new[](size_t size, size_t alignment) - { return Internal::EASTLAlignedAlloc(size, alignment); } - - void* operator new[](size_t size, size_t alignment, const std::nothrow_t&)EA_THROW_SPEC_NEW_NONE() - { return Internal::EASTLAlignedAlloc(size, alignment); } - - // C++14 deleter - void operator delete(void* p, std::size_t sz ) EA_THROW_SPEC_DELETE_NONE() - { Internal::EASTLAlignedFree(p); EA_UNUSED(sz); } - - void operator delete[](void* p, std::size_t sz ) EA_THROW_SPEC_DELETE_NONE() - { Internal::EASTLAlignedFree(p); EA_UNUSED(sz); } - - void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE() - { Internal::EASTLAlignedFree(p); } - - void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE() - { Internal::EASTLAlignedFree(p); } - - void EASTLTest_SetGeneralAllocator() { /* intentionally blank */ } - bool EASTLTest_ValidateHeap() { return true; } - -#endif // !EASTL_OPENSOURCE - -#endif // Header include guard diff --git a/test/source/EASTLTestAllocator.h b/test/source/EASTLTestAllocator.h deleted file mode 100644 index 775aff6..0000000 --- a/test/source/EASTLTestAllocator.h +++ /dev/null @@ -1,26 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#ifndef EASTLTEST_ALLOCATOR_H -#define EASTLTEST_ALLOCATOR_H - -#include <EABase/eabase.h> -#include <new> - - void* operator new(size_t size); - void* operator new[](size_t size); - void* operator new[](size_t size, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/); - void* operator new[](size_t size, size_t alignment, size_t /*alignmentOffset*/, const char* /*name*/, int /*flags*/, unsigned /*debugFlags*/, const char* /*file*/, int /*line*/); - void* operator new(size_t size, size_t alignment); - void* operator new(size_t size, size_t alignment, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE(); - void* operator new[](size_t size, size_t alignment); - void* operator new[](size_t size, size_t alignment, const std::nothrow_t&)EA_THROW_SPEC_NEW_NONE(); - void operator delete(void* p) EA_THROW_SPEC_DELETE_NONE(); - void operator delete[](void* p) EA_THROW_SPEC_DELETE_NONE(); - void EASTLTest_SetGeneralAllocator(); - bool EASTLTest_ValidateHeap(); - - -#endif // Header include guard diff --git a/test/source/GetTypeName.h b/test/source/GetTypeName.h deleted file mode 100644 index f844167..0000000 --- a/test/source/GetTypeName.h +++ /dev/null @@ -1,119 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#ifndef GETTYPENAME_H -#define GETTYPENAME_H - - -#include <EABase/eabase.h> -#include <EASTL/type_traits.h> -#include <EASTL/string.h> -#include <stdlib.h> -#include <typeinfo> - - -/////////////////////////////////////////////////////////////////////////////// -// EASTL_LIBSTDCPP_DEMANGLE_AVAILABLE -// -// Defined as 0 or 1. The value depends on the compilation environment. -// Indicates if we can use system-provided abi::__cxa_demangle() at runtime. -// -#if !defined(EASTL_LIBSTDCPP_DEMANGLE_AVAILABLE) - #if (defined(EA_PLATFORM_LINUX) || defined(EA_PLATFORM_APPLE)) && defined(EA_PLATFORM_DESKTOP) - #define EASTL_LIBSTDCPP_DEMANGLE_AVAILABLE 1 - #else - #define EASTL_LIBSTDCPP_DEMANGLE_AVAILABLE 0 - #endif -#endif - - -#if EASTL_LIBSTDCPP_DEMANGLE_AVAILABLE - #include <cxxabi.h> -#elif EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_DESKTOP) - EA_DISABLE_ALL_VC_WARNINGS(); - #include <Windows.h> - #include <DbgHelp.h> - #pragma comment(lib, "dbghelp.lib") - EA_RESTORE_ALL_VC_WARNINGS(); -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// EASTLTEST_GETTYPENAME_AVAILABLE -// -// Defined as 0 or 1. The value depends on the compilation environment. -// Indicates if we can use system-provided abi::__cxa_demangle() at runtime. -// -#if !defined(EASTLTEST_GETTYPENAME_AVAILABLE) - #if (EASTL_LIBSTDCPP_DEMANGLE_AVAILABLE || EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_DESKTOP)) && (!defined(EA_COMPILER_NO_RTTI) || defined(_MSC_VER)) // VC++ works without RTTI enabled. - #define EASTLTEST_GETTYPENAME_AVAILABLE 1 - #else - #define EASTLTEST_GETTYPENAME_AVAILABLE 0 - #endif -#endif - - -/// GetTypeName -/// -/// Returns the type name of a templated type. -/// -template <typename T> -eastl::string GetTypeName() -{ - eastl::string result; - - #if !defined(EA_COMPILER_NO_RTTI) || defined(_MSC_VER) // VC++ works without RTTI enabled. - typedef typename eastl::remove_reference<T>::type TR; - - const char* pName = typeid(TR).name(); - - #if EASTL_LIBSTDCPP_DEMANGLE_AVAILABLE - const char* pDemangledName = abi::__cxa_demangle(pName, NULL, NULL, NULL); - - #elif EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_DESKTOP) - char pDemangledName[1024]; - DWORD count = UnDecorateSymbolName(pName, pDemangledName, (DWORD)EAArrayCount(pDemangledName), UNDNAME_NO_THISTYPE | UNDNAME_NO_ACCESS_SPECIFIERS | UNDNAME_NO_MEMBER_TYPE); - if(count == 0) - pDemangledName[0] = 0; - #else - const char* pDemangledName = NULL; - #endif - - if(pDemangledName && pDemangledName[0]) - result = pDemangledName; - else - result = pName; - - if(eastl::is_const<TR>::value) - result += " const"; - - if(eastl::is_volatile<TR>::value) - result += " volatile"; - - if(eastl::is_lvalue_reference<T>::value) - result += "&"; - else if(eastl::is_rvalue_reference<T>::value) - result += "&&"; - - if(pDemangledName) - { - #if EASTL_LIBSTDCPP_DEMANGLE_AVAILABLE - free((void*)(pDemangledName)); - #endif - } - #endif - - return result; -} - - -#endif // Header include guard - - - - - - - diff --git a/test/source/TestAlgorithm.cpp b/test/source/TestAlgorithm.cpp deleted file mode 100644 index a0f64da..0000000 --- a/test/source/TestAlgorithm.cpp +++ /dev/null @@ -1,2761 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#if defined(_MSC_VER) - // We have little choice but to disable this warning. See the FAQ for why. - #pragma warning(disable: 4244) // conversion from '___' to '___', possible loss of data -#endif - - -#include <EASTL/algorithm.h> -#include <EASTL/functional.h> -#include <EASTL/unique_ptr.h> -#include <EASTL/vector.h> -#include <EASTL/array.h> -#include <EASTL/deque.h> -#include <EASTL/list.h> -#include <EASTL/slist.h> -#include <EASTL/string.h> -#include <EASTL/set.h> -#include <EASTL/sort.h> -#include "ConceptImpls.h" -#include <EAStdC/EAMemory.h> -#include "EASTLTest.h" // Put this after the above so that it doesn't block any warnings from the includes above. - -namespace eastl -{ - #if 0 - // These are some tests of altermative implementations of branch-free min/max functions. - /* - union FloatInt32Union - { - float f; - int32_t i; - }; - - inline float min_alt2(float a, float b) - { - FloatInt32Union uc; - uc.f = a - b; - - const float choices[2] = { a, b }; - return (choices + 1)[uc.i >> 31]; - } - - inline float min_alt3(float a, float b) - { - FloatInt32Union uc, ua, ub, ur; - - uc.f = a - b; - uc.i >>= 31; - ua.f = a; - ub.f = b; - ur.i = (ua.i & uc.i) | (ub.i & ~uc.i); - - return ur.f; - } - */ - #endif -} - - -namespace -{ - struct A{ - A(int n) : a(n){} - int a; - }; - struct LessStruct{ bool operator()(const A& a1, const A& a2){ return a1.a < a2.a; } }; - - - struct B{ - B(int n) : b(n){} - int b; - }; - inline bool LessFunction(const B& b1, const B& b2){ return b1.b < b2.b; } -} - -enum TestMinMaxEnum -{ - teX = 0, - teY = 3 -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Greater -// -// A version of greater that uses operator < instead of operator >. -// -template <typename T> -struct Greater : public eastl::binary_function<T, T, bool> -{ - bool operator()(const T& a, const T& b) const - { return (b < a); } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// DivisibleBy -// -struct DivisibleBy -{ - int d; - DivisibleBy(int n = 1) : d(n) {} - bool operator()(int n) const { return ((n % d) == 0); } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// TestObjectNegate -// -struct TestObjectNegate : public eastl::unary_function<TestObject, TestObject> -{ - TestObject operator()(const TestObject& a) const - { return TestObject(-a.mX); } -}; - -static int TestMinMax() -{ - using namespace eastl; - - int nErrorCount = 0; - - EA::UnitTest::Rand rng(EA::UnitTest::GetRandSeed()); - - { - // NOTE(rparolin): This compiles but it should not. We provide explicit eastl::max overloads for float, double, - // and long double which enable this behaviour. It is not standards compliant and it will be removed in a - // future release. - { - struct Foo - { - operator float() const { return 0; } - }; - - Foo f1; - float f2{}; - eastl::max(f1, f2); - } - - // NOTE(rparolin): This will not compile because we lack explicit eastl::max overloads for 'int'. - // { - // struct Foo - // { - // operator int() const { return 0; } - // }; - - // Foo f1; - // int f2{}; - // eastl::max(f1, f2); - // } - } - - { - // const T& min(const T& a, const T& b); - // const T& min(const T& a, const T& b, Compare compare) - // const T& max(const T& a, const T& b); - // const T& max(const T& a, const T& b, Compare compare) - - A a1(1), a2(2), a3(3); - a3 = min(a1, a2, LessStruct()); - EATEST_VERIFY(a3.a == 1); - a3 = max(a1, a2, LessStruct()); - EATEST_VERIFY(a3.a == 2); - - B b1(1), b2(2), b3(3); - b3 = min(b2, b1, LessFunction); - EATEST_VERIFY(b3.b == 1); - b3 = max(b2, b1, LessFunction); - EATEST_VERIFY(b3.b == 2); - - - TestObject t1(1), t2(2), t3(3); - t3 = min(t2, t1); - EATEST_VERIFY(t3.mX == 1); - t3 = max(t2, t1); - EATEST_VERIFY(t3.mX == 2); - - - int i1, i2(-1), i3(1); - i1 = min(i2, i3); - EATEST_VERIFY(i1 == -1); - i1 = min(i3, i2); - EATEST_VERIFY(i1 == -1); - i1 = max(i2, i3); - EATEST_VERIFY(i1 == 1); - i1 = max(i3, i2); - EATEST_VERIFY(i1 == 1); - - const volatile int i2cv(-1), i3cv(1); - i1 = min(i2cv, i3cv); - EATEST_VERIFY(i1 == -1); - i1 = min(i3cv, i2cv); - EATEST_VERIFY(i1 == -1); - i1 = max(i2cv, i3cv); - EATEST_VERIFY(i1 == 1); - i1 = max(i3cv, i2cv); - EATEST_VERIFY(i1 == 1); - - float f1, f2(-1), f3(1); - f1 = min(f2, f3); - EATEST_VERIFY(f1 == -1); - f1 = min(f3, f2); - EATEST_VERIFY(f1 == -1); - f1 = max(f2, f3); - EATEST_VERIFY(f1 == 1); - f1 = max(f3, f2); - EATEST_VERIFY(f1 == 1); - - double d1, d2(-1), d3(1); - d1 = min(d2, d3); - EATEST_VERIFY(d1 == -1); - d1 = min(d3, d2); - EATEST_VERIFY(d1 == -1); - d1 = max(d2, d3); - EATEST_VERIFY(d1 == 1); - d1 = max(d3, d2); - EATEST_VERIFY(d1 == 1); - - void* p1, *p2 = &d2, *p3 = &d3; - p1 = min(p2, p3); - EATEST_VERIFY((uintptr_t)p1 == min((uintptr_t)p2, (uintptr_t)p3)); - - double* pd1, *pd2 = &d2, *pd3 = &d3; - pd1 = min(pd2, pd3); - EATEST_VERIFY((uintptr_t)pd1 == min((uintptr_t)pd2, (uintptr_t)pd3)); - - - // initializer_list tests - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - EATEST_VERIFY(min({ 3, 1, 2}) == 1); - EATEST_VERIFY(max({ 3, 1, 2}) == 3); - #endif - - - // Test scalar specializations - EATEST_VERIFY(min((char)1, (char)1) == 1); - EATEST_VERIFY(min((char)1, (char)2) == 1); - EATEST_VERIFY(min((char)2, (char)1) == 1); - - EATEST_VERIFY(min((signed char)1, (signed char)1) == 1); - EATEST_VERIFY(min((signed char)1, (signed char)2) == 1); - EATEST_VERIFY(min((signed char)2, (signed char)1) == 1); - - EATEST_VERIFY(min((unsigned char)1, (unsigned char)1) == 1); - EATEST_VERIFY(min((unsigned char)1, (unsigned char)2) == 1); - EATEST_VERIFY(min((unsigned char)2, (unsigned char)1) == 1); - - EATEST_VERIFY(min((signed short)1, (signed short)1) == 1); - EATEST_VERIFY(min((signed short)1, (signed short)2) == 1); - EATEST_VERIFY(min((signed short)2, (signed short)1) == 1); - - EATEST_VERIFY(min((unsigned short)1, (unsigned short)1) == 1); - EATEST_VERIFY(min((unsigned short)1, (unsigned short)2) == 1); - EATEST_VERIFY(min((unsigned short)2, (unsigned short)1) == 1); - - EATEST_VERIFY(min((signed int)1, (signed int)1) == 1); - EATEST_VERIFY(min((signed int)1, (signed int)2) == 1); - EATEST_VERIFY(min((signed int)2, (signed int)1) == 1); - - EATEST_VERIFY(min((unsigned int)1, (unsigned int)1) == 1); - EATEST_VERIFY(min((unsigned int)1, (unsigned int)2) == 1); - EATEST_VERIFY(min((unsigned int)2, (unsigned int)1) == 1); - - EATEST_VERIFY(min((signed long)1, (signed long)1) == 1); - EATEST_VERIFY(min((signed long)1, (signed long)2) == 1); - EATEST_VERIFY(min((signed long)2, (signed long)1) == 1); - - EATEST_VERIFY(min((unsigned long)1, (unsigned long)1) == 1); - EATEST_VERIFY(min((unsigned long)1, (unsigned long)2) == 1); - EATEST_VERIFY(min((unsigned long)2, (unsigned long)1) == 1); - - EATEST_VERIFY(min((signed long long)1, (signed long long)1) == 1); - EATEST_VERIFY(min((signed long long)1, (signed long long)2) == 1); - EATEST_VERIFY(min((signed long long)2, (signed long long)1) == 1); - - EATEST_VERIFY(min((unsigned long long)1, (unsigned long long)1) == 1); - EATEST_VERIFY(min((unsigned long long)1, (unsigned long long)2) == 1); - EATEST_VERIFY(min((unsigned long long)2, (unsigned long long)1) == 1); - - EATEST_VERIFY(min((float)1, (float)1) == 1); - EATEST_VERIFY(min((float)1, (float)2) == 1); - EATEST_VERIFY(min((float)2, (float)1) == 1); - - EATEST_VERIFY(min((double)1, (double)1) == 1); - EATEST_VERIFY(min((double)1, (double)2) == 1); - EATEST_VERIFY(min((double)2, (double)1) == 1); - - EATEST_VERIFY(min((long double)1, (long double)1) == 1); - EATEST_VERIFY(min((long double)1, (long double)2) == 1); - EATEST_VERIFY(min((long double)2, (long double)1) == 1); - - - // Test max specializations - EATEST_VERIFY(max((char)1, (char)1) == 1); - EATEST_VERIFY(max((char)1, (char)2) == 2); - EATEST_VERIFY(max((char)2, (char)1) == 2); - - EATEST_VERIFY(max((signed char)1, (signed char)1) == 1); - EATEST_VERIFY(max((signed char)1, (signed char)2) == 2); - EATEST_VERIFY(max((signed char)2, (signed char)1) == 2); - - EATEST_VERIFY(max((unsigned char)1, (unsigned char)1) == 1); - EATEST_VERIFY(max((unsigned char)1, (unsigned char)2) == 2); - EATEST_VERIFY(max((unsigned char)2, (unsigned char)1) == 2); - - EATEST_VERIFY(max((signed short)1, (signed short)1) == 1); - EATEST_VERIFY(max((signed short)1, (signed short)2) == 2); - EATEST_VERIFY(max((signed short)2, (signed short)1) == 2); - - EATEST_VERIFY(max((unsigned short)1, (unsigned short)1) == 1); - EATEST_VERIFY(max((unsigned short)1, (unsigned short)2) == 2); - EATEST_VERIFY(max((unsigned short)2, (unsigned short)1) == 2); - - EATEST_VERIFY(max((signed int)1, (signed int)1) == 1); - EATEST_VERIFY(max((signed int)1, (signed int)2) == 2); - EATEST_VERIFY(max((signed int)2, (signed int)1) == 2); - - EATEST_VERIFY(max((unsigned int)1, (unsigned int)1) == 1); - EATEST_VERIFY(max((unsigned int)1, (unsigned int)2) == 2); - EATEST_VERIFY(max((unsigned int)2, (unsigned int)1) == 2); - - EATEST_VERIFY(max((signed long)1, (signed long)1) == 1); - EATEST_VERIFY(max((signed long)1, (signed long)2) == 2); - EATEST_VERIFY(max((signed long)2, (signed long)1) == 2); - - EATEST_VERIFY(max((unsigned long)1, (unsigned long)1) == 1); - EATEST_VERIFY(max((unsigned long)1, (unsigned long)2) == 2); - EATEST_VERIFY(max((unsigned long)2, (unsigned long)1) == 2); - - EATEST_VERIFY(max((signed long long)1, (signed long long)1) == 1); - EATEST_VERIFY(max((signed long long)1, (signed long long)2) == 2); - EATEST_VERIFY(max((signed long long)2, (signed long long)1) == 2); - - EATEST_VERIFY(max((unsigned long long)1, (unsigned long long)1) == 1); - EATEST_VERIFY(max((unsigned long long)1, (unsigned long long)2) == 2); - EATEST_VERIFY(max((unsigned long long)2, (unsigned long long)1) == 2); - - EATEST_VERIFY(max((float)1, (float)1) == 1); - EATEST_VERIFY(max((float)1, (float)2) == 2); - EATEST_VERIFY(max((float)2, (float)1) == 2); - - EATEST_VERIFY(max((double)1, (double)1) == 1); - EATEST_VERIFY(max((double)1, (double)2) == 2); - EATEST_VERIFY(max((double)2, (double)1) == 2); - - EATEST_VERIFY(max((long double)1, (long double)1) == 1); - EATEST_VERIFY(max((long double)1, (long double)2) == 2); - EATEST_VERIFY(max((long double)2, (long double)1) == 2); - - - // Test min_alt specializations - EATEST_VERIFY(min_alt((char)1, (char)1) == 1); - EATEST_VERIFY(min_alt((char)1, (char)2) == 1); - EATEST_VERIFY(min_alt((char)2, (char)1) == 1); - - EATEST_VERIFY(min_alt((signed char)1, (signed char)1) == 1); - EATEST_VERIFY(min_alt((signed char)1, (signed char)2) == 1); - EATEST_VERIFY(min_alt((signed char)2, (signed char)1) == 1); - - EATEST_VERIFY(min_alt((unsigned char)1, (unsigned char)1) == 1); - EATEST_VERIFY(min_alt((unsigned char)1, (unsigned char)2) == 1); - EATEST_VERIFY(min_alt((unsigned char)2, (unsigned char)1) == 1); - - EATEST_VERIFY(min_alt((signed short)1, (signed short)1) == 1); - EATEST_VERIFY(min_alt((signed short)1, (signed short)2) == 1); - EATEST_VERIFY(min_alt((signed short)2, (signed short)1) == 1); - - EATEST_VERIFY(min_alt((unsigned short)1, (unsigned short)1) == 1); - EATEST_VERIFY(min_alt((unsigned short)1, (unsigned short)2) == 1); - EATEST_VERIFY(min_alt((unsigned short)2, (unsigned short)1) == 1); - - EATEST_VERIFY(min_alt((signed int)1, (signed int)1) == 1); - EATEST_VERIFY(min_alt((signed int)1, (signed int)2) == 1); - EATEST_VERIFY(min_alt((signed int)2, (signed int)1) == 1); - - EATEST_VERIFY(min_alt((unsigned int)1, (unsigned int)1) == 1); - EATEST_VERIFY(min_alt((unsigned int)1, (unsigned int)2) == 1); - EATEST_VERIFY(min_alt((unsigned int)2, (unsigned int)1) == 1); - - EATEST_VERIFY(min_alt((signed long)1, (signed long)1) == 1); - EATEST_VERIFY(min_alt((signed long)1, (signed long)2) == 1); - EATEST_VERIFY(min_alt((signed long)2, (signed long)1) == 1); - - EATEST_VERIFY(min_alt((unsigned long)1, (unsigned long)1) == 1); - EATEST_VERIFY(min_alt((unsigned long)1, (unsigned long)2) == 1); - EATEST_VERIFY(min_alt((unsigned long)2, (unsigned long)1) == 1); - - EATEST_VERIFY(min_alt((signed long long)1, (signed long long)1) == 1); - EATEST_VERIFY(min_alt((signed long long)1, (signed long long)2) == 1); - EATEST_VERIFY(min_alt((signed long long)2, (signed long long)1) == 1); - - EATEST_VERIFY(min_alt((unsigned long long)1, (unsigned long long)1) == 1); - EATEST_VERIFY(min_alt((unsigned long long)1, (unsigned long long)2) == 1); - EATEST_VERIFY(min_alt((unsigned long long)2, (unsigned long long)1) == 1); - - EATEST_VERIFY(min_alt((float)1, (float)1) == 1); - EATEST_VERIFY(min_alt((float)1, (float)2) == 1); - EATEST_VERIFY(min_alt((float)2, (float)1) == 1); - - EATEST_VERIFY(min_alt((double)1, (double)1) == 1); - EATEST_VERIFY(min_alt((double)1, (double)2) == 1); - EATEST_VERIFY(min_alt((double)2, (double)1) == 1); - - EATEST_VERIFY(min_alt((long double)1, (long double)1) == 1); - EATEST_VERIFY(min_alt((long double)1, (long double)2) == 1); - EATEST_VERIFY(min_alt((long double)2, (long double)1) == 1); - - - // Test max_alt specializations - EATEST_VERIFY(max_alt((char)1, (char)1) == 1); - EATEST_VERIFY(max_alt((char)1, (char)2) == 2); - EATEST_VERIFY(max_alt((char)2, (char)1) == 2); - - EATEST_VERIFY(max_alt((signed char)1, (signed char)1) == 1); - EATEST_VERIFY(max_alt((signed char)1, (signed char)2) == 2); - EATEST_VERIFY(max_alt((signed char)2, (signed char)1) == 2); - - EATEST_VERIFY(max_alt((unsigned char)1, (unsigned char)1) == 1); - EATEST_VERIFY(max_alt((unsigned char)1, (unsigned char)2) == 2); - EATEST_VERIFY(max_alt((unsigned char)2, (unsigned char)1) == 2); - - EATEST_VERIFY(max_alt((signed short)1, (signed short)1) == 1); - EATEST_VERIFY(max_alt((signed short)1, (signed short)2) == 2); - EATEST_VERIFY(max_alt((signed short)2, (signed short)1) == 2); - - EATEST_VERIFY(max_alt((unsigned short)1, (unsigned short)1) == 1); - EATEST_VERIFY(max_alt((unsigned short)1, (unsigned short)2) == 2); - EATEST_VERIFY(max_alt((unsigned short)2, (unsigned short)1) == 2); - - EATEST_VERIFY(max_alt((signed int)1, (signed int)1) == 1); - EATEST_VERIFY(max_alt((signed int)1, (signed int)2) == 2); - EATEST_VERIFY(max_alt((signed int)2, (signed int)1) == 2); - - EATEST_VERIFY(max_alt((unsigned int)1, (unsigned int)1) == 1); - EATEST_VERIFY(max_alt((unsigned int)1, (unsigned int)2) == 2); - EATEST_VERIFY(max_alt((unsigned int)2, (unsigned int)1) == 2); - - EATEST_VERIFY(max_alt((signed long)1, (signed long)1) == 1); - EATEST_VERIFY(max_alt((signed long)1, (signed long)2) == 2); - EATEST_VERIFY(max_alt((signed long)2, (signed long)1) == 2); - - EATEST_VERIFY(max_alt((unsigned long)1, (unsigned long)1) == 1); - EATEST_VERIFY(max_alt((unsigned long)1, (unsigned long)2) == 2); - EATEST_VERIFY(max_alt((unsigned long)2, (unsigned long)1) == 2); - - EATEST_VERIFY(max_alt((signed long long)1, (signed long long)1) == 1); - EATEST_VERIFY(max_alt((signed long long)1, (signed long long)2) == 2); - EATEST_VERIFY(max_alt((signed long long)2, (signed long long)1) == 2); - - EATEST_VERIFY(max_alt((unsigned long long)1, (unsigned long long)1) == 1); - EATEST_VERIFY(max_alt((unsigned long long)1, (unsigned long long)2) == 2); - EATEST_VERIFY(max_alt((unsigned long long)2, (unsigned long long)1) == 2); - - EATEST_VERIFY(max_alt((float)1, (float)1) == 1); - EATEST_VERIFY(max_alt((float)1, (float)2) == 2); - EATEST_VERIFY(max_alt((float)2, (float)1) == 2); - - EATEST_VERIFY(max_alt((double)1, (double)1) == 1); - EATEST_VERIFY(max_alt((double)1, (double)2) == 2); - EATEST_VERIFY(max_alt((double)2, (double)1) == 2); - - EATEST_VERIFY(max_alt((long double)1, (long double)1) == 1); - EATEST_VERIFY(max_alt((long double)1, (long double)2) == 2); - EATEST_VERIFY(max_alt((long double)2, (long double)1) == 2); - } - - { - // const T& min_alt(const T& a, const T& b); - // const T& min_alt(const T& a, const T& b, Compare compare) - // const T& max_alt(const T& a, const T& b); - // const T& max_alt(const T& a, const T& b, Compare compare) - - A a1(1), a2(2), a3(3); - a3 = min_alt(a1, a2, LessStruct()); - EATEST_VERIFY(a3.a == 1); - a3 = max_alt(a1, a2, LessStruct()); - EATEST_VERIFY(a3.a == 2); - - B b1(1), b2(2), b3(3); - b3 = min_alt(b2, b1, LessFunction); - EATEST_VERIFY(b3.b == 1); - b3 = max_alt(b2, b1, LessFunction); - EATEST_VERIFY(b3.b == 2); - - - TestObject t1(1), t2(2), t3(3); - t3 = min_alt(t2, t1); - EATEST_VERIFY(t3.mX == 1); - t3 = max_alt(t2, t1); - EATEST_VERIFY(t3.mX == 2); - - - int i1, i2(-1), i3(1); - i1 = min_alt(i2, i3); - EATEST_VERIFY(i1 == -1); - i1 = min_alt(i3, i2); - EATEST_VERIFY(i1 == -1); - i1 = max_alt(i2, i3); - EATEST_VERIFY(i1 == 1); - i1 = max_alt(i3, i2); - EATEST_VERIFY(i1 == 1); - - float f1, f2(-1), f3(1); - f1 = min_alt(f2, f3); - EATEST_VERIFY(f1 == -1); - f1 = min_alt(f3, f2); - EATEST_VERIFY(f1 == -1); - f1 = max_alt(f2, f3); - EATEST_VERIFY(f1 == 1); - f1 = max_alt(f3, f2); - EATEST_VERIFY(f1 == 1); - - double d1, d2(-1), d3(1); - d1 = min_alt(d2, d3); - EATEST_VERIFY(d1 == -1); - d1 = min_alt(d3, d2); - EATEST_VERIFY(d1 == -1); - d1 = max_alt(d2, d3); - EATEST_VERIFY(d1 == 1); - d1 = max_alt(d3, d2); - EATEST_VERIFY(d1 == 1); - - // Make sure enums work - static_assert(eastl::is_enum<TestMinMaxEnum>::value, "is_enum failure"); - EATEST_VERIFY(eastl::min(teX, teY) == teX); - - // Make sure pointers work - TestObject testObjectArray[2]; - EATEST_VERIFY(eastl::min(&testObjectArray[0], &testObjectArray[1]) == &testObjectArray[0]); - - // Regression for Microsoft warning C4347 (http://msdn.microsoft.com/en-us/library/x7wb5te0.aspx) - int32_t value = rng.RandRange(17, 18); - int32_t result = eastl::max_alt<int32_t>(0, value); // warning C4347: behavior change: 'const T &eastl::max_alt<int32_t>(const T &,const T &)' is called instead of 'int eastl::max_alt(int,int)' - EATEST_VERIFY(result == 17); - - // Regression for Microsoft error C2666 (http://msdn.microsoft.com/en-us/library/dyafzty4%28v=vs.110%29.aspx) - uint32_t value2a = 17; - uint32_t value2b = 2; - uint32_t result2 = eastl::min_alt<uint32_t>(value2a - value2b, 4); // error C2666: 'eastl::min_alt' : 12 overloads have similar conversions - EATEST_VERIFY(result2 == 4); - - // Regression for volatile arguments + literals - // This test is disabled until we come up with a solution for this. std::min gives the same result as below, so we aren't necessarily obligated to resolve this. - // volatile uint32_t value3 = 17; - // uint32_t result3 = eastl::min_alt<uint32_t>(value3, 4); // error C2664: 'const T &eastl::min_alt<unsigned int>(const T &,const T &)' : cannot convert parameter 1 from 'volatile uint32_t' to 'const unsigned int &' - // EATEST_VERIFY(result3 == 4); - } - - - { - // ForwardIterator min_element(ForwardIterator first, ForwardIterator last) - // ForwardIterator min_element(ForwardIterator first, ForwardIterator last, Compare compare) - - int intArray[] = { -5, 2, 1, 5, 4, 5 }; - int* pInt = min_element(intArray, intArray + 6); - EATEST_VERIFY(pInt && (*pInt == -5)); - - pInt = min_element(intArray, intArray + 6, Greater<int>()); - EATEST_VERIFY(pInt && (*pInt == 5)); - - - TestObject toArray[] = { TestObject(7), TestObject(2), TestObject(8), TestObject(5), TestObject(4), TestObject(-12) }; - TestObject* pTO = min_element(toArray, toArray + 6); - EATEST_VERIFY(pTO && (*pTO == TestObject(-12))); - - pTO = min_element(toArray, toArray + 6, Greater<TestObject>()); - EATEST_VERIFY(pTO && (*pTO == TestObject(8))); - } - - - { - // ForwardIterator max_element(ForwardIterator first, ForwardIterator last) - // ForwardIterator max_element(ForwardIterator first, ForwardIterator last, Compare compare) - - int intArray[] = { -5, 2, 1, 5, 4, 5 }; - int* pInt = max_element(intArray, intArray + 6); - EATEST_VERIFY(pInt && (*pInt == 5)); - - pInt = max_element(intArray, intArray + 6, less<int>()); - EATEST_VERIFY(pInt && (*pInt == 5)); - - - TestObject toArray[] = { TestObject(7), TestObject(2), TestObject(8), TestObject(5), TestObject(4), TestObject(-12) }; - TestObject* pTO = max_element(toArray, toArray + 6); - EATEST_VERIFY(pTO && (*pTO == TestObject(8))); - - pTO = max_element(toArray, toArray + 6, less<TestObject>()); - EATEST_VERIFY(pTO && (*pTO == TestObject(8))); - } - - { - // template <class ForwardIterator, class Compare> - // eastl::pair<ForwardIterator, ForwardIterator> - // minmax_element(ForwardIterator first, ForwardIterator last) - // - // template <class ForwardIterator, class Compare> - // eastl::pair<ForwardIterator, ForwardIterator> - // minmax_element(ForwardIterator first, ForwardIterator last, Compare compare) - - int intArray[] = { 5, -2, 1, 5, 6, 5 }; - - eastl::pair<int*, int*> result = eastl::minmax_element(intArray, intArray + 6); - EATEST_VERIFY((*result.first == -2) && (*result.second == 6)); - - - // template <typename T> - // eastl::pair<const T&, const T&> - // minmax(const T& a, const T& b) - // - // template <typename T, typename Compare> - // eastl::pair<const T&, const T&> - // minmax(const T& a, const T& b, Compare comp) - - // The VC++ compiler is broken in such a way that it can't compile the following without generating a warning: - // warning C4413: 'eastl::pair<T1,T2>::first' : reference member is initialized to a temporary that doesn't persist after the constructor exits. - // The Microsoft standard library definition of minmax doesn't generate this warning... because that minmax is broken and non-conforming. I think they - // made it the way they did because of the aforementioned compiler bug. - // Recent versions of clang seem to generate a warning of its own. To do: we need to address this. - // GCC 4.8 for x86 has a compiler bug in optimized builds for this code, so we currently enable this for non-optimized builds only. - #if defined(EA_COMPILER_CPP11_ENABLED) && ((defined(EA_COMPILER_CLANG) && EA_COMPILER_VERSION < 302) || (defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4007)) && !defined(__OPTIMIZE__)) - - int i3(3), i2(2); - eastl::pair<const int&, const int&> resulti = eastl::minmax(i3, i2); - EATEST_VERIFY_F((resulti.first == 2) && (resulti.second == 3), "minmax failure. %d %d", resulti.first, resulti.second); - - char c3(3), c2(2); - eastl::pair<const char&, const char&> resultc = eastl::minmax(c3, c2); - EATEST_VERIFY_F((resultc.first == 2) && (resultc.second == 3), "minmax failure. %d %d", (int)resultc.first, (int)resultc.second); - - float f3(3), f2(2); - eastl::pair<const float&, const float&> resultf = eastl::minmax(f3, f2); - EATEST_VERIFY_F((resultf.first == 2) && (resultf.second == 3), "minmax failure. %f %f", resultf.first, resultf.second); - #endif - - - // template <typename T> - // eastl::pair<T, T> - // minmax(std::initializer_list<T> ilist) - // - // template <typename T, class Compare> - // eastl::pair<T, T> - // minmax(std::initializer_list<T> ilist, Compare compare) - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - eastl::pair<int, int> result3 = eastl::minmax({3, 2}); - EATEST_VERIFY((result3.first == 2) && (result3.second == 3)); - #endif - } - - - return nErrorCount; -} - - -static int TestClamp() -{ - using namespace eastl; - - int nErrorCount = 0; - - EATEST_VERIFY(eastl::clamp(42, 1, 100) == 42); - EATEST_VERIFY(eastl::clamp(-42, 1, 100) == 1); - EATEST_VERIFY(eastl::clamp(420, 1, 100) == 100); - EATEST_VERIFY(eastl::clamp(1, 1, 100) == 1); - EATEST_VERIFY(eastl::clamp(100, 1, 100) == 100); - - EATEST_VERIFY(eastl::clamp(42.f, 1.f, 100.f, less<float>()) == 42.f); - EATEST_VERIFY(eastl::clamp(-42.f, 1.f, 100.f, less<float>()) == 1.f); - EATEST_VERIFY(eastl::clamp(420.f, 1.f, 100.f, less<float>()) == 100.f); - EATEST_VERIFY(eastl::clamp(1.f, 1.f, 100.f, less<float>()) == 1.f); - EATEST_VERIFY(eastl::clamp(100.f, 1.f, 100.f, less<float>()) == 100.f); - - EATEST_VERIFY(eastl::clamp(42., 1., 100., less<double>()) == 42.); - EATEST_VERIFY(eastl::clamp(-42., 1., 100., less<double>()) == 1.); - EATEST_VERIFY(eastl::clamp(420., 1., 100., less<double>()) == 100.); - EATEST_VERIFY(eastl::clamp(1., 1., 100., less<double>()) == 1.); - EATEST_VERIFY(eastl::clamp(100., 1., 100., less<double>()) == 100.); - - EATEST_VERIFY(eastl::clamp(A(42), A(1), A(100), LessStruct()).a == A(42).a); - EATEST_VERIFY(eastl::clamp(A(-42), A(1), A(100), LessStruct()).a == A(1).a); - EATEST_VERIFY(eastl::clamp(A(420), A(1), A(100), LessStruct()).a == A(100).a); - EATEST_VERIFY(eastl::clamp(A(1), A(1), A(100), LessStruct()).a == A(1).a); - EATEST_VERIFY(eastl::clamp(A(100), A(1), A(100), LessStruct()).a == A(100).a); - - return nErrorCount; -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestAlgorithm -// -int TestAlgorithm() -{ - using namespace eastl; - - int nErrorCount = 0; - - EA::UnitTest::Rand rng(EA::UnitTest::GetRandSeed()); - - TestObject::Reset(); - - nErrorCount += TestMinMax(); - nErrorCount += TestClamp(); - - - // bool all_of (InputIterator first, InputIterator last, Predicate p); - // bool any_of (InputIterator first, InputIterator last, Predicate p); - // bool none_of(InputIterator first, InputIterator last, Predicate p); - { - - eastl::vector<int> v; - v.push_back(2); - v.push_back(4); - v.push_back(6); - v.push_back(8); - - EATEST_VERIFY(eastl::all_of( v.begin(), v.end(), DivisibleBy(2))); - EATEST_VERIFY(eastl::any_of( v.begin(), v.end(), DivisibleBy(3))); - EATEST_VERIFY(eastl::none_of(v.begin(), v.end(), DivisibleBy(5))); - } - - - { - // pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) - // pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Predicate predicate) - - int intArray1[] = { -5, 2, 1, 5, 4, 8888 }; - int intArray2[] = { -5, 2, 1, 5, 4, 9999 }; - int intArray3[] = { -5, 2, 1, 5, 4, 9999 }; - - eastl::pair<int*, int*> pairInt = mismatch(intArray1, intArray1, intArray2); - EATEST_VERIFY(pairInt.first == intArray1 + 0); - EATEST_VERIFY(pairInt.second == intArray2 + 0); - - pairInt = mismatch(intArray1, intArray1 + 6, intArray2); - EATEST_VERIFY(pairInt.first == intArray1 + 5); - EATEST_VERIFY(pairInt.second == intArray2 + 5); - pairInt = mismatch(intArray2, intArray2 + 6, intArray3); - - EATEST_VERIFY(pairInt.first == intArray2 + 6); - EATEST_VERIFY(pairInt.second == intArray3 + 6); - - - pairInt = mismatch(intArray1, intArray1, intArray2, equal_to<int>()); - EATEST_VERIFY(pairInt.first == intArray1 + 0); - EATEST_VERIFY(pairInt.second == intArray2 + 0); - - pairInt = mismatch(intArray1, intArray1 + 6, intArray2, equal_to<int>()); - EATEST_VERIFY(pairInt.first == intArray1 + 5); - EATEST_VERIFY(pairInt.second == intArray2 + 5); - - pairInt = mismatch(intArray2, intArray2 + 6, intArray3, equal_to<int>()); - EATEST_VERIFY(pairInt.first == intArray2 + 6); - EATEST_VERIFY(pairInt.second == intArray3 + 6); - } - - - { - // void swap(T& a, T& b) - // void iter_swap(ForwardIterator1 a, ForwardIterator2 b) - - int intArray[] = { -5, 2, 1, 5, 4, 5 }; - - swap(intArray[0], intArray[4]); - EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "swap", 4, 2, 1, 5, -5, 5, -1)); - - iter_swap(intArray + 2, intArray + 3); - EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "iter_swap", 4, 2, 5, 1, -5, 5, -1)); - - - TestObject toArray[] = { TestObject(-5), TestObject(2), TestObject(1), TestObject(5), TestObject(4), TestObject(5) }; - - swap(toArray[0], toArray[4]); - EATEST_VERIFY(toArray[0] == TestObject(4)); - EATEST_VERIFY(toArray[4] == TestObject(-5)); - - iter_swap(toArray + 2, toArray + 3); - EATEST_VERIFY(toArray[2] == TestObject(5)); - EATEST_VERIFY(toArray[3] == TestObject(1)); - } - - - { - // ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) - - int intArray1[] = { 3, 2, 6, 5, 4, 1 }; - int intArray2[] = { 0, 0, 0, 0, 0, 0 }; - - swap_ranges(intArray1, intArray1 + 6, intArray2); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 6, int(), "swap_ranges", 0, 0, 0, 0, 0, 0, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 6, int(), "swap_ranges", 3, 2, 6, 5, 4, 1, -1)); - - - TestObject toArray1[] = { TestObject(3), TestObject(2), TestObject(6), TestObject(5), TestObject(4), TestObject(1) }; - TestObject toArray2[] = { TestObject(0), TestObject(0), TestObject(0), TestObject(0), TestObject(0), TestObject(0) }; - - swap_ranges(toArray1, toArray1 + 6, toArray2); - EATEST_VERIFY(toArray1[0] == TestObject(0)); - EATEST_VERIFY(toArray1[5] == TestObject(0)); - EATEST_VERIFY(toArray2[0] == TestObject(3)); - EATEST_VERIFY(toArray2[5] == TestObject(1)); - } - - - { - // ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) - // ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate predicate) - - int intArray[] = { 3, 2, 5, 5, 4, 1 }; - - int* pInt = adjacent_find(intArray + 0, intArray + 6); - EATEST_VERIFY(pInt == (intArray + 2)); - - pInt = adjacent_find(intArray + 3, intArray + 6); - EATEST_VERIFY(pInt == (intArray + 6)); // Verify not found - - - TestObject toArray[] = { TestObject(3), TestObject(2), TestObject(5), TestObject(5), TestObject(4), TestObject(1) }; - - TestObject* pTO = adjacent_find(toArray + 0, toArray + 6); - EATEST_VERIFY(pTO == (toArray + 2)); - - pTO = adjacent_find(toArray + 3, toArray + 6); - EATEST_VERIFY(pTO == (toArray + 6)); // Verify not found - } - - - { - // OutputIterator move(InputIterator first, InputIterator last, OutputIterator result) - - int intArray1[] = { 3, 2, 6, 5, 4, 1 }; - int intArray2[] = { 0, 0, 0, 0, 0, 0 }; - - move(intArray1, intArray1 + 0, intArray2); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 6, int(), "move", 0, 0, 0, 0, 0, 0, -1)); - - move(intArray1, intArray1 + 6, intArray2); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 6, int(), "move", 3, 2, 6, 5, 4, 1, -1)); - - move(intArray1 + 1, intArray1 + 6, intArray1 + 0); // Copy over self. - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 6, int(), "move", 2, 6, 5, 4, 1, 1, -1)); - } - - - { - // OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) - - int intArray1[] = { 3, 2, 6, 5, 4, 1 }; - int intArray2[] = { 0, 0, 0, 0, 0, 0 }; - - copy(intArray1, intArray1 + 0, intArray2); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 6, int(), "copy", 0, 0, 0, 0, 0, 0, -1)); - - copy(intArray1, intArray1 + 6, intArray2); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 6, int(), "copy", 3, 2, 6, 5, 4, 1, -1)); - - copy(intArray1 + 1, intArray1 + 6, intArray1 + 0); // Copy over self. - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 6, int(), "copy", 2, 6, 5, 4, 1, 1, -1)); - } - - - { - // OutputIterator copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate) - - int intArray1[] = { 9, 1, 9, 9, 9, 9, 1, 1, 9, 9 }; - int intArray2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - copy_if(intArray1, intArray1 + 0, intArray2, bind2nd(equal_to<int>(), (int)1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 10, int(), "copy_if", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1)); - - copy_if(intArray1, intArray1 + 9, intArray2, bind2nd(equal_to<int>(), (int)1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 10, int(), "copy_if", 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, -1)); - - copy_if(intArray1 + 1, intArray1 + 9, intArray1 + 0, bind2nd(equal_to<int>(), (int)1)); // Copy over self. - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 10, int(), "copy_if", 1, 1, 1, 9, 9, 9, 1, 1, 9, 9, -1)); - } - - - { - // OutputIterator copy_n(InputIterator first, Size count, OutputIterator result) - - eastl::string in = "123456"; - eastl::string out; - - eastl::copy_n(in.begin(), 4, eastl::back_inserter(out)); - EATEST_VERIFY(out == "1234"); - } - - - { - // BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result) - - int intArray1[] = { 3, 2, 6, 5, 4, 1 }; - int intArray2[] = { 0, 0, 0, 0, 0, 0 }; - - copy_backward(intArray1, intArray1 + 0, intArray2 + 0); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 6, int(), "copy_backward", 0, 0, 0, 0, 0, 0, -1)); - - copy_backward(intArray1, intArray1 + 6, intArray2 + 6); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 6, int(), "copy_backward", 3, 2, 6, 5, 4, 1, -1)); - - copy_backward(intArray1, intArray1 + 5, intArray1 + 6); // Copy over self. - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 6, int(), "copy_backward", 3, 3, 2, 6, 5, 4, -1)); - } - - - { - // OutputIterator move(InputIterator first, InputIterator last, OutputIterator result) - { - eastl::vector<eastl::string> src; - for(eastl_size_t i = 0; i < 4; i++) - src.push_back(eastl::string(1, (char8_t)('0' + i))); - eastl::vector<eastl::string> dest(src.size()); - - eastl::move(src.begin(), src.end(), dest.begin()); - EATEST_VERIFY((dest[0] == "0") && (dest[3] == "3")); - EATEST_VERIFY(src[0].empty() && src[3].empty()); - } - - { - // BidirectionalIterator2 move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result) - eastl::vector<eastl::string> src; - for(eastl_size_t i = 0; i < 4; i++) - src.push_back(eastl::string(1, (char8_t)('0' + i))); - eastl::vector<eastl::string> dest(src.size()); - - eastl::move_backward(src.begin(), src.end(), dest.end()); - EATEST_VERIFY((dest[0] == "0") && (dest[3] == "3")); - EATEST_VERIFY(src[0].empty() && src[3].empty()); - } - } - - - { - // difference_type count(InputIterator first, InputIterator last, const T& value) - - int intArray[] = { 1, 2, 1, 5, 4, 1 }; - ptrdiff_t n = count(intArray, intArray + 6, 1); - EATEST_VERIFY(n == 3); - - TestObject toArray[] = { TestObject(1), TestObject(2), TestObject(1), TestObject(5), TestObject(4), TestObject(1) }; - n = count(toArray, toArray + 6, TestObject(1)); - EATEST_VERIFY(n == 3); - } - - - { - // difference_type count_if(InputIterator first, InputIterator last, Predicate predicate) - - int intArray[] = { 3, 2, 6, 5, 4, 1, 2, 4, 5, 4, 1, 2 }; - - // Count all items whose value is less than three. - ptrdiff_t n = count_if(intArray, intArray, bind2nd(less<int>(), (int)3)); // No-op - EATEST_VERIFY(n == 0); - n = count_if(intArray, intArray + 12, bind2nd(less<int>(), (int)3)); - EATEST_VERIFY(n == 5); - - - // Count all items whose value is less than three. - TestObject toArray[] = { TestObject(1), TestObject(3), TestObject(1), TestObject(4), TestObject(2), TestObject(5) }; - - n = count_if(toArray, toArray, bind2nd(less<TestObject>(), TestObject(3))); // No-op - EATEST_VERIFY(n == 0); - n = count_if(toArray, toArray + 6, bind2nd(less<TestObject>(), TestObject(3))); - EATEST_VERIFY(n == 3); - - - // Count all items whose value is less than three. - slist<int> intList; - intList.push_front(1); - intList.push_front(3); - intList.push_front(1); - intList.push_front(4); - intList.push_front(2); - intList.push_front(5); - - n = count_if(intList.begin(), intList.begin(), bind2nd(less<int>(), (int)3)); // No-op - EATEST_VERIFY(n == 0); - n = count_if(intList.begin(), intList.end(), bind2nd(less<int>(), (int)3)); - EATEST_VERIFY(n == 3); - } - - - { - // void fill(ForwardIterator first, ForwardIterator last, const T& value) - - vector<int> intArray(10); - - EATEST_VERIFY(VerifySequence(intArray.begin(), intArray.end(), int(), "fill", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1)); - fill(intArray.begin() + 3, intArray.begin() + 7, 4); - EATEST_VERIFY(VerifySequence(intArray.begin(), intArray.end(), int(), "fill", 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, -1)); - - - slist<int> intList(10); - slist<int>::iterator first = intList.begin(); - slist<int>::iterator last = intList.begin(); - - advance(first, 3); - advance(last, 7); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "fill", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1)); - fill(first, last, 4); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "fill", 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, -1)); - - - // Exercise specializations we have for some platform/compiler combinations - // void fill(uint64_t* first, uint64_t* last, uint64_t c); - // void fill( int64_t* first, int64_t* last, int64_t c); - // void fill(uint32_t* first, uint32_t* last, uint32_t c); - // void fill( int32_t* first, int32_t* last, int32_t c); - // void fill(uint16_t* first, uint16_t* last, uint16_t c); - // void fill( int16_t* first, int16_t* last, int16_t c); - const eastl_size_t kMaxSize = 300; - eastl::vector<uint64_t> vU64(kMaxSize, 0); - eastl::vector< int64_t> vI64(kMaxSize, 0); - eastl::vector<uint32_t> vU32(kMaxSize, 0); - eastl::vector< int32_t> vI32(kMaxSize, 0); - eastl::vector<uint16_t> vU16(kMaxSize, 0); - eastl::vector< int16_t> vI16(kMaxSize, 0); - - for(eastl_size_t i = 0; i < kMaxSize; ++i) - { - eastl::fill(vU64.begin(), vU64.begin() + i, UINT64_C(0x0123456789abcdef)); - EATEST_VERIFY(EA::StdC::Memcheck64(&vU64[0], UINT64_C(0x0123456789abcdef), i) == NULL); - EA::StdC::Memset64(&vU64[0], 0, i); - - eastl::fill(vI64.begin(), vI64.begin() + i, UINT64_C(0x0123456789abcdef)); - EATEST_VERIFY(EA::StdC::Memcheck64(&vI64[0], UINT64_C(0x0123456789abcdef), i) == NULL); - EA::StdC::Memset64(&vI64[0], 0, i); - - eastl::fill(vU32.begin(), vU32.begin() + i, UINT32_C(0x01234567)); - EATEST_VERIFY(EA::StdC::Memcheck32(&vU32[0], UINT32_C(0x01234567), i) == NULL); - EA::StdC::Memset32(&vU32[0], 0, i); - - eastl::fill(vI32.begin(), vI32.begin() + i, UINT32_C(0x01234567)); - EATEST_VERIFY(EA::StdC::Memcheck32(&vI32[0], UINT32_C(0x01234567), i) == NULL); - EA::StdC::Memset32(&vI32[0], 0, i); - - eastl::fill(vU16.begin(), vU16.begin() + i, UINT16_C(0x0123)); - EATEST_VERIFY(EA::StdC::Memcheck16(&vU16[0], UINT16_C(0x0123), i) == NULL); - EA::StdC::Memset16(&vU16[0], 0, i); - - eastl::fill(vI16.begin(), vI16.begin() + i, UINT16_C(0x0123)); - EATEST_VERIFY(EA::StdC::Memcheck16(&vI16[0], UINT16_C(0x0123), i) == NULL); - EA::StdC::Memset16(&vI16[0], 0, i); - } - - { // Regression for user-reported compile failure. - enum TestEnum { eTestValue = -1 }; - eastl::vector<int32_t> intArrayEnum; - - eastl::fill<eastl::vector<int32_t>::iterator, int32_t>(intArrayEnum.begin(), intArrayEnum.end(), eTestValue); - EATEST_VERIFY(intArrayEnum.size() == 0); - } - } - - - { - // OutputIterator fill_n(OutputIterator first, Size n, const T& value) - - vector<int> intArray(10); - - EATEST_VERIFY(VerifySequence(intArray.begin(), intArray.end(), int(), "fill_n", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1)); - fill_n(intArray.begin() + 3, 4, 4); - EATEST_VERIFY(VerifySequence(intArray.begin(), intArray.end(), int(), "fill_n", 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, -1)); - - - list<int> intList(10); - list<int>::iterator first = intList.begin(); - - advance(first, 3); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "fill_n", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1)); - fill_n(first, 4, 4); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "fill_n", 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, -1)); - - // Exercise specializations we have for some platform/compiler combinations - // template<typename Size> - // uint64_t* fill_n(uint64_t* first, Size n, uint64_t c); - // int64_t* fill_n( int64_t* first, Size n, int64_t c); - // uint32_t* fill_n(uint32_t* first, Size n, uint32_t c); - // int32_t* fill_n( int32_t* first, Size n, int32_t c); - // uint16_t* fill_n(uint16_t* first, Size n, uint16_t c); - // int16_t* fill_n( int16_t* first, Size n, int16_t c); - const eastl_size_t kMaxSize = 17; - eastl::vector<uint64_t> vU64(kMaxSize, 0); - eastl::vector< int64_t> vI64(kMaxSize, 0); - eastl::vector<uint32_t> vU32(kMaxSize, 0); - eastl::vector< int32_t> vI32(kMaxSize, 0); - eastl::vector<uint16_t> vU16(kMaxSize, 0); - eastl::vector< int16_t> vI16(kMaxSize, 0); - - eastl::vector<uint64_t>::iterator itU64 = eastl::fill_n(vU64.begin(), kMaxSize, UINT64_C(0x0123456789abcdef)); - EATEST_VERIFY(EA::StdC::Memcheck64(&vU64[0], UINT64_C(0x0123456789abcdef), kMaxSize) == NULL); - EATEST_VERIFY(itU64 == (vU64.begin() + kMaxSize)); - EA::StdC::Memset64(&vU64[0], 0, kMaxSize); - - eastl::vector<int64_t>::iterator itI64 = eastl::fill_n(vI64.begin(), kMaxSize, UINT64_C(0x0123456789abcdef)); - EATEST_VERIFY(EA::StdC::Memcheck64(&vI64[0], UINT64_C(0x0123456789abcdef), kMaxSize) == NULL); - EATEST_VERIFY(itI64 == (vI64.begin() + kMaxSize)); - EA::StdC::Memset64(&vI64[0], 0, kMaxSize); - - eastl::vector<uint32_t>::iterator itU32 = eastl::fill_n(vU32.begin(), kMaxSize, UINT32_C(0x01234567)); - EATEST_VERIFY(EA::StdC::Memcheck32(&vU32[0], UINT32_C(0x01234567), kMaxSize) == NULL); - EATEST_VERIFY(itU32 == (vU32.begin() + kMaxSize)); - EA::StdC::Memset32(&vU32[0], 0, kMaxSize); - - eastl::vector<int32_t>::iterator itI32 = eastl::fill_n(vI32.begin(), kMaxSize, UINT32_C(0x01234567)); - EATEST_VERIFY(EA::StdC::Memcheck32(&vI32[0], UINT32_C(0x01234567), kMaxSize) == NULL); - EATEST_VERIFY(itI32 == (vI32.begin() + kMaxSize)); - EA::StdC::Memset32(&vI32[0], 0, kMaxSize); - - eastl::vector<uint16_t>::iterator itU16 = eastl::fill_n(vU16.begin(), kMaxSize, UINT16_C(0x0123)); - EATEST_VERIFY(EA::StdC::Memcheck16(&vU16[0], UINT16_C(0x0123), kMaxSize) == NULL); - EATEST_VERIFY(itU16 == (vU16.begin() + kMaxSize)); - EA::StdC::Memset16(&vU16[0], 0, kMaxSize); - - eastl::vector<int16_t>::iterator itI16 = eastl::fill_n(vI16.begin(), kMaxSize, UINT16_C(0x0123)); - EATEST_VERIFY(EA::StdC::Memcheck16(&vI16[0], UINT16_C(0x0123), kMaxSize) == NULL); - EATEST_VERIFY(itI16 == (vI16.begin() + kMaxSize)); - EA::StdC::Memset16(&vI16[0], 0, kMaxSize); - } - - - { - // InputIterator find(InputIterator first, InputIterator last, const T& value) - vector<int> intArray; - intArray.push_back(0); - intArray.push_back(1); - intArray.push_back(2); - intArray.push_back(3); - - vector<int>::iterator it = find(intArray.begin(), intArray.end(), 2); - EATEST_VERIFY(it == (intArray.begin() + 2)); - EATEST_VERIFY(*it == 2); - - it = find(intArray.begin(), intArray.end(), 7); - EATEST_VERIFY(it == intArray.end()); - } - - - { - // InputIterator find_if(InputIterator first, InputIterator last, Predicate predicate) - // InputIterator find_if_not(InputIterator first, InputIterator last, Predicate predicate) - - int intArray[] = { 3, 2, 6, 5, 4, 1, 2, 4, 5, 4, 1, 2 }; - - // Find an item which is equal to 1. - int* pInt = find_if(intArray, intArray, bind2nd(equal_to<int>(), (int)1)); // No-op - EATEST_VERIFY(pInt == (intArray)); - pInt = find_if(intArray, intArray + 12, bind2nd(equal_to<int>(), (int)1)); - EATEST_VERIFY(pInt == (intArray + 5)); - pInt = find_if(intArray, intArray + 12, bind2nd(equal_to<int>(), (int)99)); - EATEST_VERIFY(pInt == (intArray + 12)); - - pInt = find_if_not(intArray, intArray + 12, bind2nd(equal_to<int>(), (int)3)); - EATEST_VERIFY(pInt == (intArray + 1)); - - // Find an item which is equal to 1. - TestObject toArray[] = { TestObject(4), TestObject(3), TestObject(2), TestObject(1), TestObject(2), TestObject(5) }; - - TestObject* pTO = find_if(toArray, toArray, bind2nd(equal_to<TestObject>(), TestObject(1))); // No-op - EATEST_VERIFY(pTO == (toArray)); - pTO = find_if(toArray, toArray + 6, bind2nd(equal_to<TestObject>(), TestObject(1))); - EATEST_VERIFY(pTO == (toArray + 3)); - pTO = find_if(toArray, toArray + 6, bind2nd(equal_to<TestObject>(), TestObject(99))); - EATEST_VERIFY(pTO == (toArray + 6)); - - pTO = find_if_not(toArray, toArray + 6, bind2nd(equal_to<TestObject>(), TestObject(4))); - EATEST_VERIFY(pTO == (toArray + 1)); - - // Find an item which is equal to 1. - slist<int> intList; - intList.push_front(4); - intList.push_front(3); - intList.push_front(2); - intList.push_front(1); - intList.push_front(2); - intList.push_front(5); - - // The list is now: { 5, 2, 1, 2, 3, 4 } - slist<int>::iterator it = find_if(intList.begin(), intList.begin(), bind2nd(equal_to<int>(), (int)1)); // No-op - EATEST_VERIFY(it == intList.begin()); - it = find_if(intList.begin(), intList.end(), bind2nd(equal_to<int>(), (int)1)); - EATEST_VERIFY(*it == 1); - it = find_if(intList.begin(), intList.end(), bind2nd(equal_to<int>(), (int)99)); - EATEST_VERIFY(it == intList.end()); - - it = find_if_not(intList.begin(), intList.end(), bind2nd(equal_to<int>(), (int)5)); - EATEST_VERIFY(*it == 2); - } - - - { - // ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) - // ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate predicate) - - int intArray1[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - int intArray2[3] = { 7, 6, 5 }; - - int* pInt = find_first_of(intArray1, intArray1, intArray2, intArray2 + 3); - EATEST_VERIFY(pInt == intArray1); - pInt = find_first_of(intArray1, intArray1 + 10, intArray2, intArray2); - EATEST_VERIFY(pInt == intArray1 + 10); - pInt = find_first_of(intArray1, intArray1 + 10, intArray2, intArray2 + 3); - EATEST_VERIFY(pInt == intArray1 + 5); - - pInt = find_first_of(intArray1, intArray1, intArray2, intArray2 + 3, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1); - pInt = find_first_of(intArray1, intArray1 + 10, intArray2, intArray2, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1 + 10); - pInt = find_first_of(intArray1, intArray1 + 10, intArray2, intArray2 + 3, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1 + 5); - } - - - { - // ForwardIterator1 find_first_not_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) - // ForwardIterator1 find_first_not_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2), BinaryPredicate predicate) - - int intArray1[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - int intArray2[3] = { 0, 1, 2 }; - - int* pInt = find_first_not_of(intArray1, intArray1, intArray2, intArray2 + 3); - EATEST_VERIFY(pInt == intArray1); - pInt = find_first_not_of(intArray1, intArray1 + 10, intArray2, intArray2); - EATEST_VERIFY(pInt == intArray1 + 0); - pInt = find_first_not_of(intArray1, intArray1 + 10, intArray2, intArray2 + 3); - EATEST_VERIFY(pInt == intArray1 + 3); - - pInt = find_first_not_of(intArray1, intArray1, intArray2, intArray2 + 3, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1); - pInt = find_first_not_of(intArray1, intArray1 + 10, intArray2, intArray2, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1 + 0); - pInt = find_first_not_of(intArray1, intArray1 + 10, intArray2, intArray2 + 3, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1 + 3); - } - - - { - // ForwardIterator1 find_last_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) - // ForwardIterator1 find_last_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate predicate) - - int intArray1[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - int intArray2[3] = { 3, 4, 5 }; - - int* pInt = find_last_of(intArray1, intArray1, intArray2, intArray2 + 3); - EATEST_VERIFY(pInt == intArray1); - pInt = find_last_of(intArray1, intArray1 + 10, intArray2, intArray2); - EATEST_VERIFY(pInt == intArray1 + 10); - pInt = find_last_of(intArray1, intArray1 + 10, intArray2, intArray2 + 3); - EATEST_VERIFY(pInt == intArray1 + 5); - - pInt = find_last_of(intArray1, intArray1, intArray2, intArray2 + 3, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1); - pInt = find_last_of(intArray1, intArray1 + 10, intArray2, intArray2, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1 + 10); - pInt = find_last_of(intArray1, intArray1 + 10, intArray2, intArray2 + 3, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1 + 5); - } - - - { - // ForwardIterator1 find_last_not_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) - // ForwardIterator1 find_last_not_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2), BinaryPredicate predicate) - - int intArray1[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - int intArray2[3] = { 7, 8, 9 }; - - int* pInt = find_last_not_of(intArray1, intArray1, intArray2, intArray2 + 3); - EATEST_VERIFY(pInt == intArray1); - pInt = find_last_not_of(intArray1, intArray1 + 10, intArray2, intArray2); - EATEST_VERIFY(pInt == intArray1 + 10); - pInt = find_last_not_of(intArray1, intArray1 + 10, intArray2, intArray2 + 3); - EATEST_VERIFY(pInt == intArray1 + 6); - - pInt = find_last_not_of(intArray1, intArray1, intArray2, intArray2 + 3, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1); - pInt = find_last_not_of(intArray1, intArray1 + 10, intArray2, intArray2, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1 + 10); - pInt = find_last_not_of(intArray1, intArray1 + 10, intArray2, intArray2 + 3, equal_to<int>()); - EATEST_VERIFY(pInt == intArray1 + 6); - } - - - { - // Function for_each(InputIterator first, InputIterator last, Function function) - - deque<int> intDeque(1000); - SetIncrementalIntegers<int> sii; // We define this class at the top of this file. - eastl_size_t i; - - sii = for_each(intDeque.begin(), intDeque.end(), sii); - EATEST_VERIFY(sii.mX == 1000); - for(i = 0; i < 1000; i++) - { - if(intDeque[i] != (int)i) - break; - } - EATEST_VERIFY(i == 1000); - - - array<int, 1000> intArray; - sii.reset(); - - sii = for_each(intArray.begin(), intArray.end(), sii); - EATEST_VERIFY(sii.mX == 1000); - for(i = 0; i < 1000; i++) - { - if(intArray[i] != (int)i) - break; - } - EATEST_VERIFY(i == 1000); - } - - // for_each_n - { - { - vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - for_each_n(v.begin(), 5, [](auto& e) { e += 10; }); - - vector<int> expected = {10, 11, 12, 13, 14, 5, 6, 7, 8, 9}; - EATEST_VERIFY(v == expected); - } - - // verify lambda can return a result that is ignored. - { - vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - for_each_n(v.begin(), 5, [](auto& e) { e += 10; return 42; }); - - vector<int> expected = {10, 11, 12, 13, 14, 5, 6, 7, 8, 9}; - EATEST_VERIFY(v == expected); - } - } - - { - // void generate(ForwardIterator first, ForwardIterator last, Generator generator) - // OutputIterator generate_n(OutputIterator first, Size n, Generator generator) - - deque<int> intDeque((eastl_size_t)rng.RandRange(100, 1000)); - GenerateIncrementalIntegers<int> gii(0); // We define this class at the top of this file. - int i, iEnd; - - generate(intDeque.begin(), intDeque.end(), gii); - for(i = 0, iEnd = (int)intDeque.size(); i < iEnd; i++) - { - if(intDeque[(eastl_size_t)i] != i) - break; - } - EATEST_VERIFY(i == iEnd); - - - array<int, 1000> intArray; - gii.reset(0); - - generate(intArray.begin(), intArray.end(), gii); - for(i = 0; i < 1000; i++) - { - if(intArray[(eastl_size_t)i] != i) - break; - } - EATEST_VERIFY(i == 1000); - } - - - { - // OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation unaryOperation) - - deque<int> intDeque((eastl_size_t)rng.RandRange(1, 1000)); - int i, iEnd; - - for(i = 0, iEnd = (int)intDeque.size(); i < iEnd; i++) - intDeque[(eastl_size_t)i] = 1; - transform(intDeque.begin(), intDeque.begin(), intDeque.begin(), negate<int>()); // No-op - EATEST_VERIFY(intDeque[0] == 1); // Verify nothing happened - transform(intDeque.begin(), intDeque.end(), intDeque.begin(), negate<int>()); - for(i = 0, iEnd = (int)intDeque.size(); i < iEnd; i++) - { - if(intDeque[(eastl_size_t)i] != -1) - break; - } - EATEST_VERIFY(i == iEnd); - - - slist<TestObject> sList; - for(i = 0, iEnd = rng.RandRange(1, 100); i < iEnd; i++) - sList.push_front(TestObject(1)); - transform(sList.begin(), sList.begin(), sList.begin(), TestObjectNegate()); // No-op - EATEST_VERIFY(sList.front() == TestObject(1)); - transform(sList.begin(), sList.end(), sList.begin(), TestObjectNegate()); // TestObjectNegate is a custom function we define for this test. - slist<TestObject>::iterator it = sList.begin(); - for(; it != sList.end(); it++) - { - if(!(*it == TestObject(-1))) - break; - } - EATEST_VERIFY(it == sList.end()); - } - - - { - // OutputIterator transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binaryOperation) - - int intArray1[12] = { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }; - int intArray2[12] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; - - int* pInt = transform(intArray1, intArray1, intArray2, intArray2, plus<int>()); - EATEST_VERIFY(pInt == intArray2); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "transform", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "transform", 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1)); - - pInt = transform(intArray1, intArray1 + 12, intArray2, intArray2, plus<int>()); - EATEST_VERIFY(pInt == intArray2 + 12); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "transform", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "transform", 3, 3, 4, 4, 3, 3, 4, 4, 3, 3, 4, 4, -1)); - } - - - { - // bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) - // bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate predicate) - - vector<eastl_size_t> intArray(100); - list<eastl_size_t> intList(100); - generate(intArray.begin(), intArray.end(), rng); - copy(intArray.begin(), intArray.end(), intList.begin()); - - bool b = equal(intArray.begin(), intArray.begin(), (eastl_size_t*)NULL); - EATEST_VERIFY(b); - b = equal(intArray.begin(), intArray.end(), intList.begin()); - EATEST_VERIFY(b); - intArray[50] += 1; - b = equal(intArray.begin(), intArray.end(), intList.begin()); - EATEST_VERIFY(!b); - - intArray[50] -= 1; // resulttore its original value so the containers are equal again. - b = equal(intArray.begin(), intArray.begin(), (eastl_size_t*)NULL, equal_to<eastl_size_t>()); - EATEST_VERIFY(b); - b = equal(intArray.begin(), intArray.end(), intList.begin(), equal_to<eastl_size_t>()); - EATEST_VERIFY(b); - intArray[50] += 1; - b = equal(intArray.begin(), intArray.end(), intList.begin(), equal_to<eastl_size_t>()); - EATEST_VERIFY(!b); - } - - - { - // bool identical(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) - // bool identical(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate predicate) - - vector<eastl_size_t> intArray(100); - list<eastl_size_t> intList(100); - generate(intArray.begin(), intArray.end(), rng); - copy(intArray.begin(), intArray.end(), intList.begin()); - - - bool b = identical(intArray.begin(), intArray.begin(), (eastl_size_t*)NULL, (eastl_size_t*)NULL); - EATEST_VERIFY(b); - b = identical(intArray.begin(), intArray.end(), intList.begin(), intList.end()); - EATEST_VERIFY(b); - b = identical(intArray.begin(), intArray.end() - 10, intList.begin(), intList.end()); - EATEST_VERIFY(!b); - b = identical(intList.begin(), intList.end(), intArray.begin() + 10, intArray.end()); - EATEST_VERIFY(!b); - intArray[50] += 1; - b = identical(intArray.begin(), intArray.end(), intList.begin(), intList.end()); - EATEST_VERIFY(!b); - - - intArray[50] -= 1; // resulttore its original value so the containers are equal again. - b = identical(intArray.begin(), intArray.begin(), (eastl_size_t*)NULL, (eastl_size_t*)NULL, equal_to<eastl_size_t>()); - EATEST_VERIFY(b); - b = identical(intArray.begin(), intArray.end(), intList.begin(), intList.end(), equal_to<eastl_size_t>()); - EATEST_VERIFY(b); - b = identical(intArray.begin(), intArray.end() - 10, intList.begin(), intList.end(), equal_to<eastl_size_t>()); - EATEST_VERIFY(!b); - b = identical(intList.begin(), intList.end(), intArray.begin() + 10, intArray.end(), equal_to<eastl_size_t>()); - EATEST_VERIFY(!b); - intArray[50] += 1; - b = identical(intArray.begin(), intArray.end(), intList.begin(), intList.end(), equal_to<eastl_size_t>()); - EATEST_VERIFY(!b); - } - - - { - // bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) - // bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare compare) - - int intArray1[6] = { 0, 1, 2, 3, 4, 5 }; - int intArray2[6] = { 0, 1, 2, 3, 4, 6 }; - int intArray3[5] = { 0, 1, 2, 3, 4 }; - - bool b = lexicographical_compare(intArray1, intArray1, intArray2, intArray2); // Test empty range. - EATEST_VERIFY(!b); - b = lexicographical_compare(intArray1, intArray1 + 6, intArray2, intArray2 + 6); - EATEST_VERIFY( b); - b = lexicographical_compare(intArray2, intArray2 + 6, intArray1, intArray1 + 6); - EATEST_VERIFY(!b); - b = lexicographical_compare(intArray1, intArray1 + 6, intArray3, intArray3 + 5); - EATEST_VERIFY(!b); - - b = lexicographical_compare(intArray1, intArray1, intArray2, intArray2, greater<int>()); // Test empty range. - EATEST_VERIFY(!b); - b = lexicographical_compare(intArray1, intArray1 + 6, intArray2, intArray2 + 6, greater<int>()); - EATEST_VERIFY(!b); - b = lexicographical_compare(intArray2, intArray2 + 6, intArray1, intArray1 + 6, greater<int>()); - EATEST_VERIFY( b); - b = lexicographical_compare(intArray3, intArray3 + 5, intArray1, intArray1 + 6, less<int>()); - EATEST_VERIFY( b); - } - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - // <compairison_category> lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare compare) - - int intArray1[6] = {0, 1, 2, 3, 4, 5}; - int intArray2[6] = {0, 1, 2, 3, 4, 6}; - int intArray3[5] = {0, 1, 2, 3, 4}; - int intArray4[5] = {4, 3, 2, 1, 0}; - - // strong ordering - auto compare_strong = [](int first, int second) - { - return (first < second) ? std::strong_ordering::less : - (first > second) ? std::strong_ordering::greater : - std::strong_ordering::equal; - }; - - auto b = lexicographical_compare_three_way(intArray1, intArray1 + 6, intArray2, intArray2 + 6, compare_strong); - EATEST_VERIFY(b == std::strong_ordering::less); - b = lexicographical_compare_three_way(intArray3, intArray3 + 5, intArray2, intArray2 + 6, compare_strong); - EATEST_VERIFY(b == std::strong_ordering::less); - b = lexicographical_compare_three_way(intArray3, intArray3 + 5, intArray2, intArray2 + 6, synth_three_way{}); - EATEST_VERIFY(b == std::strong_ordering::less); - - b = lexicographical_compare_three_way(intArray2, intArray2 + 6, intArray1, intArray1 + 6, compare_strong); - EATEST_VERIFY(b == std::strong_ordering::greater); - b = lexicographical_compare_three_way(intArray2, intArray2 + 6, intArray1, intArray1 + 6, synth_three_way{}); - EATEST_VERIFY(b == std::strong_ordering::greater); - - b = lexicographical_compare_three_way(intArray1, intArray1 + 6, intArray3, intArray3 + 5, compare_strong); - EATEST_VERIFY(b == std::strong_ordering::greater); - b = lexicographical_compare_three_way(intArray1, intArray1 + 6, intArray3, intArray3 + 5, synth_three_way{}); - EATEST_VERIFY(b == std::strong_ordering::greater); - - b = lexicographical_compare_three_way(intArray1, intArray1, intArray2, intArray2, compare_strong); // Test empty range. - EATEST_VERIFY(b == std::strong_ordering::equal); - b = lexicographical_compare_three_way(intArray1, intArray1, intArray2, intArray2, synth_three_way{}); // Test empty range. - EATEST_VERIFY(b == std::strong_ordering::equal); - - // weak ordering - auto compare_weak = [](int first, int second) - { - return (first < second) ? std::weak_ordering::less : - (first > second) ? std::weak_ordering::greater : - std::weak_ordering::equivalent; - }; - - auto c = lexicographical_compare_three_way(intArray3, intArray3 + 5, intArray4, intArray4 + 5, compare_weak); - EATEST_VERIFY(c == std::weak_ordering::less); - c = lexicographical_compare_three_way(intArray4, intArray4 + 5, intArray3, intArray3 + 5, compare_weak); - EATEST_VERIFY(c == std::weak_ordering::greater); - c = lexicographical_compare_three_way(intArray3, intArray3 + 5, intArray4, intArray4 + 5, synth_three_way{}); - EATEST_VERIFY(c == std::weak_ordering::less); - c = lexicographical_compare_three_way(intArray4, intArray4 + 5, intArray3, intArray3 + 5, synth_three_way{}); - EATEST_VERIFY(c == std::weak_ordering::greater); - } - - { - EATEST_VERIFY(synth_three_way{}(1, 1) == std::strong_ordering::equal); - EATEST_VERIFY(synth_three_way{}(2, 1) == std::strong_ordering::greater); - EATEST_VERIFY(synth_three_way{}(1, 2) == std::strong_ordering::less); - - struct weak_struct - { - int val; - inline std::weak_ordering operator<=>(const weak_struct& b) const - { - return val <=> b.val; - } - }; - - EATEST_VERIFY(synth_three_way{}(weak_struct{1}, weak_struct{2}) == std::weak_ordering::less); - EATEST_VERIFY(synth_three_way{}(weak_struct{2}, weak_struct{1}) == std::weak_ordering::greater); - EATEST_VERIFY(synth_three_way{}(weak_struct{1}, weak_struct{1}) == std::weak_ordering::equivalent); - } -#endif - - { - // ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value) - // ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare compare) - - int i; - - int* pInt = lower_bound((int*)NULL, (int*)NULL, 100); - EATEST_VERIFY(pInt == NULL); - - - for(i = 0; i < 20 + (gEASTL_TestLevel * 20); i++) - { - deque<int> intDeque((eastl_size_t)rng.RandRange(1, 500)); - - for(int j = 0, jEnd = (int)intDeque.size(); j < jEnd; j++) - intDeque[(eastl_size_t)j] = (int)rng.RandLimit(jEnd / 2); // This will result in both gaps and duplications. - - for(int k = 0, kEnd = (int)intDeque.size(); k < kEnd; k++) - { - deque<int>::iterator it = lower_bound(intDeque.begin(), intDeque.end(), k); - - if(it != intDeque.begin()) - EATEST_VERIFY(*(it - 1) < k); - - if(it != intDeque.end()) - EATEST_VERIFY((k < *it) || !(*it < k)); // Verify tha k <= *it by using only operator< - } - } - - - for(i = 0; i < 20 + (gEASTL_TestLevel * 20); i++) - { - list<TestObject> toList; - int nSize = (int)rng.RandRange(1, 500); - - for(int j = 0, jEnd = nSize; j < jEnd; j++) - toList.push_back(TestObject((int)rng.RandLimit(jEnd / 2))); // This will result in both gaps and duplications. - - for(int k = 0; k < nSize; k++) - { - TestObject toK(k); - list<TestObject>::iterator it = lower_bound(toList.begin(), toList.end(), toK); - - if(it != toList.begin()) - { - --it; - EATEST_VERIFY(*it < toK); - ++it; - } - - if(it != toList.end()) - EATEST_VERIFY((toK < *it) || !(*it < toK)); // Verify tha k <= *it by using only operator< - } - } - } - - - { - // ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value) - // ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare compare) - - int i; - - int* pInt = upper_bound((int*)NULL, (int*)NULL, 100); - EATEST_VERIFY(pInt == NULL); - - - for(i = 0; i < 20 + (gEASTL_TestLevel * 20); i++) - { - deque<int> intDeque((eastl_size_t)rng.RandRange(1, 500)); - - for(eastl_size_t j = 0, jEnd = intDeque.size(); j < jEnd; j++) - intDeque[j] = (int)rng.RandLimit((uint32_t)jEnd / 2); // This will result in both gaps and duplications. - - for(int k = 0, kEnd = (int)intDeque.size(); k < kEnd; k++) - { - deque<int>::iterator it = upper_bound(intDeque.begin(), intDeque.end(), k); - - if(it != intDeque.begin()) - EATEST_VERIFY((*(it - 1) < k) || !(k < *(it - 1))); // Verify tha *it <= k by using only operator< - - if(it != intDeque.end()) - EATEST_VERIFY(k < *it); - } - } - - - for(i = 0; i < 20 + (gEASTL_TestLevel * 20); i++) - { - list<TestObject> toList; - int nSize = (int)rng.RandRange(1, 500); - - for(int j = 0, jEnd = nSize; j < jEnd; j++) - toList.push_back(TestObject((int)rng.RandLimit(jEnd / 2))); // This will result in both gaps and duplications. - - for(int k = 0; k < nSize; k++) - { - TestObject toK(k); - list<TestObject>::iterator it = upper_bound(toList.begin(), toList.end(), toK); - - if(it != toList.begin()) - { - --it; - EATEST_VERIFY((*it < toK) || !(toK < *it)); // Verify tha *it <= k by using only operator< - ++it; - } - - if(it != toList.end()) - EATEST_VERIFY(toK < *it); - } - } - } - - - { - // pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first, ForwardIterator last, const T& value) - // pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare compare) - - int i; - - pair<int*, int*> pInt = equal_range((int*)NULL, (int*)NULL, 100); - EATEST_VERIFY(pInt.first == NULL); - EATEST_VERIFY(pInt.second == NULL); - - - for(i = 0; i < 20 + (gEASTL_TestLevel * 20); i++) - { - deque<int> intDeque((eastl_size_t)rng.RandRange(1, 500)); - - for(int j = 0, jEnd = (int)intDeque.size(); j < jEnd; j++) - intDeque[(eastl_size_t)j] = (int)rng.RandLimit(jEnd / 2); // This will result in both gaps and duplications. - - for(int k = 0, kEnd = (int)intDeque.size(); k < kEnd; k++) - { - pair<deque<int>::iterator, deque<int>::iterator> it = equal_range(intDeque.begin(), intDeque.end(), k); - - // Test it.first as lower_bound. - if(it.first != intDeque.begin()) - EATEST_VERIFY(*(it.first - 1) < k); - - if(it.first != intDeque.end()) - EATEST_VERIFY((k < *it.first) || !(*it.first < k)); // Verify tha k <= *it by using only operator< - - // Test it.second as upper_bound. - if(it.second != intDeque.begin()) - EATEST_VERIFY((*(it.second - 1) < k) || !(k < *(it.second - 1))); // Verify tha *it <= k by using only operator< - - if(it.second != intDeque.end()) - EATEST_VERIFY(k < *it.second); - } - } - - - for(i = 0; i < 20 + (gEASTL_TestLevel * 20); i++) - { - list<TestObject> toList; - int nSize = (int)rng.RandRange(1, 500); - - for(int j = 0, jEnd = nSize; j < jEnd; j++) - toList.push_back(TestObject((int)rng.RandLimit(jEnd / 2))); // This will result in both gaps and duplications. - - for(int k = 0; k < nSize; k++) - { - TestObject toK(k); - pair<list<TestObject>::iterator, list<TestObject>::iterator> it = equal_range(toList.begin(), toList.end(), toK); - - // Test it.first as lower_bound - if(it.first != toList.begin()) - { - --it.first; - EATEST_VERIFY(*it.first < toK); - ++it.first; - } - - if(it.first != toList.end()) - EATEST_VERIFY((toK < *it.first) || !(*it.first < toK)); // Verify tha k <= *it by using only operator< - - // Test it.second as upper_bound - if(it.second != toList.begin()) - { - --it.second; - EATEST_VERIFY((*it.second < toK) || !(toK < *it.second)); // Verify tha *it <= k by using only operator< - ++it.second; - } - - if(it.second != toList.end()) - EATEST_VERIFY(toK < *it.second); - } - } - } - - - { - // void replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value) - // void replace_if(ForwardIterator first, ForwardIterator last, Predicate predicate, const T& new_value) - - int intArray[8] = { 0, 3, 2, 7, 5, 4, 5, 3, }; - - // Convert 3s to 99s. - replace(intArray, intArray, 3, 99); // No-op - EATEST_VERIFY((intArray[1] == 3) && (intArray[7] == 3)); - replace(intArray, intArray + 8, 3, 99); // No-op - EATEST_VERIFY((intArray[1] == 99) && (intArray[7] == 99)); - - // Convert 99s to 88s. - replace_if(intArray, intArray, bind2nd(equal_to<int>(), (int)99), 88); // No-op - EATEST_VERIFY((intArray[1] == 99) && (intArray[7] == 99)); - replace_if(intArray, intArray + 8, bind2nd(equal_to<int>(), (int)99), 88); - EATEST_VERIFY((intArray[1] == 88) && (intArray[7] == 88)); - - - slist<TestObject> toList; - slist<TestObject>::iterator it; - toList.push_front(TestObject(3)); - toList.push_front(TestObject(5)); - toList.push_front(TestObject(4)); - toList.push_front(TestObject(5)); - toList.push_front(TestObject(7)); - toList.push_front(TestObject(2)); - toList.push_front(TestObject(3)); - toList.push_front(TestObject(0)); - - // Convert 3s to 99s. - replace(toList.begin(), toList.begin(), TestObject(3), TestObject(99)); // No-op - it = toList.begin(); - advance(it, 1); - EATEST_VERIFY(*it == TestObject(3)); - advance(it, 6); - EATEST_VERIFY(*it == TestObject(3)); - replace(toList.begin(), toList.end(), TestObject(3), TestObject(99)); - it = toList.begin(); - advance(it, 1); - EATEST_VERIFY(*it == TestObject(99)); - advance(it, 6); - EATEST_VERIFY(*it == TestObject(99)); - - // Convert 99s to 88s. - replace_if(toList.begin(), toList.begin(), bind2nd(equal_to<TestObject>(), TestObject(99)), TestObject(88)); // No-op - it = toList.begin(); - advance(it, 1); - EATEST_VERIFY(*it == TestObject(99)); - advance(it, 6); - EATEST_VERIFY(*it == TestObject(99)); - replace_if(toList.begin(), toList.end(), bind2nd(equal_to<TestObject>(), TestObject(99)), TestObject(88)); - it = toList.begin(); - advance(it, 1); - EATEST_VERIFY(*it == TestObject(88)); - advance(it, 6); - EATEST_VERIFY(*it == TestObject(88)); - } - - - { - // OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value) - // OutputIterator remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate) - - int intArray1[12] = { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }; - int intArray2[12] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; - - int* pInt = remove_copy(intArray1, intArray1, intArray2, 1); // No-op - EATEST_VERIFY(pInt == intArray2); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "remove_copy", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "remove_copy", 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1)); - - pInt = remove_copy(intArray1, intArray1 + 12, intArray2, 1); - EATEST_VERIFY(pInt == intArray2 + 6); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "remove_copy", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "remove_copy", 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, -1)); - - - pInt = remove_copy_if(intArray1, intArray1, intArray2, bind2nd(equal_to<int>(), (int)0)); // No-op - EATEST_VERIFY(pInt == intArray2); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "remove_copy_if", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "remove_copy_if", 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, -1)); - - pInt = remove_copy_if(intArray1, intArray1 + 12, intArray2, bind2nd(equal_to<int>(), (int)0)); - EATEST_VERIFY(pInt == intArray2 + 6); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "remove_copy_if", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "remove_copy_if", 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, -1)); - } - - - { - // ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T& value) - // ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, Predicate predicate) - - int intArray1[12] = { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }; - int intArray2[12] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; - - int* pInt = remove(intArray1, intArray1, 1); - EATEST_VERIFY(pInt == intArray1); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "remove", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - pInt = remove(intArray1, intArray1 + 12, 1); - EATEST_VERIFY(pInt == intArray1 + 6); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "remove", 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - - pInt = remove(intArray2, intArray2, 1); - EATEST_VERIFY(pInt == intArray2); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "remove", 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1)); - pInt = remove(intArray2, intArray2 + 12, 1); - EATEST_VERIFY(pInt == intArray2 + 12); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "remove", 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1)); - } - - - { - // ForwardIterator apply_and_remove(ForwardIterator first, ForwardIterator last, Function function, const T& - // value) ForwardIterator apply_and_remove_if(ForwardIterator first, ForwardIterator last, Function function, - // Predicate predicate) - - // Test for empty range and full container range - { - int intArray[12] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - int* pInt = apply_and_remove(intArray, intArray, func, 1); - EATEST_VERIFY(pInt == intArray); - EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove", 0, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", -1)); - pInt = apply_and_remove(intArray, intArray + 12, func, 1); - EATEST_VERIFY(pInt == intArray + 6); - EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "apply_and_remove", 0, 0, 0, 0, 0, 0, -1)); - EATEST_VERIFY( - VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", 1, 1, 1, 1, 1, 1, -1)); - } - - // Test for no match on empty range and full container range - { - int intArray[12] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - int* pInt = apply_and_remove(intArray, intArray, func, 1); - EATEST_VERIFY(pInt == intArray); - EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove", 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", -1)); - pInt = apply_and_remove(intArray, intArray + 12, func, 1); - EATEST_VERIFY(pInt == intArray + 12); - EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove", 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", -1)); - } - - // Test for empty range and full container range - { - int intArray[12] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - int* pInt = apply_and_remove_if(intArray, intArray, func, bind2nd(equal_to<int>(), (int)1)); - EATEST_VERIFY(pInt == intArray); - EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove_if", 0, 0, 1, 1, 0, 0, 1, 1, - 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", -1)); - pInt = apply_and_remove_if(intArray, intArray + 12, func, bind2nd(equal_to<int>(), (int)1)); - EATEST_VERIFY(pInt == intArray + 6); - EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "apply_and_remove_if", 0, 0, 0, 0, 0, 0, -1)); - EATEST_VERIFY( - VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", 1, 1, 1, 1, 1, 1, -1)); - } - - // Test for no match on empty range and full container range - { - int intArray[12] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - int* pInt = apply_and_remove_if(intArray, intArray, func, bind2nd(equal_to<int>(), (int)1)); - EATEST_VERIFY(pInt == intArray); - EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove_if", 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", -1)); - pInt = apply_and_remove_if(intArray, intArray + 12, func, bind2nd(equal_to<int>(), (int)1)); - EATEST_VERIFY(pInt == intArray + 12); - EATEST_VERIFY(VerifySequence(intArray, intArray + 12, int(), "apply_and_remove_if", 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", -1)); - } - - auto even = [](int a) { return (a % 2) == 0; }; - // Test to verify that the remaining element have stable ordering - { - int intArray[12] = {7, 8, 2, 3, 4, 5, 6, 0, 1, 9, 10, 11}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - int* pInt = apply_and_remove_if(intArray, intArray + 12, func, even); - EATEST_VERIFY(pInt == intArray + 6); - EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "apply_and_remove_if", 7, 3, 5, 1, 9, 11, -1)); - EATEST_VERIFY( - VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", 8, 2, 4, 6, 0, 10, -1)); - } - { - int intArray[12] = {7, 8, 0, 0, 4, 5, 6, 0, 1, 9, 0, 11}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - int* pInt = apply_and_remove(intArray, intArray + 12, func, 0); - EATEST_VERIFY(pInt == intArray + 8); - EATEST_VERIFY( - VerifySequence(intArray, intArray + 8, int(), "apply_and_remove", 7, 8, 4, 5, 6, 1, 9, 11, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", 0, 0, 0, 0, -1)); - } - - // Tests on a list (i.e. non-contiguous memory container) - { - list<int> intList = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - auto listIter = apply_and_remove_if(intList.begin(), intList.begin(), func, even); - EATEST_VERIFY(listIter == intList.begin()); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "apply_and_remove_if", 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", -1)); - listIter = apply_and_remove_if(intList.begin(), intList.end(), func, even); - EATEST_VERIFY(listIter == next(intList.begin(), 6)); - EATEST_VERIFY( - VerifySequence(intList.begin(), listIter, int(), "apply_and_remove_if", 1, 3, 5, 7, 9, 11, -1)); - EATEST_VERIFY( - VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", 0, 2, 4, 6, 8, 10, -1)); - } - { - list<int> intList = {0, 4, 2, 3, 4, 5, 6, 4, 4, 4, 10, 11}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - auto listIter = apply_and_remove(intList.begin(), intList.begin(), func, 4); - EATEST_VERIFY(listIter == intList.begin()); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "apply_and_remove", 0, 4, 2, 3, 4, 5, 6, - 4, 4, 4, 10, 11, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", -1)); - listIter = apply_and_remove(intList.begin(), intList.end(), func, 4); - EATEST_VERIFY(listIter == next(intList.begin(), 7)); - EATEST_VERIFY( - VerifySequence(intList.begin(), listIter, int(), "apply_and_remove", 0, 2, 3, 5, 6, 10, 11, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", 4, 4, 4, 4, 4, -1)); - } - - // Tests on a part of a container - { - vector<int> intVector = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - auto vectorIter = apply_and_remove_if(next(intVector.begin(), 3), prev(intVector.end(), 2), func, even); - EATEST_VERIFY(vectorIter == next(intVector.begin(), 7)); - EATEST_VERIFY( - VerifySequence(intVector.begin(), vectorIter, int(), "apply_and_remove_if", 0, 1, 2, 3, 5, 7, 9, -1)); - EATEST_VERIFY( - VerifySequence(prev(intVector.end(), 2), intVector.end(), int(), "apply_and_remove_if", 10, 11, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove_if", 4, 6, 8, -1)); - } - { - vector<int> intVector = {5, 1, 5, 3, 4, 5, 5, 7, 8, 5, 10, 5}; - vector<int> output; - auto func = [&output](int a) { output.push_back(a); }; - auto vectorIter = apply_and_remove(next(intVector.begin(), 2), prev(intVector.end(), 3), func, 5); - EATEST_VERIFY(vectorIter == next(intVector.begin(), 6)); - EATEST_VERIFY( - VerifySequence(intVector.begin(), vectorIter, int(), "apply_and_remove", 5, 1, 3, 4, 7, 8, -1)); - EATEST_VERIFY( - VerifySequence(prev(intVector.end(), 3), intVector.end(), int(), "apply_and_remove", 5, 10, 5, -1)); - EATEST_VERIFY(VerifySequence(output.begin(), output.end(), int(), "apply_and_remove", 5, 5, 5, -1)); - } - } - - - { - // OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value) - // OutputIterator replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate predicate, const T& new_value) - - int intArray1[12] = { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }; - int intArray2[12] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; - - int* pInt = replace_copy(intArray1, intArray1, intArray2, 1, 4); - EATEST_VERIFY(pInt == intArray2); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "replace_copy", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "replace_copy", 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1)); - - pInt = replace_copy(intArray1, intArray1 + 12, intArray2, 1, 4); - EATEST_VERIFY(pInt == intArray2 + 12); - EATEST_VERIFY(VerifySequence(intArray1, intArray1 + 12, int(), "replace_copy", 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, -1)); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 12, int(), "replace_copy", 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, -1)); - } - - - { - // void reverse(BidirectionalIterator first, BidirectionalIterator last) - - vector<int> intArray; - for(int i = 0; i < 10; i++) - intArray.push_back(i); - - reverse(intArray.begin(), intArray.begin()); // No-op - EATEST_VERIFY(VerifySequence(intArray.begin(), intArray.end(), int(), "reverse", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1)); - - reverse(intArray.begin(), intArray.end()); - EATEST_VERIFY(VerifySequence(intArray.begin(), intArray.end(), int(), "reverse", 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1)); - - - list<TestObject> toList; - for(int j = 0; j < 10; j++) - toList.push_back(TestObject(j)); - - reverse(toList.begin(), toList.begin()); // No-op - EATEST_VERIFY(toList.front() == TestObject(0)); - EATEST_VERIFY(toList.back() == TestObject(9)); - - reverse(toList.begin(), toList.end()); - EATEST_VERIFY(toList.front() == TestObject(9)); - EATEST_VERIFY(toList.back() == TestObject(0)); - - // Verify that reversing an empty range executes without exception. - reverse(toList.begin(), toList.begin()); - } - - - { - // reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result) - - vector<int> intArray1; - int intArray2[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; - - for(int i = 0; i < 10; i++) - intArray1.push_back(i); - - int* pInt = reverse_copy(intArray1.begin(), intArray1.begin(), intArray2); // No-op - EATEST_VERIFY(pInt == intArray2); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 10, int(), "reverse_copy", 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1)); - - pInt = reverse_copy(intArray1.begin(), intArray1.end(), intArray2); - EATEST_VERIFY(pInt == intArray2 + intArray1.size()); - EATEST_VERIFY(VerifySequence(intArray2, intArray2 + 10, int(), "reverse_copy", 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1)); - - - list<TestObject> toList; - TestObject toArray2[10]; - - for(int j = 0; j < 10; j++) - { - toList.push_back(TestObject(j)); - toArray2[j] = TestObject(5); - } - - TestObject* pTO = reverse_copy(toList.begin(), toList.begin(), toArray2); // No-op - EATEST_VERIFY(pTO == toArray2); - EATEST_VERIFY(toArray2[0] == TestObject(5)); - EATEST_VERIFY(toArray2[9] == TestObject(5)); - - pTO = reverse_copy(toList.begin(), toList.end(), toArray2); - EATEST_VERIFY(pTO == toArray2 + 10); - } - - - { - // ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) - // ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate predicate) - - // Test via bidirectional/random_access iterator. - basic_string<char> sTest("abcdefg abcdefg abcdefg"); - const char* pSubstring1 = " abcd"; - const char* pSubstring2 = "1234"; - - basic_string<char>::iterator iString = search(sTest.begin(), sTest.end(), pSubstring1, pSubstring1 + strlen(pSubstring1)); - EATEST_VERIFY(&*iString == &sTest[7]); - - iString = search(sTest.begin(), sTest.end(), pSubstring1, pSubstring1 + 1); // Search for sequence of 1. - EATEST_VERIFY(&*iString == &sTest[7]); - - iString = search(sTest.begin(), sTest.end(), pSubstring2, pSubstring2 + strlen(pSubstring2)); - EATEST_VERIFY(&*iString == sTest.end()); - - iString = search(sTest.begin(), sTest.end(), pSubstring2, pSubstring2); // Search with empty search pattern. - EATEST_VERIFY(&*iString == sTest.begin()); - - // Test via forward iterator. - slist<char> sListTest; - for(slist<char>::size_type i = sTest.size(); i > 0; --i) - sListTest.push_front(sTest[i - 1]); - - slist<char>::iterator iSlist = search(sListTest.begin(), sListTest.end(), pSubstring1, pSubstring1 + 5); - slist<char>::iterator i7 = sListTest.begin(); - advance(i7, 7); - EATEST_VERIFY(iSlist == i7); - - iSlist = search(sListTest.begin(), sListTest.end(), pSubstring2, pSubstring2 + strlen(pSubstring2)); - EATEST_VERIFY(iSlist == sListTest.end()); - - iSlist = search(sListTest.begin(), sListTest.end(), pSubstring2, pSubstring2); // Search with empty search pattern. - EATEST_VERIFY(iSlist == sListTest.begin()); - } - - - { - // ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value) - - const char* pString1 = "Hello wwworld"; - const char* presultult = search_n(pString1, pString1 + strlen(pString1), 1, 'w'); - EATEST_VERIFY(presultult == pString1 + 6); - } - - - { - // bool binary_search(ForwardIterator first, ForwardIterator last, const T& value) - // bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare compare) - - // ForwardIterator binary_search_i(ForwardIterator first, ForwardIterator last, const T& value) - // ForwardIterator binary_search_i(ForwardIterator first, ForwardIterator last, const T& value, Compare compare) - - vector<int> intArray; - for(int i = 0; i < 1000; i++) - intArray.push_back(i); - - bool b = binary_search(intArray.begin(), intArray.begin(), 0); - EATEST_VERIFY(b == false); - - b = binary_search(intArray.begin(), intArray.begin() + 1, 0); - EATEST_VERIFY(b == true); - - b = binary_search(intArray.begin(), intArray.end(), 733, less<int>()); - EATEST_VERIFY(b == true); - - - vector<int>::iterator it = binary_search_i(intArray.begin(), intArray.begin(), 0); - EATEST_VERIFY(it == intArray.begin()); - - it = binary_search_i(intArray.begin(), intArray.begin() + 1, 0, less<int>()); - EATEST_VERIFY(it == intArray.begin()); - - it = binary_search_i(intArray.begin(), intArray.end(), 733); - EATEST_VERIFY(it == intArray.begin() + 733); - - - list<TestObject> toList; - list<TestObject>::iterator toI; - for(int j = 0; j < 1000; j++) - toList.push_back(TestObject(j)); - - b = binary_search(toList.begin(), toList.begin(), TestObject(0), less<TestObject>()); - EATEST_VERIFY(b == false); - - toI = toList.begin(); - toI++; - b = binary_search(toList.begin(), toI, TestObject(0)); - EATEST_VERIFY(b == true); - - b = binary_search(toList.begin(), toList.end(), TestObject(733)); - EATEST_VERIFY(b == true); - - - toI = binary_search_i(toList.begin(), toList.begin(), TestObject(0), less<TestObject>()); // No-op - EATEST_VERIFY(toI == toList.begin()); - - toI = toList.begin(); - toI++; - toI = binary_search_i(toList.begin(), toI, TestObject(0)); - EATEST_VERIFY(*toI == TestObject(0)); - - toI = binary_search_i(toList.begin(), toList.end(), TestObject(733)); - EATEST_VERIFY(*toI == TestObject(733)); - } - - - { - // ForwardIterator unique(ForwardIterator first, ForwardIterator last) - // ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate predicate) - - int intArray[] = { 1, 2, 3, 3, 4, 4 }; - - int* pInt = unique(intArray, intArray + 0); - EATEST_VERIFY(pInt == intArray); - EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "unique", 1, 2, 3, 3, 4, 4, -1)); - - pInt = unique(intArray, intArray + 6, equal_to<int>()); - EATEST_VERIFY(pInt == intArray + 4); - EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "unique", 1, 2, 3, 4, 4, 4, -1)); - - - TestObject toArray[] = { TestObject(1), TestObject(2), TestObject(3), TestObject(3), TestObject(4), TestObject(4) }; - - TestObject* pTO = unique(toArray, toArray + 6); - EATEST_VERIFY(pTO == toArray + 4); - EATEST_VERIFY(toArray[3] == TestObject(4)); - } - - - { - // ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) - // ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate predicate) - - // Test via bidirectional/random_access iterator. - basic_string<char> sTest("abcdefg abcdefg abcdefg"); - const char* pSubstring1 = "abcd"; - const char* pSubstring2 = "1234"; - - basic_string<char>::iterator iString = find_end(sTest.begin(), sTest.end(), pSubstring1, pSubstring1 + 4); - EATEST_VERIFY(&*iString == &sTest[16]); - - iString = find_end(sTest.begin(), sTest.end(), pSubstring1, pSubstring1 + 4, equal_to<char>()); - EATEST_VERIFY(&*iString == &sTest[16]); - - iString = find_end(sTest.begin(), sTest.end(), pSubstring2, pSubstring2 + strlen(pSubstring2)); - EATEST_VERIFY(iString == sTest.end()); - - iString = find_end(sTest.begin(), sTest.end(), pSubstring2, pSubstring2 + strlen(pSubstring2), equal_to<char>()); - EATEST_VERIFY(iString == sTest.end()); - - // Test via forward iterator. - slist<char> sListTest; - for(slist<char>::size_type i = sTest.size(); i > 0; --i) - sListTest.push_front(sTest[i - 1]); - - slist<char>::iterator iSlist = find_end(sListTest.begin(), sListTest.end(), pSubstring1, pSubstring1 + strlen(pSubstring1)); - slist<char>::iterator i16 = sListTest.begin(); - advance(i16, 16); - EATEST_VERIFY(iSlist == i16); - - iSlist = find_end(sListTest.begin(), sListTest.end(), pSubstring1, pSubstring1 + strlen(pSubstring1), equal_to<char>()); - i16 = sListTest.begin(); - advance(i16, 16); - EATEST_VERIFY(iSlist == i16); - - iSlist = find_end(sListTest.begin(), sListTest.end(), pSubstring2, pSubstring2 + strlen(pSubstring2)); - EATEST_VERIFY(iSlist == sListTest.end()); - - iSlist = find_end(sListTest.begin(), sListTest.end(), pSubstring2, pSubstring2 + strlen(pSubstring2), equal_to<char>()); - EATEST_VERIFY(iSlist == sListTest.end()); - } - - - { - // OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) - // OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare compare) - - int intArray1[] = { 0, 0, 2, 5, 8, 8, 12, 24, 26, 43 }; - int intArray2[] = { 0, 0, 0, 5, 7, 8, 11, 24, 25, 43 }; - int intArray3[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; - - set_difference(intArray1, intArray1 + 0, intArray2, intArray2 + 0, intArray3); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_difference", 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -1)); - - set_difference(intArray1, intArray1 + 10, intArray2, intArray2 + 10, intArray3); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_difference", 2, 8, 12, 26, 9, 9, 9, 9, 9, 9, -1)); - - intArray3[0] = intArray3[1] = intArray3[2] = 9; - - set_difference(intArray1, intArray1 + 10, intArray2, intArray2 + 10, intArray3, less<int>()); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_difference", 2, 8, 12, 26, 9, 9, 9, 9, 9, 9, -1)); - } - - - { - // OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) - // OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare compare) - - int intArray1[] = { 0, 0, 2, 5, 8, 8, 12, 24, 26, 43 }; - int intArray2[] = { 0, 0, 0, 5, 7, 8, 11, 24, 25, 43 }; - int intArray3[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; - - set_symmetric_difference(intArray1, intArray1 + 0, intArray2, intArray2 + 0, intArray3); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_symmetric_difference", 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -1)); - - set_symmetric_difference(intArray1, intArray1 + 10, intArray2, intArray2 + 10, intArray3); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_symmetric_difference", 0, 2, 7, 8, 11, 12, 25, 26, 9, 9, -1)); - - intArray3[0] = intArray3[1] = intArray3[2] = intArray3[4] = intArray3[5] = intArray3[6] = 9; - - set_symmetric_difference(intArray1, intArray1 + 10, intArray2, intArray2 + 10, intArray3, less<int>()); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_symmetric_difference", 0, 2, 7, 8, 11, 12, 25, 26, 9, 9, -1)); - } - - - { - // OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) - // OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare compare) - - int intArray1[] = { 0, 0, 2, 5, 8, 8, 12, 24, 26, 43 }; - int intArray2[] = { 0, 0, 0, 5, 7, 8, 11, 24, 25, 43 }; - int intArray3[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; - - set_intersection(intArray1, intArray1 + 0, intArray2, intArray2 + 0, intArray3); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_intersection", 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -1)); - - set_intersection(intArray1, intArray1 + 10, intArray2, intArray2 + 10, intArray3); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_intersection", 0, 0, 5, 8, 24, 43, 9, 9, 9, 9, -1)); - - intArray3[0] = intArray3[1] = intArray3[2] = intArray3[4] = intArray3[5] = intArray3[6] = 9; - - set_intersection(intArray1, intArray1 + 10, intArray2, intArray2 + 10, intArray3, less<int>()); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 10, int(), "set_intersection", 0, 0, 5, 8, 24, 43, 9, 9, 9, 9, -1)); - } - - - { - // OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) - // OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare compare) - - int intArray1[] = { 0, 0, 2, 5, 8, 8, 12, 24, 26, 43 }; - int intArray2[] = { 0, 0, 0, 5, 7, 8, 11, 24, 25, 43 }; - int intArray3[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; - - set_union(intArray1, intArray1 + 0, intArray2, intArray2 + 0, intArray3); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 20, int(), "set_union", 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, -1)); - - set_union(intArray1, intArray1 + 10, intArray2, intArray2 + 10, intArray3); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 20, int(), "set_union", 0, 0, 0, 2, 5, 7, 8, 8, 11, 12, 24, 25, 26, 43, 9, 9, 9, 9, 9, 9, -1)); - - intArray3[0] = intArray3[1] = intArray3[2] = intArray3[3] = intArray3[4] = intArray3[5] = intArray3[6] = intArray3[7] = intArray3[8] = intArray3[9] = intArray3[10] = intArray3[11] = 9; - - set_union(intArray1, intArray1 + 10, intArray2, intArray2 + 10, intArray3, less<int>()); - EATEST_VERIFY(VerifySequence(intArray3, intArray3 + 20, int(), "set_union", 0, 0, 0, 2, 5, 7, 8, 8, 11, 12, 24, 25, 26, 43, 9, 9, 9, 9, 9, 9, -1)); - } - - - // set_difference_2 - { - // template <typename InputIterator1, typename InputIterator2, typename OutputIterator> - // void set_difference_2(InputIterator1 first1, InputIterator1 last1, - // InputIterator2 first2, InputIterator2 last2, - // OutputIterator result1, OutputIterator result2) - { - const eastl::vector<int> v1 = {1, 2, 4, 5, 7, 7, 9}; - const eastl::vector<int> v2 = { 2, 6, 9}; - eastl::vector<int> only_v1, only_v2; - - eastl::set_difference_2(v1.begin(), v1.end(), v2.begin(), v2.end(), - eastl::inserter(only_v1, only_v1.begin()), - eastl::inserter(only_v2, only_v2.begin())); - - EATEST_VERIFY((only_v1 == eastl::vector<int>{1, 4, 5, 7, 7})); - EATEST_VERIFY((only_v2 == eastl::vector<int>{6})); - } - - // template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare> - // void set_difference_2(InputIterator1 first1, InputIterator1 last1, - // InputIterator2 first2, InputIterator2 last2, - // OutputIterator result1, OutputIterator result2, Compare compare) - { - struct local - { - int data = -1; - bool operator==(const local& other) const - { return data == other.data; } - }; - - const eastl::vector<local> v1 = {{1}, {2}, {4}, {5}, {7}, {7}, {9}}; - const eastl::vector<local> v2 = { {2}, {6}, {9}}; - eastl::vector<local> only_v1, only_v2; - - eastl::set_difference_2(v1.begin(), v1.end(), v2.begin(), v2.end(), - eastl::inserter(only_v1, only_v1.begin()), - eastl::inserter(only_v2, only_v2.begin()), - [](const local& lhs, const local& rhs) { return lhs.data < rhs.data; }); - - EATEST_VERIFY((only_v1 == eastl::vector<local>{{1}, {4}, {5}, {7}, {7}})); - EATEST_VERIFY((only_v2 == eastl::vector<local>{{6}})); - } - } - - - // set_decomposition - { - // OutputIterator3 set_decomposition(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, - // OutputIterator1 result1, OutputIterator2 result2, OutputIterator3 result3) - { - const eastl::vector<int> v1 = {1, 2, 4, 5, 7, 7, 9}; - const eastl::vector<int> v2 = { 2, 6, 9}; - eastl::vector<int> only_v1, only_v2, intersection; - - eastl::set_decomposition(v1.begin(), v1.end(), v2.begin(), v2.end(), - eastl::inserter(only_v1, only_v1.begin()), - eastl::inserter(only_v2, only_v2.begin()), - eastl::inserter(intersection, intersection.begin())); - - EATEST_VERIFY((only_v1 == eastl::vector<int>{1, 4, 5, 7, 7})); - EATEST_VERIFY((only_v2 == eastl::vector<int>{6})); - EATEST_VERIFY((intersection == eastl::vector<int>{2, 9})); - } - - // OutputIterator3 set_decomposition(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, - // OutputIterator1 result1, OutputIterator2 result2, OutputIterator3 result3, Compare compare) - { - struct local - { - int data = -1; - bool operator==(const local& other) const - { return data == other.data; } - }; - - const eastl::vector<local> v1 = {{1}, {2}, {4}, {5}, {7}, {7}, {9}}; - const eastl::vector<local> v2 = { {2}, {6}, {9}}; - eastl::vector<local> only_v1, only_v2, intersection; - - eastl::set_decomposition(v1.begin(), v1.end(), v2.begin(), v2.end(), - eastl::inserter(only_v1, only_v1.begin()), - eastl::inserter(only_v2, only_v2.begin()), - eastl::inserter(intersection, intersection.begin()), - [](const local& lhs, const local& rhs) { return lhs.data < rhs.data; }); - - EATEST_VERIFY((only_v1 == eastl::vector<local>{{1}, {4}, {5}, {7}, {7}})); - EATEST_VERIFY((only_v2 == eastl::vector<local>{{6}})); - EATEST_VERIFY((intersection == eastl::vector<local>{{2}, {9}})); - } - } - - { - // template<typename ForwardIterator1, typename ForwardIterator2> - // bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) - - // template<typename ForwardIterator1, typename ForwardIterator2, class BinaryPredicate> - // bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate predicate) - EASTLTest_Rand eastlRNG(EA::UnitTest::GetRandSeed()); - - { - int intArray1[] = { 0, 1, 2, 3, 4 }; - int intArray2[] = { 0, 1, 2, 3, 4 }; - - // Test an empty set. - EATEST_VERIFY(eastl::is_permutation(intArray1, intArray1 + 0, intArray2)); - - // Test two identical sets. - EATEST_VERIFY(eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2)); - eastl::random_shuffle(intArray1, intArray1 + EAArrayCount(intArray1), eastlRNG); - - // Test order randomization. - EATEST_VERIFY(eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2)); - eastl::random_shuffle(intArray2, intArray2 + EAArrayCount(intArray2), eastlRNG); - EATEST_VERIFY(eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2)); - - // Test the case where there's a difference. - intArray2[4] = intArray2[3]; // This change guarantees is_permutation will return false. - EATEST_VERIFY(!eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2)); - } - - { - int intArray1[] = { 0, 0, 0, 1, 1 }; - int intArray2[] = { 0, 0, 0, 1, 1 }; - - // Test two identical sets. - EATEST_VERIFY(eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2)); - eastl::random_shuffle(intArray1, intArray1 + EAArrayCount(intArray1), eastlRNG); - - // Test order randomization. - EATEST_VERIFY(eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2)); - eastl::random_shuffle(intArray2, intArray2 + EAArrayCount(intArray2), eastlRNG); - EATEST_VERIFY(eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2)); - - // Test the case where there's a difference. - intArray2[4] = (intArray2[4] == 0) ? 1 : 0; - EATEST_VERIFY(!eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2)); - } - - for(int n = 0; n < 100000; n++) - { - eastl_size_t intArray1[6]; - eastl_size_t intArray2[6]; - - for(size_t i = 0; i < EAArrayCount(intArray1); i++) - { - intArray1[i] = eastlRNG.RandLimit(6); - intArray2[i] = eastlRNG.RandLimit(6); - } - - bool isPermutation = eastl::is_permutation(intArray1, intArray1 + EAArrayCount(intArray1), intArray2); - - // If is_permutation returned true, then sorted versions of the two arrays should be identical. - eastl::sort(intArray1, intArray1 + EAArrayCount(intArray1)); - eastl::sort(intArray2, intArray2 + EAArrayCount(intArray2)); - - eastl::pair<eastl_size_t*, eastl_size_t*> mismatchResult = eastl::mismatch(intArray1, intArray1 + EAArrayCount(intArray1), intArray2); - bool isIdentical = (mismatchResult.first == (intArray1 + EAArrayCount(intArray1))); - - EATEST_VERIFY(isPermutation == isIdentical); // With an array size of 6, isPermutation ends up being true about 1 in 400 times here. - } - } - - { - //template<typename BidirectionalIterator> - //bool next_permutation(BidirectionalIterator first, BidirectionalIterator last); - - //template<typename BidirectionalIterator, typename Compare> - //bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare compare); - - uint64_t count; - vector<int> intArray; - for(int i = 0; i < 8; i++) - intArray.push_back(i); - - count = 0; - do { - ++count; - } while(next_permutation(intArray.begin(), intArray.end())); - EATEST_VERIFY(count == 40320); // count = n! - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - - count = 0; - do { - ++count; - } while(next_permutation(intArray.begin(), intArray.end(), eastl::less<int>())); - EATEST_VERIFY(count == 40320); // count = n! - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - } - - - { - // template <typename ForwardIterator> - // ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); - - // eastl::array (ContiguousIterator/Pointer) - const eastl_size_t kRotateArraySize = 10; - typedef eastl::array<int, kRotateArraySize> IntArray; - - { // This type is templated, so we can't run a loop over various sizes. - IntArray intArray; - - for(eastl_size_t i = 0; i < kRotateArraySize; i++) - { - eastl::generate_n(intArray.begin(), kRotateArraySize, GenerateIncrementalIntegers<int>()); - IntArray::iterator intArrayItMiddle = eastl::next(intArray.begin(), i); - IntArray::iterator intArrayIt = eastl::rotate(intArray.begin(), intArrayItMiddle, intArray.end()); - - for(eastl_size_t j = 0; j < kRotateArraySize; j++) - { - if(intArrayIt == intArray.end()) - intArrayIt = intArray.begin(); - EATEST_VERIFY(*intArrayIt++ == (int)j); - } - } - } - - // eastl::vector (ContiguousIterator) - typedef eastl::vector<int> IntVector; - - for(eastl_size_t s = 10; s < 500; s += (eastl_size_t)rng.RandRange(50, 100)) - { - IntVector intVector(s, 0); - - for(eastl_size_t i = 0; i < s; i++) - { - eastl::generate_n(intVector.begin(), s, GenerateIncrementalIntegers<int>()); - IntVector::iterator intVectorItMiddle = eastl::next(intVector.begin(), i); - IntVector::iterator intVectorIt = eastl::rotate(intVector.begin(), intVectorItMiddle, intVector.end()); - - for(eastl_size_t j = 0; j < s; j++) - { - if(intVectorIt == intVector.end()) - intVectorIt = intVector.begin(); - EATEST_VERIFY(*intVectorIt++ == (int)j); - } - } - } - - // eastl::deque (RandomAccessIterator) - typedef eastl::deque<int> IntDeque; - - for(eastl_size_t s = 10; s < 500; s += (eastl_size_t)rng.RandRange(50, 100)) - { - IntDeque intDeque(s, 0); - - for(eastl_size_t i = 0; i < s; i++) - { - eastl::generate_n(intDeque.begin(), s, GenerateIncrementalIntegers<int>()); - IntDeque::iterator intDequeItMiddle = eastl::next(intDeque.begin(), i); - IntDeque::iterator intDequeIt = eastl::rotate(intDeque.begin(), intDequeItMiddle, intDeque.end()); - - for(eastl_size_t j = 0; j < s; j++) - { - if(intDequeIt == intDeque.end()) - intDequeIt = intDeque.begin(); - EATEST_VERIFY(*intDequeIt++ == (int)j); - } - } - } - - // eastl::list (BidirectionalIterator) - typedef eastl::list<int> IntList; - - for(eastl_size_t s = 10; s < 500; s += (eastl_size_t)rng.RandRange(50, 100)) - { - IntList intList(s, 0); - - for(eastl_size_t i = 0; i < s; i++) - { - eastl::generate_n(intList.begin(), s, GenerateIncrementalIntegers<int>()); - IntList::iterator intListItMiddle = eastl::next(intList.begin(), i); - IntList::iterator intListIt = eastl::rotate(intList.begin(), intListItMiddle, intList.end()); - - for(eastl_size_t j = 0; j < s; j++) - { - if(intListIt == intList.end()) - intListIt = intList.begin(); - EATEST_VERIFY(*intListIt++ == (int)j); - } - } - } - - // eastl::slist (ForwardIterator) - typedef eastl::slist<int> IntSlist; - - for(eastl_size_t s = 10; s < 500; s += (eastl_size_t)rng.RandRange(50, 100)) - { - IntSlist intSlist(s, 0); - - for(eastl_size_t i = 0; i < s; i++) - { - eastl::generate_n(intSlist.begin(), s, GenerateIncrementalIntegers<int>()); - IntSlist::iterator intSlistItMiddle = eastl::next(intSlist.begin(), i); - IntSlist::iterator intSlistIt = eastl::rotate(intSlist.begin(), intSlistItMiddle, intSlist.end()); - - for(eastl_size_t j = 0; j < s; j++) - { - if(intSlistIt == intSlist.end()) - intSlistIt = intSlist.begin(); - EATEST_VERIFY(*intSlistIt++ == (int)j); - } - } - } - } - - // test eastl::sort with move-only type - { - { - eastl::vector<eastl::unique_ptr<int>> vec; - eastl::sort(vec.begin(), vec.end(), [](const eastl::unique_ptr<int>& lhs, const eastl::unique_ptr<int>& rhs) { return *lhs < *rhs; }); - } - { - eastl::vector<eastl::unique_ptr<int>> vec; - eastl::sort(vec.begin(), vec.end()); - } - { - eastl::vector<MissingMoveConstructor> vec; - eastl::sort(vec.begin(), vec.end(), [](const MissingMoveConstructor& lhs, const MissingMoveConstructor& rhs) { return lhs < rhs; }); - } - { - eastl::vector<MissingMoveConstructor> vec; - eastl::sort(vec.begin(), vec.end()); - } - { - eastl::vector<MissingMoveAssignable> vec; - eastl::sort(vec.begin(), vec.end(), [](const MissingMoveAssignable& lhs, const MissingMoveAssignable& rhs) { return lhs < rhs; }); - } - { - eastl::vector<MissingMoveAssignable> vec; - eastl::sort(vec.begin(), vec.end()); - } - { - eastl::vector<eastl::unique_ptr<int>> vec; - vec.emplace_back(new int(7)); - vec.emplace_back(new int(-42)); - vec.emplace_back(new int(5)); - eastl::sort(vec.begin(), vec.end(), [](const eastl::unique_ptr<int>& lhs, const eastl::unique_ptr<int>& rhs) { return *lhs < *rhs; }); - EATEST_VERIFY(*vec[0] == -42); - EATEST_VERIFY(*vec[1] == 5); - EATEST_VERIFY(*vec[2] == 7); - } - { - for (unsigned tests = 0; tests < 50; ++tests) - { - eastl::vector<eastl::unique_ptr<int>> vec1; - - for (int i = 0; i < 100; ++i) - { - int randomNumber = rng(); - vec1.emplace_back(new int(randomNumber)); - } - - auto vec1Cmp = [](const eastl::unique_ptr<int>& lhs, const eastl::unique_ptr<int>& rhs) { return *lhs < *rhs; }; - eastl::sort(vec1.begin(), vec1.end(), vec1Cmp); - EATEST_VERIFY(eastl::is_sorted(vec1.begin(), vec1.end(), vec1Cmp)); - } - } - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} diff --git a/test/source/TestAllocator.cpp b/test/source/TestAllocator.cpp deleted file mode 100644 index 2a28c07..0000000 --- a/test/source/TestAllocator.cpp +++ /dev/null @@ -1,405 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/allocator.h> -#include <EASTL/allocator_malloc.h> -#include <EASTL/fixed_allocator.h> -#include <EASTL/core_allocator_adapter.h> -#include <EASTL/list.h> -#include <EAStdC/EAString.h> -#include <EAStdC/EAAlignment.h> - - - -/////////////////////////////////////////////////////////////////////////////// -// fixed_pool_reference -// -struct fixed_pool_reference -{ -public: - fixed_pool_reference(const char* = NULL) - { - mpFixedPool = NULL; - } - - fixed_pool_reference(eastl::fixed_pool& fixedPool) - { - mpFixedPool = &fixedPool; - } - - fixed_pool_reference(const fixed_pool_reference& x) - { - mpFixedPool = x.mpFixedPool; - } - - fixed_pool_reference& operator=(const fixed_pool_reference& x) - { - mpFixedPool = x.mpFixedPool; - return *this; - } - - void* allocate(size_t /*n*/, int /*flags*/ = 0) - { - return mpFixedPool->allocate(); - } - - void* allocate(size_t /*n*/, size_t /*alignment*/, size_t /*offset*/, int /*flags*/ = 0) - { - return mpFixedPool->allocate(); - } - - void deallocate(void* p, size_t /*n*/) - { - return mpFixedPool->deallocate(p); - } - - const char* get_name() const - { - return "fixed_pool_reference"; - } - - void set_name(const char* /*pName*/) - { - } - -protected: - friend bool operator==(const fixed_pool_reference& a, const fixed_pool_reference& b); - friend bool operator!=(const fixed_pool_reference& a, const fixed_pool_reference& b); - - eastl::fixed_pool* mpFixedPool; -}; - - -inline bool operator==(const fixed_pool_reference& a, const fixed_pool_reference& b) -{ - return (a.mpFixedPool == b.mpFixedPool); -} - -inline bool operator!=(const fixed_pool_reference& a, const fixed_pool_reference& b) -{ - return (a.mpFixedPool != b.mpFixedPool); -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedAllocator -// -EA_DISABLE_VC_WARNING(6262) -static int TestFixedAllocator() -{ - using namespace eastl; - - int nErrorCount = 0; - - { // fixed_allocator - typedef eastl::list<int, fixed_allocator> IntList; - typedef IntList::node_type IntListNode; - - const size_t kBufferCount = 200; - IntListNode buffer1[kBufferCount]; - IntList intList1; - const size_t kAlignOfIntListNode = EA_ALIGN_OF(IntListNode); - - intList1.get_allocator().init(buffer1, sizeof(buffer1), sizeof(IntListNode), kAlignOfIntListNode); - - for(size_t i = 0; i < kBufferCount; i++) - intList1.push_back(0); - - EATEST_VERIFY(intList1.size() == kBufferCount); - - // Try making a copy. - IntListNode buffer2[kBufferCount]; - IntList intList2; - intList2.get_allocator().init(buffer2, sizeof(buffer2), sizeof(IntListNode), kAlignOfIntListNode); - intList2 = intList1; - EATEST_VERIFY(intList2.size() == kBufferCount); - } - - // fixed_allocator_with_overflow, ensure allocations are coming from fixed buffer. This is to - // prevent a reported user regression where all allocations were being routed to the overflow - // allocator. - { - const int DEFAULT_VALUE = 0xbaadf00d; - const int TEST_VALUE = 0x12345689; - const size_t kBufferCount = 10; - - typedef eastl::list<int, fixed_allocator_with_overflow> IntList; - typedef IntList::node_type IntListNode; - - const size_t kAlignOfIntListNode = EA_ALIGN_OF(IntListNode); - - // ensure the fixed buffer contains the default value that will be replaced - IntListNode buffer1[kBufferCount]; - for (int i = 0; i < kBufferCount; i++) - { - buffer1[i].mValue = DEFAULT_VALUE; - EATEST_VERIFY(buffer1[i].mValue == DEFAULT_VALUE); - } - - IntList intList1; - - // replace all the values in the local buffer with the test value - intList1.get_allocator().init(buffer1, sizeof(buffer1), sizeof(IntListNode), kAlignOfIntListNode); - for (size_t i = 0; i < kBufferCount; i++) - intList1.push_back(TEST_VALUE); - - // ensure the local buffer has been altered with the contents of the list::push_back - for (int i = 0; i < kBufferCount; i++) - { - EATEST_VERIFY(buffer1[i].mValue == TEST_VALUE); - } - - intList1.clear(); - } - - { // fixed_allocator_with_overflow - typedef eastl::list<int, fixed_allocator_with_overflow> IntList; - typedef IntList::node_type IntListNode; - - const size_t kBufferCount = 200; - IntListNode buffer1[kBufferCount]; - IntList intList1; - const size_t kAlignOfIntListNode = EA_ALIGN_OF(IntListNode); - - intList1.get_allocator().init(buffer1, sizeof(buffer1), sizeof(IntListNode), kAlignOfIntListNode); - - for(size_t i = 0; i < kBufferCount * 2; i++) - intList1.push_back(0); - - EATEST_VERIFY(intList1.size() == (kBufferCount * 2)); - - // Try making a copy. - IntListNode buffer2[kBufferCount]; - IntList intList2; - intList2.get_allocator().init(buffer2, sizeof(buffer2), sizeof(IntListNode), kAlignOfIntListNode); - intList2 = intList1; - EATEST_VERIFY(intList2.size() == (kBufferCount * 2)); - } - - { - // fixed_pool_reference - typedef eastl::list<int, fixed_pool_reference> WidgetList; - - WidgetList::node_type buffer[16]; - eastl::fixed_pool myPool(buffer, sizeof(buffer), sizeof(WidgetList::node_type), 16); - - WidgetList myList1(myPool); - WidgetList myList2(myPool); - - myList1.push_back(1); - myList2.push_back(1); - EATEST_VERIFY(myList1 == myList2); - - myList1.push_back(2); - myList1.sort(); - myList2.push_front(2); - myList2.sort(); - EATEST_VERIFY(myList1 == myList2); - } - - return nErrorCount; -} -EA_RESTORE_VC_WARNING() - - -/////////////////////////////////////////////////////////////////////////////// -// TestAllocatorMalloc -// -static int TestAllocatorMalloc() -{ - int nErrorCount = 0; - - { - typedef eastl::list<int, eastl::allocator_malloc> WidgetList; - - WidgetList myList1; - WidgetList myList2; - - myList1.push_back(1); - myList2.push_back(1); - EATEST_VERIFY(myList1 == myList2); - - myList1.push_back(2); - myList1.sort(); - myList2.push_front(2); - myList2.sort(); - EATEST_VERIFY(myList1 == myList2); - - #if EASTL_ALIGNED_MALLOC_AVAILABLE - - #endif - } - - return nErrorCount; -} - - - -#if EASTL_DLL - void* operator new[](size_t size, const char* pName, int flags, unsigned debugFlags, const char* file, int line); - void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName, int flags, unsigned debugFlags, const char* file, int line); -#endif - - -struct EASTLTestCoreAllocator -{ -public: - void* Alloc(size_t size, const char* name, unsigned int flags) - { - return ::operator new[](size, name, flags, 0, __FILE__, __LINE__); - } - - void* Alloc(size_t size, const char* name, unsigned int flags, - unsigned int alignment, unsigned int alignOffset = 0) - { - return ::operator new[](size, alignment, alignOffset, name, flags, 0, __FILE__, __LINE__); - } - - void Free(void* p, size_t /*size*/ = 0) - { - ::operator delete((char*)p); - } - - static EASTLTestCoreAllocator* GetDefaultAllocator(); -}; - -EASTLTestCoreAllocator gEASTLTestCoreAllocator; - -EASTLTestCoreAllocator* EASTLTestCoreAllocator::GetDefaultAllocator() -{ - return &gEASTLTestCoreAllocator; -} - - - -struct TestClass -{ - mutable int mX; - - TestClass() : mX(37) { } - - void Increment() - { mX++; } - - void IncrementConst() const - { mX++; } - - int MultiplyBy(int x) - { return mX * x; } - - int MultiplyByConst(int x) const - { return mX * x; } -}; - -/////////////////////////////////////////////////////////////////////////////// -// TestCoreAllocatorAdapter -// -static int TestCoreAllocatorAdapter() -{ - int nErrorCount = 0; - -#if EASTL_CORE_ALLOCATOR_ENABLED - typedef EA::Allocator::CoreAllocatorAdapter<EASTLTestCoreAllocator> Adapter; - - eastl::list<TestClass, Adapter> widgetList(Adapter("UI/WidgetList", &gEASTLTestCoreAllocator)); - widgetList.push_back(TestClass()); - EATEST_VERIFY(widgetList.size() == 1); - - eastl::vector<TestClass, Adapter> widgetVector(100, Adapter("UI/WidgetVector", &gEASTLTestCoreAllocator)); - widgetVector.push_back(TestClass()); - EATEST_VERIFY(widgetVector.size() == 101); - - eastl::vector<TestClass, Adapter> widgetVector2(widgetVector); - widgetVector2.resize(400); - EATEST_VERIFY(widgetVector2.size() == 400); -#endif - - return nErrorCount; -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestSwapAllocator -// -static int TestSwapAllocator() -{ - int nErrorCount = 0; - - { - InstanceAllocator a(nullptr, (uint8_t)111), b(nullptr, (uint8_t)222); - eastl::swap(a, b); - - EATEST_VERIFY(a.mInstanceId == 222); - EATEST_VERIFY(b.mInstanceId == 111); - - EATEST_VERIFY(EA::StdC::Strcmp(a.get_name(), "InstanceAllocator 222") == 0); - EATEST_VERIFY(EA::StdC::Strcmp(b.get_name(), "InstanceAllocator 111") == 0); - } - - return nErrorCount; -} - -static int TestAllocationOffsetAndAlignment() -{ - int nErrorCount = 0; - - auto testAllocatorAlignment = [&nErrorCount](int requestedSize, int requestedAlignment, int requestedOffset) - { - CountingAllocator::resetCount(); - CountingAllocator a; - - void* p = allocate_memory(a, requestedSize, requestedAlignment, requestedOffset); - - EATEST_VERIFY(p != nullptr); - EATEST_VERIFY(EA::StdC::IsAligned(p, requestedAlignment)); - - a.deallocate(p, requestedSize); - EATEST_VERIFY(CountingAllocator::getActiveAllocationSize() == 0); - }; - - testAllocatorAlignment(100, 1, 0); - testAllocatorAlignment(100, 2, 0); - testAllocatorAlignment(100, 4, 0); - testAllocatorAlignment(100, 8, 0); - testAllocatorAlignment(100, 16, 0); - - testAllocatorAlignment(100, 1, 16); - testAllocatorAlignment(100, 2, 16); - testAllocatorAlignment(100, 4, 16); - testAllocatorAlignment(100, 8, 16); - testAllocatorAlignment(100, 16, 16); - - return nErrorCount; -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestAllocator -// -int TestAllocator() -{ - int nErrorCount = 0; - - nErrorCount += TestAllocationOffsetAndAlignment(); - nErrorCount += TestFixedAllocator(); - nErrorCount += TestAllocatorMalloc(); - nErrorCount += TestCoreAllocatorAdapter(); - nErrorCount += TestSwapAllocator(); - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestAny.cpp b/test/source/TestAny.cpp deleted file mode 100644 index fedc85f..0000000 --- a/test/source/TestAny.cpp +++ /dev/null @@ -1,472 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/any.h> -#include <EASTL/vector.h> -#include <EASTL/string.h> -#include <EASTL/numeric.h> -#include <EAStdC/EAString.h> - - -// SmallTestObject -// -struct SmallTestObject -{ - static int mCtorCount; - - SmallTestObject() EA_NOEXCEPT { mCtorCount++; } - SmallTestObject(const SmallTestObject&) EA_NOEXCEPT { mCtorCount++; } - SmallTestObject(SmallTestObject&&) EA_NOEXCEPT { mCtorCount++; } - SmallTestObject& operator=(const SmallTestObject&) EA_NOEXCEPT { mCtorCount++; return *this; } - ~SmallTestObject() EA_NOEXCEPT { mCtorCount--; } - - static void Reset() { mCtorCount = 0; } - static bool IsClear() { return mCtorCount == 0; } -}; - -int SmallTestObject::mCtorCount = 0; - - -// RequiresInitList -// -struct RequiresInitList -{ - RequiresInitList(std::initializer_list<int> ilist) - : sum(eastl::accumulate(begin(ilist), end(ilist), 0)) {} - - int sum; -}; - - -int TestAny() -{ - using namespace eastl; - int nErrorCount = 0; - - // NOTE(rparolin): Ensure 'any' is at least the size of an eastl::string and an eastl::vector to prevent heap - // allocation of handle objects (objects that point to a heap allocation). This will reduce memory pressure since - // eastl::string will be a commonly used type. We could also test with a vector. - { - static_assert(sizeof(eastl::string) <= sizeof(eastl::any), "ensure that 'any' has enough local memory to store a string"); - static_assert(sizeof(eastl::vector<int>) <= sizeof(eastl::any), "ensure that 'any' has enough local memory to store a vector"); - } - - { - // default construct - any a; - VERIFY(a.has_value() == false); - } - - { - // test object ctors & dtors are called for a large object - TestObject::Reset(); - { any a{TestObject()}; } - VERIFY(TestObject::IsClear()); - } - - { - // test object ctors & dtors are called for a small object - SmallTestObject::Reset(); - { any a{SmallTestObject()}; } - VERIFY(SmallTestObject::IsClear()); - } - - { - any a(42); - VERIFY(a.has_value() == true); - - VERIFY(any_cast<int>(a) == 42); - VERIFY(any_cast<int>(a) != 1337); - any_cast<int&>(a) = 10; - VERIFY(any_cast<int>(a) == 10); - - a = 1.f; - any_cast<float&>(a) = 1337.f; - VERIFY(any_cast<float>(a) == 1337.f); - - a = 4343; - VERIFY(any_cast<int>(a) == 4343); - - a = string("hello world"); - VERIFY(any_cast<string>(a) == "hello world"); - VERIFY(any_cast<string&>(a) == "hello world"); - } - - { - struct custom_type { int data; }; - - any a = custom_type{}; - any_cast<custom_type&>(a).data = 42; - VERIFY(any_cast<custom_type>(a).data == 42); - } - - { - any a = 42; - VERIFY(any_cast<int>(a) == 42); - - #if EASTL_EXCEPTIONS_ENABLED - int throwCount = 0; - try { VERIFY(any_cast<short>(a) == 42); } - catch (bad_any_cast) { throwCount++; } - VERIFY(throwCount != 0); - #endif - } - - { - vector<any> va = {42, 'a', 42.f, 3333u, 4444ul, 5555ull, 6666.0}; - - VERIFY(any_cast<int>(va[0]) == 42); - VERIFY(any_cast<char>(va[1]) == 'a'); - VERIFY(any_cast<float>(va[2]) == 42.f); - VERIFY(any_cast<unsigned>(va[3]) == 3333u); - VERIFY(any_cast<unsigned long>(va[4]) == 4444ul); - VERIFY(any_cast<unsigned long long>(va[5]) == 5555ull); - VERIFY(any_cast<double>(va[6]) == 6666.0); - } - - { - any a(string("test string")); - VERIFY(a.has_value()); - VERIFY(any_cast<string>(a) == "test string"); - } - - { - vector<any> va = {42, string("rob"), 'a', 42.f}; - VERIFY(any_cast<int>(va[0]) == 42); - VERIFY(any_cast<string>(va[1]) == "rob"); - VERIFY(any_cast<char>(va[2]) == 'a'); - VERIFY(any_cast<float>(va[3]) == 42.f); - } - - { - vector<any> va; - va.push_back(42); - va.push_back(string("rob")); - va.push_back('a'); - va.push_back(42.f); - - VERIFY(any_cast<int>(va[0]) == 42); - VERIFY(any_cast<string>(va[1]) == "rob"); - VERIFY(any_cast<char>(va[2]) == 'a'); - VERIFY(any_cast<float>(va[3]) == 42.f); - } - - // NOTE(rparolin): Replaces a small 'any' object with a large one and make sure it doesn't corrupt - // the surrounding memory in the vector. - { - TestObject::Reset(); - { - vector<any> va = {42, 'a', 42.f, 3333u, 4444ul, 5555ull, 6666.0}; - - VERIFY(any_cast<int>(va[0]) == 42); - VERIFY(any_cast<char>(va[1]) == 'a'); - VERIFY(any_cast<float>(va[2]) == 42.f); - VERIFY(any_cast<unsigned>(va[3]) == 3333u); - VERIFY(any_cast<unsigned long>(va[4]) == 4444ul); - VERIFY(any_cast<unsigned long long>(va[5]) == 5555ull); - VERIFY(any_cast<double>(va[6]) == 6666.0); - - va[3] = TestObject(3333); // replace a small integral with a large heap allocated object. - - VERIFY(any_cast<int>(va[0]) == 42); - VERIFY(any_cast<char>(va[1]) == 'a'); - VERIFY(any_cast<float>(va[2]) == 42.f); - VERIFY(any_cast<TestObject>(va[3]).mX == 3333); // not 3333u because TestObject ctor takes a signed type. - VERIFY(any_cast<unsigned long>(va[4]) == 4444ul); - VERIFY(any_cast<unsigned long long>(va[5]) == 5555ull); - VERIFY(any_cast<double>(va[6]) == 6666.0); - } - VERIFY(TestObject::IsClear()); - } - - { - any a(string("test string")); - VERIFY(a.has_value()); - a.reset(); - VERIFY(!a.has_value()); - } - - { - any a1 = 42; - any a2 = a1; - - VERIFY(a1.has_value()); - VERIFY(a2.has_value()); - VERIFY(any_cast<int>(a1) == any_cast<int>(a2)); - } - - { - any a1; - VERIFY(!a1.has_value()); - { - any a2(string("test string")); - a1 = any_cast<string>(a2); - - VERIFY(a1.has_value()); - } - VERIFY(any_cast<string>(a1) == "test string"); - VERIFY(a1.has_value()); - } - - { - any a1; - VERIFY(!a1.has_value()); - { - any a2(string("test string")); - a1 = a2; - VERIFY(a1.has_value()); - } - VERIFY(any_cast<string&>(a1) == "test string"); - VERIFY(a1.has_value()); - } - - // swap tests - { - { - any a1 = 42; - any a2 = 24; - VERIFY(any_cast<int>(a1) == 42); - VERIFY(any_cast<int>(a2) == 24); - - a1.swap(a2); - VERIFY(any_cast<int>(a1) == 24); - VERIFY(any_cast<int>(a2) == 42); - - eastl::swap(a1, a2); - VERIFY(any_cast<int>(a1) == 42); - VERIFY(any_cast<int>(a2) == 24); - } - { - any a1 = string("hello"); - any a2 = string("world"); - VERIFY(any_cast<string>(a1) == "hello"); - VERIFY(any_cast<string>(a2) == "world"); - - a1.swap(a2); - VERIFY(any_cast<string>(a1) == "world"); - VERIFY(any_cast<string>(a2) == "hello"); - - eastl::swap(a1, a2); - VERIFY(any_cast<string>(a1) == "hello"); - VERIFY(any_cast<string>(a2) == "world"); - } - } - - #if EASTL_RTTI_ENABLED - { - #if defined(EA_COMPILER_MSVC) - VERIFY(EA::StdC::Strcmp(any(42).type().name(), "int") == 0); - VERIFY(EA::StdC::Strcmp(any(42.f).type().name(), "float") == 0); - VERIFY(EA::StdC::Strcmp(any(42u).type().name(), "unsigned int") == 0); - VERIFY(EA::StdC::Strcmp(any(42ul).type().name(), "unsigned long") == 0); - VERIFY(EA::StdC::Strcmp(any(42l).type().name(), "long") == 0); - - #elif defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_GNUC) - VERIFY(EA::StdC::Strcmp(any(42).type().name(), "i") == 0); - VERIFY(EA::StdC::Strcmp(any(42.f).type().name(), "f") == 0); - VERIFY(EA::StdC::Strcmp(any(42u).type().name(), "j") == 0); - VERIFY(EA::StdC::Strcmp(any(42ul).type().name(), "m") == 0); - VERIFY(EA::StdC::Strcmp(any(42l).type().name(), "l") == 0); - #endif - } - #endif - - // emplace, small object tests - { - any a; - - a.emplace<int>(42); - VERIFY(a.has_value()); - VERIFY(any_cast<int>(a) == 42); - - a.emplace<short>((short)8); // no way to define a short literal we must cast here. - VERIFY(any_cast<short>(a) == 8); - VERIFY(a.has_value()); - - a.reset(); - VERIFY(!a.has_value()); - } - - // emplace, large object tests - { - TestObject::Reset(); - { - any a; - a.emplace<TestObject>(); - VERIFY(a.has_value()); - } - VERIFY(TestObject::IsClear()); - } - - // emplace, initializer_list - { - { - any a; - a.emplace<RequiresInitList>(std::initializer_list<int>{1,2,3,4,5,6}); - - VERIFY(a.has_value()); - VERIFY(any_cast<RequiresInitList>(a).sum == 21); - } - } - - // equivalence tests - { - any a, b; - VERIFY(!a.has_value() == !b.has_value()); - - #if EASTL_EXCEPTIONS_ENABLED - int bad_any_cast_thrown = 0; - try - { - VERIFY(any_cast<int>(a) == any_cast<int>(b)); - } - catch (eastl::bad_any_cast) - { - bad_any_cast_thrown++; - } - VERIFY(bad_any_cast_thrown != 0); - #endif - - - a = 42; b = 24; - VERIFY(any_cast<int>(a) != any_cast<int>(b)); - VERIFY(a.has_value() == b.has_value()); - - a = 42; b = 42; - VERIFY(any_cast<int>(a) == any_cast<int>(b)); - VERIFY(a.has_value() == b.has_value()); - } - - // move tests - { - any a = string("hello world"); - VERIFY(any_cast<string&>(a) == "hello world"); - - auto s = move(any_cast<string&>(a)); // move string out - VERIFY(s == "hello world"); - VERIFY(any_cast<string&>(a).empty()); - - any_cast<string&>(a) = move(s); // move string in - VERIFY(any_cast<string&>(a) == "hello world"); - } - - // nullptr tests - { - any* a = nullptr; - VERIFY(any_cast<int>(a) == nullptr); - VERIFY(any_cast<short>(a) == nullptr); - VERIFY(any_cast<long>(a) == nullptr); - VERIFY(any_cast<string>(a) == nullptr); - - any b; - VERIFY(any_cast<short>(&b) == nullptr); - VERIFY(any_cast<const short>(&b) == nullptr); - VERIFY(any_cast<volatile short>(&b) == nullptr); - VERIFY(any_cast<const volatile short>(&b) == nullptr); - - VERIFY(any_cast<short*>(&b) == nullptr); - VERIFY(any_cast<const short*>(&b) == nullptr); - VERIFY(any_cast<volatile short*>(&b) == nullptr); - VERIFY(any_cast<const volatile short*>(&b) == nullptr); - } - - // Aligned type tests - { - { - any a = Align16(1337); - VERIFY(any_cast<Align16>(a) == Align16(1337)); - } - - { - any a = Align32(1337); - VERIFY(any_cast<Align32>(a) == Align32(1337)); - } - - { - any a = Align64(1337); - VERIFY(any_cast<Align64>(a) == Align64(1337)); - } - } - - // make_any - { - { - auto a = make_any<int>(42); - VERIFY(any_cast<int>(a) == 42); - } - - { - auto a = make_any<RequiresInitList>(std::initializer_list<int>{1,2,3,4,5,6,7,8}); - VERIFY(any_cast<RequiresInitList&>(a).sum == 36); - } - } - - // user reported regression that eastl::any constructor was not decaying the deduced type correctly. - { - float f = 42.f; - eastl::any a(f); - VERIFY(any_cast<float>(a) == 42.f); - } - - //testing unsafe operations - { - eastl::any a = 1; - int* i = eastl::any_cast<int>(&a); - VERIFY((*i) == 1); - - a = 2; - int *j = (int*)eastl::unsafe_any_cast<void>(&a); - VERIFY((*j) == 2); - - const eastl::any b = 3; - const void * p = eastl::unsafe_any_cast<void>(&b); - void *q = const_cast<void *>(p); - int *r = static_cast<int *>(q); - VERIFY((*r) == 3); - } - - // user regression when calling the assignment operator - { - { - eastl::any a1; - eastl::any a2; - VERIFY(a1.has_value() == false); - VERIFY(a2.has_value() == false); - - a1 = a2; - VERIFY(a1.has_value() == false); - VERIFY(a2.has_value() == false); - } - - { - eastl::any a1 = 42; - eastl::any a2; - VERIFY(a1.has_value() == true); - VERIFY(a2.has_value() == false); - - a1 = a2; - VERIFY(a1.has_value() == false); - VERIFY(a2.has_value() == false); - } - - { - eastl::any a1; - eastl::any a2 = 42; - VERIFY(a1.has_value() == false); - VERIFY(a2.has_value() == true); - - a1 = a2; - VERIFY(a1.has_value() == true); - VERIFY(a2.has_value() == true); - VERIFY(any_cast<int>(a1) == 42); - VERIFY(any_cast<int>(a2) == 42); - } - } - - return nErrorCount; -} - - diff --git a/test/source/TestArray.cpp b/test/source/TestArray.cpp deleted file mode 100644 index ca05b67..0000000 --- a/test/source/TestArray.cpp +++ /dev/null @@ -1,360 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/array.h> -#include <EABase/eabase.h> - - - -using namespace eastl; - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template struct eastl::array<int>; -template struct eastl::array<Align32>; // VC++ fails to compile due to error generated by the swap function. C2718: http://msdn.microsoft.com/en-us/library/vstudio/sxe76d9e.aspx - -template<typename T> class TP; - - -int TestArray() -{ - int nErrorCount = 0; - - { - array<int, 5> a = { { 0, 1, 2, 3, 4 } }; - array<int, 5> b = { { 0, 1, 2, 3 } }; - array<int, 5> c = { { 4, 3, 2, 1, 0 } }; - array<int, 0> d = { { 0 } }; - - VERIFY(!a.empty()); - VERIFY(a.size() == 5); - VERIFY(a[0] == 0); - VERIFY(a[4] == 4); - - VERIFY(!b.empty()); - VERIFY(b.size() == 5); - VERIFY(b[0] == 0); - VERIFY(b[3] == 3); - - VERIFY(d.empty()); - VERIFY(d.size() == 0); - - // swap - a.swap(c); - VERIFY(a[0] == 4); - VERIFY(c[0] == 0); - - // begin, end - array<int, 5>::iterator it = a.begin(); - VERIFY((a.validate_iterator(it) & (isf_valid | isf_can_dereference)) != 0); - VERIFY(*it == 4); - - ++it; - VERIFY(*it == 3); - - ++it; - VERIFY(*it == 2); - - --it; - VERIFY(*it == 3); - - it += 3; - VERIFY((a.validate_iterator(it) & (isf_valid | isf_can_dereference)) != 0); - VERIFY(*it == 0); - - ++it; - VERIFY(it == a.end()); - VERIFY((a.validate_iterator(it) & isf_valid) != 0); - VERIFY(a.validate()); - - // rbegin, rend - array<int, 5>::reverse_iterator itr = a.rbegin(); - VERIFY((a.validate_iterator(itr.base()) & (isf_valid | isf_can_dereference)) != 0); - VERIFY(*itr == 0); - - itr++; - VERIFY(*itr == 1); - - // data - int* pArray = a.data(); - VERIFY(pArray == a.mValue); - - // front - int& nFront = a.front(); - VERIFY(nFront == 4); - - // back - int& nBack = a.back(); - VERIFY(nBack == 0); - - // at - VERIFY(a[0] == a.at(0)); - #if EASTL_EXCEPTIONS_ENABLED - bool bExceptionOccurred = false; - try{ - int x = a.at(100); - VERIFY(x != -1); - } - catch(...){ - bExceptionOccurred = true; - } - VERIFY(bExceptionOccurred); - #endif - - // global operators - a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3; a[4] = 4; // 01234 - b[0] = 0; b[1] = 1; b[2] = 2; b[3] = 3; b[4] = 4; // 01234 - c[0] = 0; c[1] = 1; c[2] = 2; c[3] = 3; c[4] = 9; // 01239 - - VERIFY( (a == b)); - VERIFY(!(a != b)); - VERIFY(!(a < b)); - VERIFY( (a <= b)); - VERIFY( (a >= b)); - VERIFY(!(a > b)); - - VERIFY(!(a == c)); - VERIFY( (a != c)); - VERIFY( (a < c)); - VERIFY( (a <= c)); - VERIFY(!(a >= c)); - VERIFY(!(a > c)); - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - VERIFY( (a <=> b) == 0); - VERIFY(!((a <=> b) != 0)); - VERIFY(!((a <=> b) < 0)); - VERIFY( (a <=> b) <= 0); - VERIFY( (a <=> b) >= 0); - VERIFY(!((a <=> b) > 0)); - - VERIFY(!((a <=> c) == 0)); - VERIFY( (a <=> c) != 0); - VERIFY( (a <=> c) < 0); - VERIFY( (a <=> c) <= 0); - VERIFY(!((a <=> c) >= 0)); - VERIFY(!((a <=> c) > 0)); -#endif - - // deduction guides - #ifdef __cpp_deduction_guides - array deduced {1,2,3,4,5}; - - static_assert(eastl::is_same_v<decltype(deduced)::value_type, int>, "deduced array value_type mismatch"); - VERIFY(deduced.size() == 5); - #endif - - // structured binding - - { - eastl::array<int, 5> aCopy = a; - auto&& [a0, a1, a2, a3, a4] = aCopy; - - VERIFY(a0 == aCopy[0]); - VERIFY(a1 == aCopy[1]); - VERIFY(a2 == aCopy[2]); - VERIFY(a3 == aCopy[3]); - VERIFY(a4 == aCopy[4]); - - a0 = 100; - VERIFY(aCopy[0] == 100); - - a4 = 0; - VERIFY(aCopy[4] == 0); - - // The deduced type may or may not be a reference type; it is an aliased type, - // as per https://en.cppreference.com/w/cpp/language/structured_binding: - // > Like a reference, a structured binding is an alias to an existing object. Unlike a reference, - // the type of a structured binding does not have to be a reference type. - // Any reference specifier is thus removed to check only the type & its const qualifier - static_assert(eastl::is_same_v<eastl::remove_reference_t<decltype(a0)>, int>); - - const eastl::array<int, 5> aConstCopy = a; - auto&& [aConst0, aConst1, aConst2, aConst3, aConst4] = aConstCopy; - - static_assert(eastl::is_same_v<eastl::remove_reference_t<decltype(aConst0)>, const int>); - } - } - - // constexpr tests - { - #ifndef EA_NO_CPP14_CONSTEXPR - EA_CPP14_CONSTEXPR eastl::array<int, 4> a = {{ 0, 1, 2, 3 }}; - - static_assert(a == eastl::array<int, 4>{{ 0, 1, 2, 3 }}, "array constexpr failure"); - - static_assert(a[0] == 0, "array constexpr failure"); - static_assert(a[1] == 1, "array constexpr failure"); - static_assert(a[2] == 2, "array constexpr failure"); - static_assert(a[3] == 3, "array constexpr failure"); - - static_assert(a.at(0) == 0, "array constexpr failure"); - static_assert(a.at(1) == 1, "array constexpr failure"); - static_assert(a.at(2) == 2, "array constexpr failure"); - static_assert(a.at(3) == 3, "array constexpr failure"); - - static_assert(a.data()[0] == 0, "array constexpr failure"); - static_assert(a.data()[1] == 1, "array constexpr failure"); - static_assert(a.data()[2] == 2, "array constexpr failure"); - static_assert(a.data()[3] == 3, "array constexpr failure"); - - static_assert(a.empty() == false, "array constexpr failure"); - static_assert(a.size() == 4, "array constexpr failure"); - static_assert(a.max_size() == 4, "array constexpr failure"); - - static_assert(a.front() == 0, "array constexpr failure"); - static_assert(a.back() == 3, "array constexpr failure"); - - static_assert(a.begin()[0] == 0, "array constexpr failure"); - static_assert(a.begin()[1] == 1, "array constexpr failure"); - static_assert(a.begin()[2] == 2, "array constexpr failure"); - static_assert(a.begin()[3] == 3, "array constexpr failure"); - - static_assert(a.cbegin()[0] == 0, "array constexpr failure"); - static_assert(a.cbegin()[1] == 1, "array constexpr failure"); - static_assert(a.cbegin()[2] == 2, "array constexpr failure"); - static_assert(a.cbegin()[3] == 3, "array constexpr failure"); - - static_assert(a.crbegin()[0] == 3, "array constexpr failure"); - static_assert(a.crbegin()[1] == 2, "array constexpr failure"); - static_assert(a.crbegin()[2] == 1, "array constexpr failure"); - static_assert(a.crbegin()[3] == 0, "array constexpr failure"); - - static_assert(a.end()[-1] == 3, "array constexpr failure"); - static_assert(a.end()[-2] == 2, "array constexpr failure"); - static_assert(a.end()[-3] == 1, "array constexpr failure"); - static_assert(a.end()[-4] == 0, "array constexpr failure"); - - static_assert(a.cend()[-1] == 3, "array constexpr failure"); - static_assert(a.cend()[-2] == 2, "array constexpr failure"); - static_assert(a.cend()[-3] == 1, "array constexpr failure"); - static_assert(a.cend()[-4] == 0, "array constexpr failure"); - - static_assert(a.crend()[-1] == 0, "array constexpr failure"); - static_assert(a.crend()[-2] == 1, "array constexpr failure"); - static_assert(a.crend()[-3] == 2, "array constexpr failure"); - static_assert(a.crend()[-4] == 3, "array constexpr failure"); - #endif - } - - // to_array - { - { - constexpr int c_array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - constexpr auto arr = to_array(c_array); - - static_assert(is_same_v<remove_cv_t<decltype(arr)>, eastl::array<int, 10>>, "unexpected return type"); - - static_assert(arr[0] == 0, "unexpected array value"); - static_assert(arr[1] == 1, "unexpected array value"); - static_assert(arr[2] == 2, "unexpected array value"); - static_assert(arr[3] == 3, "unexpected array value"); - static_assert(arr[4] == 4, "unexpected array value"); - static_assert(arr[5] == 5, "unexpected array value"); - static_assert(arr[6] == 6, "unexpected array value"); - static_assert(arr[7] == 7, "unexpected array value"); - static_assert(arr[8] == 8, "unexpected array value"); - static_assert(arr[9] == 9, "unexpected array value"); - } - - { - constexpr auto arr = to_array({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); - - static_assert(is_same_v<remove_cv_t<decltype(arr)>, eastl::array<int, 10>>, "unexpected return type"); - - static_assert(arr[0] == 0, "unexpected array value"); - static_assert(arr[1] == 1, "unexpected array value"); - static_assert(arr[2] == 2, "unexpected array value"); - static_assert(arr[3] == 3, "unexpected array value"); - static_assert(arr[4] == 4, "unexpected array value"); - static_assert(arr[5] == 5, "unexpected array value"); - static_assert(arr[6] == 6, "unexpected array value"); - static_assert(arr[7] == 7, "unexpected array value"); - static_assert(arr[8] == 8, "unexpected array value"); - static_assert(arr[9] == 9, "unexpected array value"); - } - - { - constexpr auto arr = to_array<long>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); - - static_assert(is_same_v<remove_cv_t<decltype(arr)>, eastl::array<long, 10>>, "unexpected return type"); - - static_assert(arr[0] == 0l, "unexpected array value"); - static_assert(arr[1] == 1l, "unexpected array value"); - static_assert(arr[2] == 2l, "unexpected array value"); - static_assert(arr[3] == 3l, "unexpected array value"); - static_assert(arr[4] == 4l, "unexpected array value"); - static_assert(arr[5] == 5l, "unexpected array value"); - static_assert(arr[6] == 6l, "unexpected array value"); - static_assert(arr[7] == 7l, "unexpected array value"); - static_assert(arr[8] == 8l, "unexpected array value"); - static_assert(arr[9] == 9l, "unexpected array value"); - } - - { - constexpr auto arr = to_array<unsigned long>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); - - static_assert(is_same_v<remove_cv_t<decltype(arr)>, eastl::array<unsigned long, 10>>, "unexpected return type"); - - static_assert(arr[0] == 0ul, "unexpected array value"); - static_assert(arr[1] == 1ul, "unexpected array value"); - static_assert(arr[2] == 2ul, "unexpected array value"); - static_assert(arr[3] == 3ul, "unexpected array value"); - static_assert(arr[4] == 4ul, "unexpected array value"); - static_assert(arr[5] == 5ul, "unexpected array value"); - static_assert(arr[6] == 6ul, "unexpected array value"); - static_assert(arr[7] == 7ul, "unexpected array value"); - static_assert(arr[8] == 8ul, "unexpected array value"); - static_assert(arr[9] == 9ul, "unexpected array value"); - } - - { - constexpr auto arr = to_array("EASTL"); - - static_assert(is_same_v<remove_cv_t<decltype(arr)>, eastl::array<char, 6>>, "unexpected return type"); - - static_assert(arr[0] == 'E', "unexpected value in array"); - static_assert(arr[1] == 'A', "unexpected value in array"); - static_assert(arr[2] == 'S', "unexpected value in array"); - static_assert(arr[3] == 'T', "unexpected value in array"); - static_assert(arr[4] == 'L', "unexpected value in array"); - } - - // Older Microsoft compilers don't implement guaranteed copy ellision which is problematic when dealing with - // non-copyable types. We disable this test unless we are on a version of MSVC with those features. - #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1920) // VS2019 16.0+ - { - struct LocalNonCopyable - { - LocalNonCopyable() = default; - ~LocalNonCopyable() = default; - - LocalNonCopyable(LocalNonCopyable&&) = default; - LocalNonCopyable& operator=(LocalNonCopyable&&) = default; - - LocalNonCopyable(const LocalNonCopyable&) = delete; - LocalNonCopyable& operator=(const LocalNonCopyable&) = delete; - }; - - constexpr auto arr = to_array({LocalNonCopyable{}}); - static_assert(arr.size() == 1, "unexpected error"); - } - #endif - } - - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestAtomicAsm.cpp b/test/source/TestAtomicAsm.cpp deleted file mode 100644 index d4db04e..0000000 --- a/test/source/TestAtomicAsm.cpp +++ /dev/null @@ -1,4921 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" - -#include <EASTL/atomic.h> - -#include <cstddef> - - -struct UserType128 -{ - uint32_t a,b,c,d; - - friend bool operator==(const UserType128& a, const UserType128& b) - { - return (a.a == b.a) && (a.b == b.b) && (a.c == b.c) && (a.d == b.d); - } -}; - - -/** - * There is no nice way to verify the emitted asm for each of the given operations. - * This test file is meant to put each operation into its own function so its easy - * to verify in a disassembler for manual inspection. - */ - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32StoreRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - atomic.store(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomicU32StoreRelease() -{ - eastl::atomic<uint32_t> atomic; - - atomic.store(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomicU32StoreSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - atomic.store(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomicU32Store() -{ - eastl::atomic<uint32_t> atomic; - - atomic.store(1); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomicU32StoreOrders() -{ - TestAtomicU32StoreRelaxed(); - - TestAtomicU32StoreRelease(); - - TestAtomicU32StoreSeqCst(); - - TestAtomicU32Store(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64StoreRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - atomic.store(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomicU64StoreRelease() -{ - eastl::atomic<uint64_t> atomic; - - atomic.store(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomicU64StoreSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - atomic.store(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomicU64Store() -{ - eastl::atomic<uint64_t> atomic; - - atomic.store(1); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomicU64StoreOrders() -{ - TestAtomicU64StoreRelaxed(); - - TestAtomicU64StoreRelease(); - - TestAtomicU64StoreSeqCst(); - - TestAtomicU64Store(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -EA_NO_INLINE static void TestAtomic128StoreRelaxed() -{ - eastl::atomic<UserType128> atomic; - - atomic.store(UserType128{1, 1, 1, 1}, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomic128StoreRelease() -{ - eastl::atomic<UserType128> atomic; - - atomic.store(UserType128{1, 1, 1, 1}, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomic128StoreSeqCst() -{ - eastl::atomic<UserType128> atomic; - - atomic.store(UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomic128Store() -{ - eastl::atomic<UserType128> atomic; - - atomic.store(UserType128{1, 1, 1, 1}); - - eastl::compiler_barrier_data_dependency(atomic); -} - -EA_NO_INLINE static void TestAtomic128StoreOrders() -{ - TestAtomic128StoreRelaxed(); - - TestAtomic128StoreRelease(); - - TestAtomic128StoreSeqCst(); - - TestAtomic128Store(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32LoadRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t load = atomic.load(eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomicU32LoadAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t load = atomic.load(eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomicU32LoadSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t load = atomic.load(eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomicU32Load() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t load = atomic.load(); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomicU32LoadOrders() -{ - TestAtomicU32LoadRelaxed(); - - TestAtomicU32LoadAcquire(); - - TestAtomicU32LoadSeqCst(); - - TestAtomicU32Load(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64LoadRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t load = atomic.load(eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomicU64LoadAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t load = atomic.load(eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomicU64LoadSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t load = atomic.load(eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomicU64Load() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t load = atomic.load(); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomicU64LoadOrders() -{ - TestAtomicU64LoadRelaxed(); - - TestAtomicU64LoadAcquire(); - - TestAtomicU64LoadSeqCst(); - - TestAtomicU64Load(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -EA_NO_INLINE static void TestAtomic128LoadRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 load = atomic.load(eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomic128LoadAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 load = atomic.load(eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomic128LoadSeqCst() -{ - eastl::atomic<UserType128> atomic; - - UserType128 load = atomic.load(eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomic128Load() -{ - eastl::atomic<UserType128> atomic; - - UserType128 load = atomic.load(); - - eastl::compiler_barrier_data_dependency(load); -} - -EA_NO_INLINE static void TestAtomic128LoadOrders() -{ - TestAtomic128LoadRelaxed(); - - TestAtomic128LoadAcquire(); - - TestAtomic128LoadSeqCst(); - - TestAtomic128Load(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32ExchangeRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t exchange = atomic.exchange(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU32ExchangeAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t exchange = atomic.exchange(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU32ExchangeRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t exchange = atomic.exchange(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU32ExchangeAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t exchange = atomic.exchange(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU32ExchangeSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t exchange = atomic.exchange(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU32Exchange() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t exchange = atomic.exchange(1); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU32ExchangeOrders() -{ - TestAtomicU32ExchangeRelaxed(); - - TestAtomicU32ExchangeAcquire(); - - TestAtomicU32ExchangeRelease(); - - TestAtomicU32ExchangeAcqRel(); - - TestAtomicU32ExchangeSeqCst(); - - TestAtomicU32Exchange(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64ExchangeRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t exchange = atomic.exchange(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU64ExchangeAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t exchange = atomic.exchange(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU64ExchangeRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t exchange = atomic.exchange(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU64ExchangeAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t exchange = atomic.exchange(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU64ExchangeSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t exchange = atomic.exchange(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU64Exchange() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t exchange = atomic.exchange(1); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomicU64ExchangeOrders() -{ - TestAtomicU64ExchangeRelaxed(); - - TestAtomicU64ExchangeAcquire(); - - TestAtomicU64ExchangeRelease(); - - TestAtomicU64ExchangeAcqRel(); - - TestAtomicU64ExchangeSeqCst(); - - TestAtomicU64Exchange(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -EA_NO_INLINE static void TestAtomic128ExchangeRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 exchange = atomic.exchange(UserType128{1, 1, 1, 1}, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomic128ExchangeAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 exchange = atomic.exchange(UserType128{1, 1, 1, 1}, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomic128ExchangeRelease() -{ - eastl::atomic<UserType128> atomic; - - UserType128 exchange = atomic.exchange(UserType128{1, 1, 1, 1}, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomic128ExchangeAcqRel() -{ - eastl::atomic<UserType128> atomic; - - UserType128 exchange = atomic.exchange(UserType128{1, 1, 1, 1}, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomic128ExchangeSeqCst() -{ - eastl::atomic<UserType128> atomic; - - UserType128 exchange = atomic.exchange(UserType128{1, 1, 1, 1}, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomic128Exchange() -{ - eastl::atomic<UserType128> atomic; - - UserType128 exchange = atomic.exchange(UserType128{1, 1, 1, 1}); - - eastl::compiler_barrier_data_dependency(exchange); -} - -EA_NO_INLINE static void TestAtomic128ExchangeOrders() -{ - TestAtomic128ExchangeRelaxed(); - - TestAtomic128ExchangeAcquire(); - - TestAtomic128ExchangeRelease(); - - TestAtomic128ExchangeAcqRel(); - - TestAtomic128ExchangeSeqCst(); - - TestAtomic128Exchange(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorT() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t load = atomic; - - eastl::compiler_barrier_data_dependency(load); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorT() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t load = atomic; - - eastl::compiler_barrier_data_dependency(load); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -EA_NO_INLINE static void TestAtomic128OperatorT() -{ - eastl::atomic<UserType128> atomic; - - UserType128 load = atomic; - - eastl::compiler_barrier_data_dependency(load); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorEqual() -{ - eastl::atomic<uint32_t> atomic; - - atomic = 1; - - eastl::compiler_barrier_data_dependency(atomic); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorEqual() -{ - eastl::atomic<uint64_t> atomic; - - atomic = 1; - - eastl::compiler_barrier_data_dependency(atomic); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -EA_NO_INLINE static void TestAtomic128OperatorEqual() -{ - eastl::atomic<UserType128> atomic; - - atomic = UserType128{1, 1, 1, 1}; - - eastl::compiler_barrier_data_dependency(atomic); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongRelaxedRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongAcquireRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongAcquireAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acquire, eastl::memory_order_acquire); - - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongReleaseRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_release, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongAcqRelRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongAcqRelAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongSeqCstRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongSeqCstAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongSeqCstSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrong() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeStrongOrders() -{ - TestAtomicU32CompareExchangeStrongRelaxedRelaxed(); - - TestAtomicU32CompareExchangeStrongAcquireRelaxed(); - - TestAtomicU32CompareExchangeStrongAcquireAcquire(); - - TestAtomicU32CompareExchangeStrongReleaseRelaxed(); - - TestAtomicU32CompareExchangeStrongAcqRelRelaxed(); - - TestAtomicU32CompareExchangeStrongAcqRelAcquire(); - - TestAtomicU32CompareExchangeStrongSeqCstRelaxed(); - - TestAtomicU32CompareExchangeStrongSeqCstAcquire(); - - TestAtomicU32CompareExchangeStrongSeqCstSeqCst(); - - TestAtomicU32CompareExchangeStrongRelaxed(); - - TestAtomicU32CompareExchangeStrongAcquire(); - - TestAtomicU32CompareExchangeStrongRelease(); - - TestAtomicU32CompareExchangeStrongAcqRel(); - - TestAtomicU32CompareExchangeStrongSeqCst(); - - TestAtomicU32CompareExchangeStrong(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongRelaxedRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongAcquireRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongAcquireAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acquire, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongReleaseRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_release, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongAcqRelRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongAcqRelAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongSeqCstRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongSeqCstAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongSeqCstSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrong() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_strong(expected, 1); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeStrongOrders() -{ - TestAtomicU64CompareExchangeStrongRelaxedRelaxed(); - - TestAtomicU64CompareExchangeStrongAcquireRelaxed(); - - TestAtomicU64CompareExchangeStrongAcquireAcquire(); - - TestAtomicU64CompareExchangeStrongReleaseRelaxed(); - - TestAtomicU64CompareExchangeStrongAcqRelRelaxed(); - - TestAtomicU64CompareExchangeStrongAcqRelAcquire(); - - TestAtomicU64CompareExchangeStrongSeqCstRelaxed(); - - TestAtomicU64CompareExchangeStrongSeqCstAcquire(); - - TestAtomicU64CompareExchangeStrongSeqCstSeqCst(); - - TestAtomicU64CompareExchangeStrongRelaxed(); - - TestAtomicU64CompareExchangeStrongAcquire(); - - TestAtomicU64CompareExchangeStrongRelease(); - - TestAtomicU64CompareExchangeStrongAcqRel(); - - TestAtomicU64CompareExchangeStrongSeqCst(); - - TestAtomicU64CompareExchangeStrong(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongRelaxedRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongAcquireRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongAcquireAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acquire, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongReleaseRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_release, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongAcqRelRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongAcqRelAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongSeqCstRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongSeqCstAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongSeqCstSeqCst() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongRelease() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongAcqRel() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongSeqCst() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrong() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_strong(expected, UserType128{1, 1, 1, 1}); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeStrongOrders() -{ - TestAtomic128CompareExchangeStrongRelaxedRelaxed(); - - TestAtomic128CompareExchangeStrongAcquireRelaxed(); - - TestAtomic128CompareExchangeStrongAcquireAcquire(); - - TestAtomic128CompareExchangeStrongReleaseRelaxed(); - - TestAtomic128CompareExchangeStrongAcqRelRelaxed(); - - TestAtomic128CompareExchangeStrongAcqRelAcquire(); - - TestAtomic128CompareExchangeStrongSeqCstRelaxed(); - - TestAtomic128CompareExchangeStrongSeqCstAcquire(); - - TestAtomic128CompareExchangeStrongSeqCstSeqCst(); - - TestAtomic128CompareExchangeStrongRelaxed(); - - TestAtomic128CompareExchangeStrongAcquire(); - - TestAtomic128CompareExchangeStrongRelease(); - - TestAtomic128CompareExchangeStrongAcqRel(); - - TestAtomic128CompareExchangeStrongSeqCst(); - - TestAtomic128CompareExchangeStrong(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakRelaxedRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakAcquireRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakAcquireAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acquire, eastl::memory_order_acquire); - - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakReleaseRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_release, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakAcqRelRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakAcqRelAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakSeqCstRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakSeqCstAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakSeqCstSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeak() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU32CompareExchangeWeakOrders() -{ - TestAtomicU32CompareExchangeWeakRelaxedRelaxed(); - - TestAtomicU32CompareExchangeWeakAcquireRelaxed(); - - TestAtomicU32CompareExchangeWeakAcquireAcquire(); - - TestAtomicU32CompareExchangeWeakReleaseRelaxed(); - - TestAtomicU32CompareExchangeWeakAcqRelRelaxed(); - - TestAtomicU32CompareExchangeWeakAcqRelAcquire(); - - TestAtomicU32CompareExchangeWeakSeqCstRelaxed(); - - TestAtomicU32CompareExchangeWeakSeqCstAcquire(); - - TestAtomicU32CompareExchangeWeakSeqCstSeqCst(); - - TestAtomicU32CompareExchangeWeakRelaxed(); - - TestAtomicU32CompareExchangeWeakAcquire(); - - TestAtomicU32CompareExchangeWeakRelease(); - - TestAtomicU32CompareExchangeWeakAcqRel(); - - TestAtomicU32CompareExchangeWeakSeqCst(); - - TestAtomicU32CompareExchangeWeak(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakRelaxedRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakAcquireRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakAcquireAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acquire, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakReleaseRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_release, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakAcqRelRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakAcqRelAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakSeqCstRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakSeqCstAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakSeqCstSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeak() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t expected = 0; - bool ret = atomic.compare_exchange_weak(expected, 1); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomicU64CompareExchangeWeakOrders() -{ - TestAtomicU64CompareExchangeWeakRelaxedRelaxed(); - - TestAtomicU64CompareExchangeWeakAcquireRelaxed(); - - TestAtomicU64CompareExchangeWeakAcquireAcquire(); - - TestAtomicU64CompareExchangeWeakReleaseRelaxed(); - - TestAtomicU64CompareExchangeWeakAcqRelRelaxed(); - - TestAtomicU64CompareExchangeWeakAcqRelAcquire(); - - TestAtomicU64CompareExchangeWeakSeqCstRelaxed(); - - TestAtomicU64CompareExchangeWeakSeqCstAcquire(); - - TestAtomicU64CompareExchangeWeakSeqCstSeqCst(); - - TestAtomicU64CompareExchangeWeakRelaxed(); - - TestAtomicU64CompareExchangeWeakAcquire(); - - TestAtomicU64CompareExchangeWeakRelease(); - - TestAtomicU64CompareExchangeWeakAcqRel(); - - TestAtomicU64CompareExchangeWeakSeqCst(); - - TestAtomicU64CompareExchangeWeak(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakRelaxedRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakAcquireRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakAcquireAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acquire, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakReleaseRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_release, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakAcqRelRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakAcqRelAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakSeqCstRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakSeqCstAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakSeqCstSeqCst() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakRelaxed() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakAcquire() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakRelease() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakAcqRel() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakSeqCst() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeak() -{ - eastl::atomic<UserType128> atomic; - - UserType128 expected = UserType128{0, 0, 0, 0}; - bool ret = atomic.compare_exchange_weak(expected, UserType128{1, 1, 1, 1}); - - eastl::compiler_barrier_data_dependency(ret); -} - -EA_NO_INLINE static void TestAtomic128CompareExchangeWeakOrders() -{ - TestAtomic128CompareExchangeWeakRelaxedRelaxed(); - - TestAtomic128CompareExchangeWeakAcquireRelaxed(); - - TestAtomic128CompareExchangeWeakAcquireAcquire(); - - TestAtomic128CompareExchangeWeakReleaseRelaxed(); - - TestAtomic128CompareExchangeWeakAcqRelRelaxed(); - - TestAtomic128CompareExchangeWeakAcqRelAcquire(); - - TestAtomic128CompareExchangeWeakSeqCstRelaxed(); - - TestAtomic128CompareExchangeWeakSeqCstAcquire(); - - TestAtomic128CompareExchangeWeakSeqCstSeqCst(); - - TestAtomic128CompareExchangeWeakRelaxed(); - - TestAtomic128CompareExchangeWeakAcquire(); - - TestAtomic128CompareExchangeWeakRelease(); - - TestAtomic128CompareExchangeWeakAcqRel(); - - TestAtomic128CompareExchangeWeakSeqCst(); - - TestAtomic128CompareExchangeWeak(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32FetchAddRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_add(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAddAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_add(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAddRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_add(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAddAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_add(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAddSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_add(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAdd() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_add(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAddOrders() -{ - TestAtomicU32FetchAddRelaxed(); - - TestAtomicU32FetchAddAcquire(); - - TestAtomicU32FetchAddRelease(); - - TestAtomicU32FetchAddAcqRel(); - - TestAtomicU32FetchAddSeqCst(); - - TestAtomicU32FetchAdd(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64FetchAddRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_add(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAddAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_add(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAddRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_add(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAddAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_add(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAddSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_add(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAdd() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_add(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAddOrders() -{ - TestAtomicU64FetchAddRelaxed(); - - TestAtomicU64FetchAddAcquire(); - - TestAtomicU64FetchAddRelease(); - - TestAtomicU64FetchAddAcqRel(); - - TestAtomicU64FetchAddSeqCst(); - - TestAtomicU64FetchAdd(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128FetchAddRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_add(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAddAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_add(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAddRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_add(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAddAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_add(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAddSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_add(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAdd() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_add(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAddOrders() -{ - TestAtomic128FetchAddRelaxed(); - - TestAtomic128FetchAddAcquire(); - - TestAtomic128FetchAddRelease(); - - TestAtomic128FetchAddAcqRel(); - - TestAtomic128FetchAddSeqCst(); - - TestAtomic128FetchAdd(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32AddFetchRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.add_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AddFetchAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.add_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AddFetchRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.add_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AddFetchAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.add_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AddFetchSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.add_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AddFetch() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.add_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AddFetchOrders() -{ - TestAtomicU32AddFetchRelaxed(); - - TestAtomicU32AddFetchAcquire(); - - TestAtomicU32AddFetchRelease(); - - TestAtomicU32AddFetchAcqRel(); - - TestAtomicU32AddFetchSeqCst(); - - TestAtomicU32AddFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64AddFetchRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.add_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AddFetchAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.add_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AddFetchRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.add_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AddFetchAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.add_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AddFetchSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.add_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AddFetch() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.add_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AddFetchOrders() -{ - TestAtomicU64AddFetchRelaxed(); - - TestAtomicU64AddFetchAcquire(); - - TestAtomicU64AddFetchRelease(); - - TestAtomicU64AddFetchAcqRel(); - - TestAtomicU64AddFetchSeqCst(); - - TestAtomicU64AddFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128AddFetchRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.add_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AddFetchAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.add_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AddFetchRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.add_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AddFetchAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.add_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AddFetchSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.add_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AddFetch() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.add_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AddFetchOrders() -{ - TestAtomic128AddFetchRelaxed(); - - TestAtomic128AddFetchAcquire(); - - TestAtomic128AddFetchRelease(); - - TestAtomic128AddFetchAcqRel(); - - TestAtomic128AddFetchSeqCst(); - - TestAtomic128AddFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32FetchSubRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_sub(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchSubAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_sub(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchSubRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_sub(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchSubAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_sub(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchSubSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_sub(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchSub() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_sub(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchSubOrders() -{ - TestAtomicU32FetchSubRelaxed(); - - TestAtomicU32FetchSubAcquire(); - - TestAtomicU32FetchSubRelease(); - - TestAtomicU32FetchSubAcqRel(); - - TestAtomicU32FetchSubSeqCst(); - - TestAtomicU32FetchSub(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64FetchSubRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_sub(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchSubAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_sub(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchSubRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_sub(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchSubAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_sub(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchSubSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_sub(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchSub() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_sub(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchSubOrders() -{ - TestAtomicU64FetchSubRelaxed(); - - TestAtomicU64FetchSubAcquire(); - - TestAtomicU64FetchSubRelease(); - - TestAtomicU64FetchSubAcqRel(); - - TestAtomicU64FetchSubSeqCst(); - - TestAtomicU64FetchSub(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128FetchSubRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_sub(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchSubAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_sub(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchSubRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_sub(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchSubAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_sub(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchSubSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_sub(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchSub() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_sub(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchSubOrders() -{ - TestAtomic128FetchSubRelaxed(); - - TestAtomic128FetchSubAcquire(); - - TestAtomic128FetchSubRelease(); - - TestAtomic128FetchSubAcqRel(); - - TestAtomic128FetchSubSeqCst(); - - TestAtomic128FetchSub(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32SubFetchRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.sub_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32SubFetchAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.sub_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32SubFetchRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.sub_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32SubFetchAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.sub_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32SubFetchSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.sub_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32SubFetch() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.sub_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32SubFetchOrders() -{ - TestAtomicU32SubFetchRelaxed(); - - TestAtomicU32SubFetchAcquire(); - - TestAtomicU32SubFetchRelease(); - - TestAtomicU32SubFetchAcqRel(); - - TestAtomicU32SubFetchSeqCst(); - - TestAtomicU32SubFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64SubFetchRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.sub_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64SubFetchAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.sub_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64SubFetchRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.sub_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64SubFetchAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.sub_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64SubFetchSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.sub_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64SubFetch() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.sub_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64SubFetchOrders() -{ - TestAtomicU64SubFetchRelaxed(); - - TestAtomicU64SubFetchAcquire(); - - TestAtomicU64SubFetchRelease(); - - TestAtomicU64SubFetchAcqRel(); - - TestAtomicU64SubFetchSeqCst(); - - TestAtomicU64SubFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128SubFetchRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.sub_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128SubFetchAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.sub_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128SubFetchRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.sub_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128SubFetchAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.sub_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128SubFetchSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.sub_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128SubFetch() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.sub_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128SubFetchOrders() -{ - TestAtomic128SubFetchRelaxed(); - - TestAtomic128SubFetchAcquire(); - - TestAtomic128SubFetchRelease(); - - TestAtomic128SubFetchAcqRel(); - - TestAtomic128SubFetchSeqCst(); - - TestAtomic128SubFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32FetchAndRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_and(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAndAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_and(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAndRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_and(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAndAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_and(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAndSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_and(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAnd() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_and(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchAndOrders() -{ - TestAtomicU32FetchAndRelaxed(); - - TestAtomicU32FetchAndAcquire(); - - TestAtomicU32FetchAndRelease(); - - TestAtomicU32FetchAndAcqRel(); - - TestAtomicU32FetchAndSeqCst(); - - TestAtomicU32FetchAnd(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64FetchAndRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_and(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAndAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_and(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAndRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_and(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAndAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_and(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAndSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_and(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAnd() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_and(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchAndOrders() -{ - TestAtomicU64FetchAndRelaxed(); - - TestAtomicU64FetchAndAcquire(); - - TestAtomicU64FetchAndRelease(); - - TestAtomicU64FetchAndAcqRel(); - - TestAtomicU64FetchAndSeqCst(); - - TestAtomicU64FetchAnd(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128FetchAndRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_and(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAndAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_and(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAndRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_and(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAndAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_and(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAndSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_and(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAnd() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_and(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchAndOrders() -{ - TestAtomic128FetchAndRelaxed(); - - TestAtomic128FetchAndAcquire(); - - TestAtomic128FetchAndRelease(); - - TestAtomic128FetchAndAcqRel(); - - TestAtomic128FetchAndSeqCst(); - - TestAtomic128FetchAnd(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32AndFetchRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.and_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AndFetchAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.and_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AndFetchRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.and_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AndFetchAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.and_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AndFetchSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.and_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AndFetch() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.and_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32AndFetchOrders() -{ - TestAtomicU32AndFetchRelaxed(); - - TestAtomicU32AndFetchAcquire(); - - TestAtomicU32AndFetchRelease(); - - TestAtomicU32AndFetchAcqRel(); - - TestAtomicU32AndFetchSeqCst(); - - TestAtomicU32AndFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64AndFetchRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.and_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AndFetchAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.and_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AndFetchRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.and_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AndFetchAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.and_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AndFetchSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.and_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AndFetch() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.and_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64AndFetchOrders() -{ - TestAtomicU64AndFetchRelaxed(); - - TestAtomicU64AndFetchAcquire(); - - TestAtomicU64AndFetchRelease(); - - TestAtomicU64AndFetchAcqRel(); - - TestAtomicU64AndFetchSeqCst(); - - TestAtomicU64AndFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128AndFetchRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.and_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AndFetchAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.and_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AndFetchRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.and_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AndFetchAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.and_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AndFetchSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.and_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AndFetch() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.and_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128AndFetchOrders() -{ - TestAtomic128AndFetchRelaxed(); - - TestAtomic128AndFetchAcquire(); - - TestAtomic128AndFetchRelease(); - - TestAtomic128AndFetchAcqRel(); - - TestAtomic128AndFetchSeqCst(); - - TestAtomic128AndFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OrFetchRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.or_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32OrFetchAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.or_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32OrFetchRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.or_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32OrFetchAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.or_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32OrFetchSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.or_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32OrFetch() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.or_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32OrFetchOrders() -{ - TestAtomicU32OrFetchRelaxed(); - - TestAtomicU32OrFetchAcquire(); - - TestAtomicU32OrFetchRelease(); - - TestAtomicU32OrFetchAcqRel(); - - TestAtomicU32OrFetchSeqCst(); - - TestAtomicU32OrFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OrFetchRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.or_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64OrFetchAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.or_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64OrFetchRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.or_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64OrFetchAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.or_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64OrFetchSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.or_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64OrFetch() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.or_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64OrFetchOrders() -{ - TestAtomicU64OrFetchRelaxed(); - - TestAtomicU64OrFetchAcquire(); - - TestAtomicU64OrFetchRelease(); - - TestAtomicU64OrFetchAcqRel(); - - TestAtomicU64OrFetchSeqCst(); - - TestAtomicU64OrFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128OrFetchRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.or_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128OrFetchAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.or_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128OrFetchRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.or_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128OrFetchAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.or_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128OrFetchSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.or_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128OrFetch() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.or_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128OrFetchOrders() -{ - TestAtomic128OrFetchRelaxed(); - - TestAtomic128OrFetchAcquire(); - - TestAtomic128OrFetchRelease(); - - TestAtomic128OrFetchAcqRel(); - - TestAtomic128OrFetchSeqCst(); - - TestAtomic128OrFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32FetchOrRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_or(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchOrAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_or(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchOrRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_or(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchOrAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_or(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchOrSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_or(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchOr() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_or(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchOrOrders() -{ - TestAtomicU32FetchOrRelaxed(); - - TestAtomicU32FetchOrAcquire(); - - TestAtomicU32FetchOrRelease(); - - TestAtomicU32FetchOrAcqRel(); - - TestAtomicU32FetchOrSeqCst(); - - TestAtomicU32FetchOr(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64FetchOrRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_or(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchOrAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_or(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchOrRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_or(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchOrAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_or(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchOrSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_or(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchOr() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_or(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchOrOrders() -{ - TestAtomicU64FetchOrRelaxed(); - - TestAtomicU64FetchOrAcquire(); - - TestAtomicU64FetchOrRelease(); - - TestAtomicU64FetchOrAcqRel(); - - TestAtomicU64FetchOrSeqCst(); - - TestAtomicU64FetchOr(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128FetchOrRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_or(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchOrAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_or(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchOrRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_or(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchOrAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_or(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchOrSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_or(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchOr() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_or(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchOrOrders() -{ - TestAtomic128FetchOrRelaxed(); - - TestAtomic128FetchOrAcquire(); - - TestAtomic128FetchOrRelease(); - - TestAtomic128FetchOrAcqRel(); - - TestAtomic128FetchOrSeqCst(); - - TestAtomic128FetchOr(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32FetchXorRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_xor(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchXorAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_xor(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchXorRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_xor(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchXorAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_xor(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchXorSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_xor(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchXor() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.fetch_xor(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32FetchXorOrders() -{ - TestAtomicU32FetchXorRelaxed(); - - TestAtomicU32FetchXorAcquire(); - - TestAtomicU32FetchXorRelease(); - - TestAtomicU32FetchXorAcqRel(); - - TestAtomicU32FetchXorSeqCst(); - - TestAtomicU32FetchXor(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64FetchXorRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_xor(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchXorAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_xor(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchXorRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_xor(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchXorAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_xor(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchXorSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_add(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchXor() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.fetch_xor(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64FetchXorOrders() -{ - TestAtomicU64FetchXorRelaxed(); - - TestAtomicU64FetchXorAcquire(); - - TestAtomicU64FetchXorRelease(); - - TestAtomicU64FetchXorAcqRel(); - - TestAtomicU64FetchXorSeqCst(); - - TestAtomicU64FetchXor(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128FetchXorRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_xor(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchXorAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_xor(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchXorRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_xor(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchXorAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_xor(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchXorSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_xor(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchXor() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.fetch_xor(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128FetchXorOrders() -{ - TestAtomic128FetchXorRelaxed(); - - TestAtomic128FetchXorAcquire(); - - TestAtomic128FetchXorRelease(); - - TestAtomic128FetchXorAcqRel(); - - TestAtomic128FetchXorSeqCst(); - - TestAtomic128FetchXor(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32XorFetchRelaxed() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.xor_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32XorFetchAcquire() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.xor_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32XorFetchRelease() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.xor_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32XorFetchAcqRel() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.xor_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32XorFetchSeqCst() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.xor_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32XorFetch() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic.xor_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU32XorFetchOrders() -{ - TestAtomicU32XorFetchRelaxed(); - - TestAtomicU32XorFetchAcquire(); - - TestAtomicU32XorFetchRelease(); - - TestAtomicU32XorFetchAcqRel(); - - TestAtomicU32XorFetchSeqCst(); - - TestAtomicU32XorFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64XorFetchRelaxed() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.xor_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64XorFetchAcquire() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.xor_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64XorFetchRelease() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.xor_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64XorFetchAcqRel() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.xor_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64XorFetchSeqCst() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.xor_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64XorFetch() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic.xor_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomicU64XorFetchOrders() -{ - TestAtomicU64XorFetchRelaxed(); - - TestAtomicU64XorFetchAcquire(); - - TestAtomicU64XorFetchRelease(); - - TestAtomicU64XorFetchAcqRel(); - - TestAtomicU64XorFetchSeqCst(); - - TestAtomicU64XorFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128XorFetchRelaxed() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.xor_fetch(1, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128XorFetchAcquire() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.xor_fetch(1, eastl::memory_order_acquire); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128XorFetchRelease() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.xor_fetch(1, eastl::memory_order_release); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128XorFetchAcqRel() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.xor_fetch(1, eastl::memory_order_acq_rel); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128XorFetchSeqCst() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.xor_fetch(1, eastl::memory_order_seq_cst); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128XorFetch() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic.xor_fetch(1); - - eastl::compiler_barrier_data_dependency(val); -} - -EA_NO_INLINE static void TestAtomic128XorFetchOrders() -{ - TestAtomic128XorFetchRelaxed(); - - TestAtomic128XorFetchAcquire(); - - TestAtomic128XorFetchRelease(); - - TestAtomic128XorFetchAcqRel(); - - TestAtomic128XorFetchSeqCst(); - - TestAtomic128XorFetch(); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorPlusPlus() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic++; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorPlusPlus() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic++; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128OperatorPlusPlus() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic++; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32PlusPlusOperator() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = ++atomic; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64PlusPlusOperator() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = ++atomic; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128PlusPlusOperator() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = ++atomic; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorMinusMinus() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic--; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorMinusMinus() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic--; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128OperatorMinusMinus() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic--; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32MinusMinusOperator() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = --atomic; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64MinusMinusOperator() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = --atomic; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128MinusMinusOperator() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = --atomic; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorPlusAssignment() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic += 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorPlusAssignment() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic += 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128OperatorPlusAssignment() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic += 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorMinusAssignment() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic -= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorMinusAssignment() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic -= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128OperatorMinusAssignment() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic -= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorAndAssignment() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic &= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorAndAssignment() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic &= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128OperatorAndAssignment() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic &= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorOrAssignment() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic |= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorOrAssignment() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic |= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128OperatorOrAssignment() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic |= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomicU32OperatorXorAssignment() -{ - eastl::atomic<uint32_t> atomic; - - uint32_t val = atomic ^= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_64BIT) - -EA_NO_INLINE static void TestAtomicU64OperatorXorAssignment() -{ - eastl::atomic<uint64_t> atomic; - - uint64_t val = atomic ^= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - -EA_NO_INLINE static void TestAtomic128OperatorXorAssignment() -{ - eastl::atomic<__uint128_t> atomic; - - __uint128_t val = atomic ^= 1; - - eastl::compiler_barrier_data_dependency(val); -} - -#endif - -EA_NO_INLINE static void TestAtomicSignalFenceRelaxed() -{ - eastl::atomic_signal_fence(eastl::memory_order_relaxed); -} - -EA_NO_INLINE static void TestAtomicSignalFenceAcquire() -{ - eastl::atomic_signal_fence(eastl::memory_order_acquire); -} - -EA_NO_INLINE static void TestAtomicSignalFenceRelease() -{ - eastl::atomic_signal_fence(eastl::memory_order_release); -} - -EA_NO_INLINE static void TestAtomicSignalFenceAcqRel() -{ - eastl::atomic_signal_fence(eastl::memory_order_acq_rel); -} - -EA_NO_INLINE static void TestAtomicSignalFenceSeqCst() -{ - eastl::atomic_signal_fence(eastl::memory_order_seq_cst); -} - -EA_NO_INLINE static void TestAtomicThreadFenceRelaxed() -{ - eastl::atomic_thread_fence(eastl::memory_order_relaxed); -} - -EA_NO_INLINE static void TestAtomicThreadFenceAcquire() -{ - eastl::atomic_thread_fence(eastl::memory_order_acquire); -} - -EA_NO_INLINE static void TestAtomicThreadFenceRelease() -{ - eastl::atomic_thread_fence(eastl::memory_order_release); -} - -EA_NO_INLINE static void TestAtomicThreadFenceAcqRel() -{ - eastl::atomic_thread_fence(eastl::memory_order_acq_rel); -} - -EA_NO_INLINE static void TestAtomicThreadFenceSeqCst() -{ - eastl::atomic_thread_fence(eastl::memory_order_seq_cst); -} - -EA_NO_INLINE static void TestAtomicPointerReadDepends() -{ - eastl::atomic<void*> atomic; - - void* p = atomic.load(eastl::memory_order_read_depends); - - eastl::compiler_barrier_data_dependency(p); -} - -struct ReadDependsStruct -{ - int a; - int b; -}; - -eastl::atomic<ReadDependsStruct*> gAtomicPtr; - -EA_NO_INLINE int TestAtomicReadDependsStruct() -{ - ReadDependsStruct* p = gAtomicPtr.load(eastl::memory_order_read_depends); - - int a = p->a; - int b = p->b; - - return a + b; -} - -EA_NO_INLINE static void TestCompilerBarrierDataDependency() -{ - { - UserType128 t{4, 5, 7, 8}; - - eastl::compiler_barrier_data_dependency(t); - } - - { - void* p = (void*)0xdeadbeef; - - eastl::compiler_barrier_data_dependency(p); - } - - { - bool b = false; - - eastl::compiler_barrier_data_dependency(b); - } -} - -struct ReadDependsIntrusive -{ - int a; - int b; - struct ReadDependsIntrusive* next; - int c; - int d; -}; - -eastl::atomic<ReadDependsIntrusive**> gListHead; - -EA_NO_INLINE static int TestAtomicReadDependsIntrusive() -{ - ReadDependsIntrusive** intrusivePtr = gListHead.load(eastl::memory_order_read_depends); - ReadDependsIntrusive* ptr = ((ReadDependsIntrusive*)(((char*)intrusivePtr) - offsetof(ReadDependsIntrusive, next))); - - int a = ptr->a; - int b = ptr->b; - int c = ptr->c; - int d = ptr->d; - - return a + b + c + d; -} - -#if defined(EASTL_ATOMIC_HAS_32BIT) - -EA_NO_INLINE static void TestAtomic32LoadStoreSameAddressSeqCst() -{ - eastl::atomic<uint32_t> atomic{0}; - - uint32_t ret1 = atomic.load(eastl::memory_order_relaxed); - - atomic.store(4, eastl::memory_order_relaxed); - - uint32_t ret2 = atomic.load(eastl::memory_order_relaxed); - - uint32_t ret3 = atomic.load(eastl::memory_order_relaxed); - - atomic.store(5, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret1); - eastl::compiler_barrier_data_dependency(ret2); - eastl::compiler_barrier_data_dependency(ret3); -} - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -EA_NO_INLINE static void TestAtomic128LoadStoreSameAddressSeqCst() -{ - eastl::atomic<UserType128> atomic{UserType128{0, 0, 0, 0}}; - - UserType128 ret1 = atomic.load(eastl::memory_order_relaxed); - - atomic.store(UserType128{1, 0, 2, 4}, eastl::memory_order_relaxed); - - UserType128 ret2 = atomic.load(eastl::memory_order_relaxed); - - UserType128 ret3 = atomic.load(eastl::memory_order_relaxed); - - atomic.store(UserType128{1, 1, 2, 4}, eastl::memory_order_relaxed); - - eastl::compiler_barrier_data_dependency(ret1); - eastl::compiler_barrier_data_dependency(ret2); - eastl::compiler_barrier_data_dependency(ret3); -} - -#endif - -int TestAtomicAsm() -{ - int nErrorCount = 0; - - // Stores - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32StoreOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64StoreOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) - TestAtomic128StoreOrders(); - #endif - } - - // Loads - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32LoadOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64LoadOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) - TestAtomic128LoadOrders(); - #endif - } - - // exchange - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32ExchangeOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64ExchangeOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) - TestAtomic128ExchangeOrders(); - #endif - } - - // operator T - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorT(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorT(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) - TestAtomic128OperatorT(); - #endif - } - - // operator= - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorEqual(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorEqual(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) - TestAtomic128OperatorEqual(); - #endif - } - - // compare_exchange_weak - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32CompareExchangeWeakOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64CompareExchangeWeakOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) - TestAtomic128CompareExchangeWeakOrders(); - #endif - } - - // compare_exchange_strong - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32CompareExchangeStrongOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64CompareExchangeStrongOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) - TestAtomic128CompareExchangeStrongOrders(); - #endif - } - - // fetch_add - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32FetchAddOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64FetchAddOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128FetchAddOrders(); - #endif - } - - // add_fetch - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32AddFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64AddFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128AddFetchOrders(); - #endif - } - - // fetch_sub - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32FetchSubOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64FetchSubOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128FetchSubOrders(); - #endif - } - - // sub_fetch - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32SubFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64SubFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128SubFetchOrders(); - #endif - } - - // fetch_and - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32FetchAndOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64FetchAndOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128FetchAndOrders(); - #endif - } - - // and_fetch - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32AndFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64AndFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128AndFetchOrders(); - #endif - } - - // fetch_or - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32FetchOrOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64FetchOrOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128FetchOrOrders(); - #endif - } - - // or_fetch - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OrFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OrFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128OrFetchOrders(); - #endif - } - - // fetch_xor - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32FetchXorOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64FetchXorOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128FetchXorOrders(); - #endif - } - - // xor_fetch - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32XorFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64XorFetchOrders(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128XorFetchOrders(); - #endif - } - - // operator++/++operator - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorPlusPlus(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorPlusPlus(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128OperatorPlusPlus(); - #endif - - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32PlusPlusOperator(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64PlusPlusOperator(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128PlusPlusOperator(); - #endif - } - - // operator--/--operator - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorMinusMinus(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorMinusMinus(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128OperatorMinusMinus(); - #endif - - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32MinusMinusOperator(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64MinusMinusOperator(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128MinusMinusOperator(); - #endif - } - - // operator+= - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorPlusAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorPlusAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128OperatorPlusAssignment(); - #endif - } - - // operator-= - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorMinusAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorMinusAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128OperatorMinusAssignment(); - #endif - } - - // operator&= - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorAndAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorAndAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128OperatorAndAssignment(); - #endif - } - - // operator|= - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorOrAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorOrAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128OperatorOrAssignment(); - #endif - } - - // operator^= - { - #if defined(EASTL_ATOMIC_HAS_32BIT) - TestAtomicU32OperatorXorAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - TestAtomicU64OperatorXorAssignment(); - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) - TestAtomic128OperatorXorAssignment(); - #endif - } - - // atomic_signal_fence - { - TestAtomicSignalFenceRelaxed(); - - TestAtomicSignalFenceAcquire(); - - TestAtomicSignalFenceRelease(); - - TestAtomicSignalFenceAcqRel(); - - TestAtomicSignalFenceSeqCst(); - } - - // atomic_thread_fence - { - TestAtomicThreadFenceRelaxed(); - - TestAtomicThreadFenceAcquire(); - - TestAtomicThreadFenceRelease(); - - TestAtomicThreadFenceAcqRel(); - - TestAtomicThreadFenceSeqCst(); - } - - // atomic pointer read depends - { - TestAtomicPointerReadDepends(); - } - - // atomic pointer read depends - { - ReadDependsStruct rds {3, 2}; - - gAtomicPtr.store(&rds, eastl::memory_order_release); - - int ret = TestAtomicReadDependsStruct(); - eastl::compiler_barrier_data_dependency(ret); - } - - { - ReadDependsIntrusive rdi {3, 2, &rdi, 1, 0}; - - gListHead.store(&(rdi.next), eastl::memory_order_release); - - int ret = TestAtomicReadDependsIntrusive(); - eastl::compiler_barrier_data_dependency(ret); - } - - { - TestCompilerBarrierDataDependency(); - } - -#if defined(EASTL_ATOMIC_HAS_32BIT) - - TestAtomic32LoadStoreSameAddressSeqCst(); - -#endif - -#if defined(EASTL_ATOMIC_HAS_128BIT) - - TestAtomic128LoadStoreSameAddressSeqCst(); - -#endif - - return nErrorCount; -} diff --git a/test/source/TestAtomicBasic.cpp b/test/source/TestAtomicBasic.cpp deleted file mode 100644 index 166b030..0000000 --- a/test/source/TestAtomicBasic.cpp +++ /dev/null @@ -1,4083 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" - -#include <EASTL/atomic.h> - - -/** - * This is a basic test suite that tests all functionality is implemented - * and that all operations do as expected. - * I.E. fetch_add returns the previous value and add_fetch returns the current value - */ - -static eastl::atomic<int> sAtomicInt{ 4 }; -static eastl::atomic<void*> sAtomicPtr{ nullptr }; - -static int TestAtomicConstantInitialization() -{ - int nErrorCount; - - EATEST_VERIFY(sAtomicInt.load() == 4); - EATEST_VERIFY(sAtomicPtr == nullptr); - - return 0; -} - -class AtomicStandaloneBasicTest -{ -public: - - int RunTest() - { - AtomicSignalFence(); - - AtomicThreadFence(); - - AtomicCpuPause(); - - AtomicCompilerBarrier(); - - return nErrorCount; - } - -private: - - void AtomicSignalFence(); - - void AtomicThreadFence(); - - void AtomicCpuPause(); - - void AtomicCompilerBarrier(); - -private: - - int nErrorCount = 0; -}; - -void AtomicStandaloneBasicTest::AtomicSignalFence() -{ - eastl::atomic_signal_fence(eastl::memory_order_relaxed); - - eastl::atomic_signal_fence(eastl::memory_order_acquire); - - eastl::atomic_signal_fence(eastl::memory_order_release); - - eastl::atomic_signal_fence(eastl::memory_order_acq_rel); - - eastl::atomic_signal_fence(eastl::memory_order_seq_cst); -} - -void AtomicStandaloneBasicTest::AtomicThreadFence() -{ - eastl::atomic_thread_fence(eastl::memory_order_relaxed); - - eastl::atomic_thread_fence(eastl::memory_order_acquire); - - eastl::atomic_thread_fence(eastl::memory_order_release); - - eastl::atomic_thread_fence(eastl::memory_order_acq_rel); - - eastl::atomic_thread_fence(eastl::memory_order_seq_cst); -} - -void AtomicStandaloneBasicTest::AtomicCpuPause() -{ - eastl::cpu_pause(); -} - -void AtomicStandaloneBasicTest::AtomicCompilerBarrier() -{ - eastl::compiler_barrier(); - - { - bool ret = false; - eastl::compiler_barrier_data_dependency(ret); - } -} - -class AtomicFlagBasicTest -{ -public: - - using AtomicType = eastl::atomic_flag; - using BoolType = bool; - - int RunTest() - { - TestAtomicFlagCtor(); - - TestAtomicFlagClear(); - - TestAtomicFlagTestAndSet(); - - TestAtomicFlagTest(); - - TestAllMemoryOrders(); - - TestAtomicFlagStandalone(); - - return nErrorCount; - } - -private: - - void TestAtomicFlagCtor(); - - void TestAtomicFlagClear(); - - void TestAtomicFlagTestAndSet(); - - void TestAtomicFlagTest(); - - void TestAllMemoryOrders(); - - void TestAtomicFlagStandalone(); - -private: - - int nErrorCount = 0; -}; - -void AtomicFlagBasicTest::TestAtomicFlagCtor() -{ - { - AtomicType atomic; - - VERIFY(atomic.test(eastl::memory_order_relaxed) == false); - } - - { - AtomicType atomic{ false }; - - VERIFY(atomic.test(eastl::memory_order_relaxed) == false); - } - - { - AtomicType atomic{ true }; - - VERIFY(atomic.test(eastl::memory_order_relaxed) == true); - } -} - -void AtomicFlagBasicTest::TestAtomicFlagClear() -{ - { - AtomicType atomic; - - atomic.clear(eastl::memory_order_relaxed); - - VERIFY(atomic.test(eastl::memory_order_relaxed) == false); - } - - { - AtomicType atomic{ true }; - - atomic.clear(eastl::memory_order_relaxed); - - VERIFY(atomic.test(eastl::memory_order_relaxed) == false); - } -} - -void AtomicFlagBasicTest::TestAtomicFlagTestAndSet() -{ - { - AtomicType atomic; - - BoolType ret = atomic.test_and_set(eastl::memory_order_relaxed); - - VERIFY(ret == false); - - VERIFY(atomic.test(eastl::memory_order_relaxed) == true); - } - - { - AtomicType atomic{ true }; - - BoolType ret = atomic.test_and_set(eastl::memory_order_relaxed); - - VERIFY(ret == true); - - VERIFY(atomic.test(eastl::memory_order_relaxed) == true); - } -} - -void AtomicFlagBasicTest::TestAtomicFlagTest() -{ - { - AtomicType atomic; - - VERIFY(atomic.test(eastl::memory_order_relaxed) == false); - } - - { - AtomicType atomic{ true }; - - VERIFY(atomic.test(eastl::memory_order_relaxed) == true); - } -} - -void AtomicFlagBasicTest::TestAllMemoryOrders() -{ - { - AtomicType atomic; - - atomic.clear(); - - atomic.clear(eastl::memory_order_relaxed); - - atomic.clear(eastl::memory_order_release); - - atomic.clear(eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - atomic.test_and_set(); - - atomic.test_and_set(eastl::memory_order_relaxed); - - atomic.test_and_set(eastl::memory_order_acquire); - - atomic.test_and_set(eastl::memory_order_release); - - atomic.test_and_set(eastl::memory_order_acq_rel); - - atomic.test_and_set(eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - BoolType ret = atomic.test(); - - ret = atomic.test(eastl::memory_order_relaxed); - - ret = atomic.test(eastl::memory_order_acquire); - - ret = atomic.test(eastl::memory_order_seq_cst); - } -} - -void AtomicFlagBasicTest::TestAtomicFlagStandalone() -{ - { - AtomicType atomic; - - BoolType ret = atomic_flag_test_and_set(&atomic); - - ret = atomic_flag_test_and_set_explicit(&atomic, eastl::memory_order_relaxed); - - ret = atomic_flag_test_and_set_explicit(&atomic, eastl::memory_order_acquire); - - ret = atomic_flag_test_and_set_explicit(&atomic, eastl::memory_order_release); - - ret = atomic_flag_test_and_set_explicit(&atomic, eastl::memory_order_acq_rel); - - ret = atomic_flag_test_and_set_explicit(&atomic, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - atomic_flag_clear(&atomic); - - atomic_flag_clear_explicit(&atomic, eastl::memory_order_relaxed); - - atomic_flag_clear_explicit(&atomic, eastl::memory_order_release); - - atomic_flag_clear_explicit(&atomic, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - BoolType ret = atomic_flag_test(&atomic); - - ret = atomic_flag_test_explicit(&atomic, eastl::memory_order_relaxed); - - ret = atomic_flag_test_explicit(&atomic, eastl::memory_order_acquire); - - ret = atomic_flag_test_explicit(&atomic, eastl::memory_order_seq_cst); - } -} - -class AtomicVoidPointerBasicTest -{ -public: - - using AtomicType = eastl::atomic<void*>; - using PtrType = void*; - - int RunTest() - { - TestAtomicCtor(); - - TestAssignmentOperators(); - - TestIsLockFree(); - - TestStore(); - - TestLoad(); - - TestExchange(); - - TestCompareExchangeWeak(); - - TestCompareExchangeStrong(); - - TestAllMemoryOrders(); - - return nErrorCount; - } - -private: - - void TestAtomicCtor(); - - void TestAssignmentOperators(); - - void TestIsLockFree(); - - void TestStore(); - - void TestLoad(); - - void TestExchange(); - - void TestCompareExchangeWeak(); - - void TestCompareExchangeStrong(); - - void TestAllMemoryOrders(); - -private: - - int nErrorCount = 0; -}; - -void AtomicVoidPointerBasicTest::TestAtomicCtor() -{ - { - AtomicType atomic; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } - - { - AtomicType atomic{ (PtrType)0x04 }; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x04); - } -} - -void AtomicVoidPointerBasicTest::TestAssignmentOperators() -{ - { - AtomicType atomic; - - PtrType ret = atomic = (PtrType)0x04; - - VERIFY(ret == (PtrType)0x04); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x04); - } - - { - AtomicType atomic; - - PtrType ret = atomic = (PtrType)0x0; - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } -} - -void AtomicVoidPointerBasicTest::TestIsLockFree() -{ - { - AtomicType atomic; - - VERIFY(atomic.is_lock_free() == true); - - VERIFY(atomic.is_always_lock_free == true); - } -} - -void AtomicVoidPointerBasicTest::TestStore() -{ - { - PtrType val = (PtrType)0x0; - AtomicType atomic; - - atomic.store(val, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == val); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic; - - atomic.store(val, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == val); - } -} - -void AtomicVoidPointerBasicTest::TestLoad() -{ - { - AtomicType atomic{ (PtrType)0x4 }; - - PtrType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic == (PtrType)0x4); - } -} - -void AtomicVoidPointerBasicTest::TestExchange() -{ - { - AtomicType atomic; - - PtrType ret = atomic.exchange((PtrType)0x4, eastl::memory_order_release); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } -} - -void AtomicVoidPointerBasicTest::TestCompareExchangeWeak() -{ - { - AtomicType atomic; - - PtrType observed = (PtrType)0x0; - bool ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - if (ret) - { - VERIFY(ret == true); - VERIFY(observed == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - } - - { - AtomicType atomic; - - PtrType observed = (PtrType)0x4; - bool ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - VERIFY(ret == false); - VERIFY(observed == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } -} - -void AtomicVoidPointerBasicTest::TestCompareExchangeStrong() -{ - { - AtomicType atomic; - - PtrType observed = (PtrType)0x0; - bool ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - VERIFY(ret == true); - VERIFY(observed == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType observed = (PtrType)0x4; - bool ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - VERIFY(ret == false); - VERIFY(observed == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } -} - -void AtomicVoidPointerBasicTest::TestAllMemoryOrders() -{ - { - AtomicType atomic; - PtrType val = (PtrType)0x4; - - atomic.store(val); - - atomic.store(val, eastl::memory_order_relaxed); - - atomic.store(val, eastl::memory_order_release); - - atomic.store(val, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - PtrType ret = atomic.load(); - - ret = atomic.load(eastl::memory_order_relaxed); - - ret = atomic.load(eastl::memory_order_acquire); - - ret = atomic.load(eastl::memory_order_seq_cst); - - ret = atomic.load(eastl::memory_order_read_depends); - } - - { - AtomicType atomic; - - PtrType ret = atomic.exchange((PtrType)0x4); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_relaxed); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_acquire); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_release); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_acq_rel); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - PtrType observed = (PtrType)0x0; - - bool ret = atomic.compare_exchange_weak(observed, (PtrType)0x4); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_release); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - PtrType observed = (PtrType)0x0; - - bool ret = atomic.compare_exchange_strong(observed, (PtrType)0x4); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_release); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - PtrType observed = (PtrType)0x0; - bool ret; - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acquire, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_release, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - PtrType observed = (PtrType)0x0; - bool ret; - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acquire, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_release, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - } -} - -class AtomicPointerBasicTest -{ -public: - - using AtomicType = eastl::atomic<uint32_t*>; - using PtrType = uint32_t*; - - int RunTest() - { - TestAtomicCtor(); - - TestAssignmentOperators(); - - TestIsLockFree(); - - TestStore(); - - TestLoad(); - - TestExchange(); - - TestCompareExchangeWeak(); - - TestCompareExchangeStrong(); - - TestAllMemoryOrders(); - - TestFetchAdd(); - TestAddFetch(); - - TestFetchSub(); - TestSubFetch(); - - TestAtomicPointerStandalone(); - - return nErrorCount; - } - -private: - - void TestAtomicCtor(); - - void TestAssignmentOperators(); - - void TestIsLockFree(); - - void TestStore(); - - void TestLoad(); - - void TestExchange(); - - void TestCompareExchangeWeak(); - - void TestCompareExchangeStrong(); - - void TestAllMemoryOrders(); - - void TestFetchAdd(); - void TestAddFetch(); - - void TestFetchSub(); - void TestSubFetch(); - - void TestAtomicPointerStandalone(); - -private: - - int nErrorCount = 0; -}; - -void AtomicPointerBasicTest::TestAtomicCtor() -{ - { - AtomicType atomic{}; - - PtrType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == nullptr); - } - - { - AtomicType atomic{ (PtrType)0x4 }; - - PtrType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - } -} - -void AtomicPointerBasicTest::TestAssignmentOperators() -{ - { - PtrType val = (PtrType)0x4; - AtomicType atomic{val}; - - PtrType expected = (PtrType)0x8; - - PtrType ret = atomic = expected; - - VERIFY(ret == expected); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - PtrType val = (PtrType)0x0; - AtomicType atomic{val}; - - PtrType ret = atomic = val; - - VERIFY(ret == val); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == val); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{val}; - - PtrType expected = (PtrType)0x8; - PtrType ret = ++atomic; - - VERIFY(ret == expected); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - PtrType val = (PtrType)0x4; - - AtomicType atomic{val}; - - PtrType expected = (PtrType)0x8; - PtrType ret = atomic++; - - VERIFY(ret == val); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{val}; - - PtrType expected = (PtrType)0x10; - PtrType ret = atomic += 3; - - VERIFY(ret == expected); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{val}; - - PtrType expected = (PtrType)0x4; - PtrType ret = atomic += 0; - - VERIFY(ret == expected); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{val}; - - PtrType expected = (PtrType)0x0; - PtrType ret = atomic -= 1; - - VERIFY(ret == expected); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{val}; - - PtrType expected = (PtrType)0x4; - PtrType ret = atomic -= 0; - - VERIFY(ret == expected); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } -} - -void AtomicPointerBasicTest::TestIsLockFree() -{ - { - AtomicType atomic; - - VERIFY(atomic.is_lock_free() == true); - - VERIFY(atomic.is_always_lock_free == true); - } -} - -void AtomicPointerBasicTest::TestStore() -{ - { - PtrType val = (PtrType)0x0; - AtomicType atomic; - - atomic.store(val, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == val); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic; - - atomic.store(val, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == val); - } -} - -void AtomicPointerBasicTest::TestLoad() -{ - { - AtomicType atomic{ (PtrType)0x4 }; - - PtrType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic == (PtrType)0x4); - } -} - -void AtomicPointerBasicTest::TestCompareExchangeWeak() -{ - { - AtomicType atomic; - - PtrType observed = (PtrType)0x0; - bool ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - if (ret) - { - VERIFY(ret == true); - VERIFY(observed == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - } - - { - AtomicType atomic; - - PtrType observed = (PtrType)0x4; - bool ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - VERIFY(ret == false); - VERIFY(observed == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } -} - -void AtomicPointerBasicTest::TestCompareExchangeStrong() -{ - { - AtomicType atomic; - - PtrType observed = (PtrType)0x0; - bool ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - VERIFY(ret == true); - VERIFY(observed == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType observed = (PtrType)0x4; - bool ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - VERIFY(ret == false); - VERIFY(observed == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } -} - -void AtomicPointerBasicTest::TestExchange() -{ - { - AtomicType atomic; - - PtrType ret = atomic.exchange((PtrType)0x4, eastl::memory_order_release); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } -} - -void AtomicPointerBasicTest::TestAllMemoryOrders() -{ - { - AtomicType atomic; - PtrType val = (PtrType)0x4; - - atomic.store(val); - - atomic.store(val, eastl::memory_order_relaxed); - - atomic.store(val, eastl::memory_order_release); - - atomic.store(val, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - PtrType ret = atomic.load(); - - ret = atomic.load(eastl::memory_order_relaxed); - - ret = atomic.load(eastl::memory_order_acquire); - - ret = atomic.load(eastl::memory_order_seq_cst); - - ret = atomic.load(eastl::memory_order_read_depends); - } - - { - AtomicType atomic; - - PtrType ret = atomic.fetch_add(0); - - ret = atomic.fetch_add(0, eastl::memory_order_relaxed); - - ret = atomic.fetch_add(0, eastl::memory_order_acquire); - - ret = atomic.fetch_add(0, eastl::memory_order_release); - - ret = atomic.fetch_add(0, eastl::memory_order_acq_rel); - - ret = atomic.fetch_add(0, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - PtrType ret = atomic.fetch_sub(0); - - ret = atomic.fetch_sub(0, eastl::memory_order_relaxed); - - ret = atomic.fetch_sub(0, eastl::memory_order_acquire); - - ret = atomic.fetch_sub(0, eastl::memory_order_release); - - ret = atomic.fetch_sub(0, eastl::memory_order_acq_rel); - - ret = atomic.fetch_sub(0, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - PtrType ret = atomic.add_fetch(0); - - ret = atomic.add_fetch(0, eastl::memory_order_relaxed); - - ret = atomic.add_fetch(0, eastl::memory_order_acquire); - - ret = atomic.add_fetch(0, eastl::memory_order_release); - - ret = atomic.add_fetch(0, eastl::memory_order_acq_rel); - - ret = atomic.add_fetch(0, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - PtrType ret = atomic.sub_fetch(0); - - ret = atomic.sub_fetch(0, eastl::memory_order_relaxed); - - ret = atomic.sub_fetch(0, eastl::memory_order_acquire); - - ret = atomic.sub_fetch(0, eastl::memory_order_release); - - ret = atomic.sub_fetch(0, eastl::memory_order_acq_rel); - - ret = atomic.sub_fetch(0, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - PtrType ret = atomic.exchange((PtrType)0x4); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_relaxed); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_acquire); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_release); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_acq_rel); - - ret = atomic.exchange((PtrType)0x4, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - PtrType observed = (PtrType)0x0; - - bool ret = atomic.compare_exchange_weak(observed, (PtrType)0x4); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_release); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - PtrType observed = (PtrType)0x0; - - bool ret = atomic.compare_exchange_strong(observed, (PtrType)0x4); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_release); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - PtrType observed = (PtrType)0x0; - bool ret; - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acquire, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_release, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - PtrType observed = (PtrType)0x0; - bool ret; - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acquire, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_release, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, (PtrType)0x4, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - } -} - -void AtomicPointerBasicTest::TestFetchAdd() -{ - { - PtrType val = (PtrType)0x4; - AtomicType atomic{ val }; - - PtrType ret = atomic.fetch_add(1, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x8); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{ val }; - - PtrType ret = atomic.fetch_add(0, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } -} - -void AtomicPointerBasicTest::TestAddFetch() -{ - { - PtrType val = (PtrType)0x4; - AtomicType atomic{ val }; - - PtrType ret = atomic.add_fetch(1, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x8); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x8); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{ val }; - - PtrType ret = atomic.add_fetch(0, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } -} - -void AtomicPointerBasicTest::TestFetchSub() -{ - { - PtrType val = (PtrType)0x4; - AtomicType atomic{ val }; - - PtrType ret = atomic.fetch_sub(1, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{ val }; - - PtrType ret = atomic.fetch_sub(0, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } -} - -void AtomicPointerBasicTest::TestSubFetch() -{ - { - PtrType val = (PtrType)0x4; - AtomicType atomic{ val }; - - PtrType ret = atomic.sub_fetch(1, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } - - { - PtrType val = (PtrType)0x4; - AtomicType atomic{ val }; - - PtrType ret = atomic.sub_fetch(0, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } -} - -void AtomicPointerBasicTest::TestAtomicPointerStandalone() -{ - { - AtomicType atomic; - - VERIFY(atomic_is_lock_free(&atomic) == true); - } - - { - AtomicType atomic; - PtrType val = (PtrType)0x4; - - atomic_store(&atomic, val); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == val); - } - - { - AtomicType atomic; - PtrType val = (PtrType)0x4; - - atomic_store_explicit(&atomic, val, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == val); - } - - { - AtomicType atomic; - - PtrType ret = atomic_load(&atomic); - - VERIFY(ret == (PtrType)0x0); - } - - { - AtomicType atomic; - - PtrType ret = atomic_load_explicit(&atomic, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x0); - } - - { - AtomicType atomic; - - PtrType ret = atomic_load_cond(&atomic, [](PtrType val) { return true; }); - - VERIFY(ret == (PtrType)0x0); - } - - { - AtomicType atomic; - - PtrType ret = atomic_load_cond_explicit(&atomic, [](PtrType val) { return true; }, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x0); - } - - { - AtomicType atomic; - - PtrType ret = atomic_exchange(&atomic, (PtrType)0x4); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType ret = atomic_exchange_explicit(&atomic, (PtrType)0x4, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType ret = atomic_add_fetch(&atomic, 1); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType ret = atomic_add_fetch_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType ret = atomic_fetch_add(&atomic, 1); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType ret = atomic_fetch_add_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic{ (PtrType)0x4 }; - - PtrType ret = atomic_fetch_sub(&atomic, 1); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } - - { - AtomicType atomic{ (PtrType)0x4 }; - - PtrType ret = atomic_fetch_sub_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x4); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } - - { - AtomicType atomic{ (PtrType)0x4 }; - - PtrType ret = atomic_sub_fetch(&atomic, 1); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } - - { - AtomicType atomic{ (PtrType)0x4 }; - - PtrType ret = atomic_sub_fetch_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == (PtrType)0x0); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x0); - } - - { - AtomicType atomic; - - PtrType expected = (PtrType)0x0; - bool ret = atomic_compare_exchange_strong(&atomic, &expected, (PtrType)0x4); - - VERIFY(ret == true); - - VERIFY(expected == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType expected = (PtrType)0x0; - bool ret = atomic_compare_exchange_strong_explicit(&atomic, &expected, (PtrType)0x4, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - VERIFY(ret == true); - - VERIFY(expected == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - - { - AtomicType atomic; - - PtrType expected = (PtrType)0x0; - bool ret = atomic_compare_exchange_weak(&atomic, &expected, (PtrType)0x4); - - if (ret) - { - VERIFY(ret == true); - - VERIFY(expected == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - } - - { - AtomicType atomic; - - PtrType expected = (PtrType)0x0; - bool ret = atomic_compare_exchange_weak_explicit(&atomic, &expected, (PtrType)0x4, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - if (ret) - { - VERIFY(ret == true); - - VERIFY(expected == (PtrType)0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == (PtrType)0x4); - } - } -} - -struct AtomicNonTriviallyConstructible -{ - AtomicNonTriviallyConstructible() - : a(0) - , b(0) - { - } - - AtomicNonTriviallyConstructible(uint16_t a, uint16_t b) - : a(a) - , b(b) - { - } - - friend bool operator==(const AtomicNonTriviallyConstructible& a, const AtomicNonTriviallyConstructible& b) - { - return a.a == b.a && a.b == b.b; - } - - uint16_t a; - uint16_t b; -}; - -struct AtomicNonTriviallyConstructibleNoExcept -{ - AtomicNonTriviallyConstructibleNoExcept() noexcept - : a(0) - , b(0) - { - } - - AtomicNonTriviallyConstructibleNoExcept(uint16_t a, uint16_t b) noexcept - : a(a) - , b(b) - { - } - - friend bool operator==(const AtomicNonTriviallyConstructibleNoExcept& a, const AtomicNonTriviallyConstructibleNoExcept& b) - { - return a.a == b.a && a.b == b.b; - } - - uint16_t a; - uint16_t b; -}; - -struct AtomicUserType16 -{ - uint8_t a; - uint8_t b; - - friend bool operator==(const AtomicUserType16& a, const AtomicUserType16& b) - { - return (a.a == b.a) && (a.b == b.b); - } -}; - -struct AtomicUserType128 -{ - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; - - AtomicUserType128() = default; - - AtomicUserType128(const AtomicUserType128&) = default; - - AtomicUserType128(uint32_t a, uint32_t b) - : a(a) - , b(b) - , c(0) - , d(0) - { - } - - AtomicUserType128& operator=(const AtomicUserType128&) = default; - - friend bool operator==(const AtomicUserType128& a, const AtomicUserType128& b) - { - return (a.a == b.a) && (a.b == b.b) && (a.c == b.c) && (a.d == b.d); - } -}; - -template <typename T> -class AtomicUserTypeBasicTest -{ -public: - - using AtomicType = eastl::atomic<T>; - using UserType = T; - - int RunTest() - { - TestAtomicCtor(); - - TestAssignmentOperators(); - - TestIsLockFree(); - - TestStore(); - - TestLoad(); - - TestExchange(); - - TestCompareExchangeWeak(); - - TestCompareExchangeStrong(); - - TestAllMemoryOrders(); - - return nErrorCount; - } - -private: - - void TestAtomicCtor(); - - void TestAssignmentOperators(); - - void TestIsLockFree(); - - void TestStore(); - - void TestLoad(); - - void TestExchange(); - - void TestCompareExchangeWeak(); - - void TestCompareExchangeStrong(); - - void TestAllMemoryOrders(); - -private: - - int nErrorCount = 0; -}; - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestAtomicCtor() -{ - { - AtomicType atomic; - UserType expected{0, 0}; - - UserType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == expected); - } - - { - AtomicType atomic{ {5, 8} }; - UserType expected{5, 8}; - - UserType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == expected); - } -} - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestAssignmentOperators() -{ - { - AtomicType atomic; - UserType expected{5, 6}; - - atomic = {5, 6}; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - AtomicType atomic; - UserType expected{0, 0}; - - atomic = {0, 0}; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } -} - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestIsLockFree() -{ - { - AtomicType atomic; - - VERIFY(atomic.is_lock_free() == true); - - VERIFY(AtomicType::is_always_lock_free == true); - } -} - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestStore() -{ - { - AtomicType atomic; - UserType expected{5, 6}; - - atomic.store(expected, eastl::memory_order_relaxed); - - UserType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == expected); - } - - { - AtomicType atomic; - UserType expected{5, 6}; - - atomic.store({5, 6}, eastl::memory_order_relaxed); - - UserType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == expected); - } -} - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestLoad() -{ - { - AtomicType atomic; - UserType expected{0, 0}; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - - VERIFY(atomic == expected); - } - - { - AtomicType atomic{ {5, 6} }; - UserType expected{5, 6}; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - - VERIFY(atomic == expected); - } -} - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestExchange() -{ - { - AtomicType atomic; - UserType expected{0, 0}; - - UserType ret = atomic.exchange({0, 0}, eastl::memory_order_relaxed); - - VERIFY(ret == expected); - } - - { - AtomicType atomic; - UserType expected{0, 0}; - UserType expected2{0, 1}; - - UserType ret = atomic.exchange({0, 1}, eastl::memory_order_relaxed); - - VERIFY(ret == expected); - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected2); - } -} - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestCompareExchangeWeak() -{ - { - AtomicType atomic; - - UserType observed{0, 0}; - bool ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_relaxed); - - UserType expected{0, 0}; - if (ret) - { - VERIFY(ret == true); - VERIFY(observed == expected); - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - } - - { - AtomicType atomic; - - UserType observed{0, 0}; - bool ret = atomic.compare_exchange_weak(observed, {0, 1}, eastl::memory_order_relaxed); - - UserType expected{0, 1}; - UserType expected2{0, 0}; - if (ret) - { - VERIFY(ret == true); - VERIFY(observed == expected2); - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - } - - { - AtomicType atomic; - - UserType observed{0, 1}; - bool ret = atomic.compare_exchange_weak(observed, {0, 1}, eastl::memory_order_relaxed); - - UserType expected{0, 0}; - - VERIFY(ret == false); - VERIFY(observed == expected); - } -} - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestCompareExchangeStrong() -{ - { - AtomicType atomic; - - UserType observed{0, 0}; - bool ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_relaxed); - - UserType expected{0, 0}; - - VERIFY(ret == true); - VERIFY(observed == expected); - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - AtomicType atomic; - - UserType observed{0, 0}; - bool ret = atomic.compare_exchange_strong(observed, {0, 1}, eastl::memory_order_relaxed); - - UserType expected{0, 1}; - UserType expected2{0, 0}; - - VERIFY(ret == true); - VERIFY(observed == expected2); - VERIFY(atomic.load(eastl::memory_order_relaxed) == expected); - } - - { - AtomicType atomic; - - UserType observed{0, 1}; - bool ret = atomic.compare_exchange_strong(observed, {0, 1}, eastl::memory_order_relaxed); - - UserType expected{0, 0}; - - VERIFY(ret == false); - VERIFY(observed == expected); - } -} - -template <typename T> -void AtomicUserTypeBasicTest<T>::TestAllMemoryOrders() -{ - { - AtomicType atomic; - UserType val{0, 1}; - - atomic.store(val); - - atomic.store(val, eastl::memory_order_relaxed); - - atomic.store(val, eastl::memory_order_release); - - atomic.store(val, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - UserType ret = atomic.load(); - - ret = atomic.load(eastl::memory_order_relaxed); - - ret = atomic.load(eastl::memory_order_acquire); - - ret = atomic.load(eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - UserType ret = atomic.exchange({0, 1}); - - ret = atomic.exchange({0, 0}, eastl::memory_order_relaxed); - - ret = atomic.exchange({0, 0}, eastl::memory_order_acquire); - - ret = atomic.exchange({0, 0}, eastl::memory_order_release); - - ret = atomic.exchange({0, 0}, eastl::memory_order_acq_rel); - - ret = atomic.exchange({0, 0}, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - UserType observed{0, 0}; - - bool ret = atomic.compare_exchange_weak(observed, {0, 0}); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_release); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - UserType observed{0, 0}; - - bool ret = atomic.compare_exchange_strong(observed, {0, 0}); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_release); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - UserType observed{0, 0}; - bool ret; - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_acquire, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_release, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, {0, 0}, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - UserType observed{0, 0}; - bool ret; - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_acquire, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_release, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, {0, 0}, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - } -} - - -class AtomicBoolBasicTest -{ -public: - - using AtomicType = eastl::atomic<bool>; - using BoolType = bool; - - int RunTest() - { - TestAtomicCtor(); - - TestAssignmentOperators(); - - TestIsLockFree(); - - TestStore(); - - TestLoad(); - - TestExchange(); - - TestCompareExchangeWeak(); - - TestCompareExchangeStrong(); - - TestAllMemoryOrders(); - - return nErrorCount; - } - -private: - - void TestAtomicCtor(); - - void TestAssignmentOperators(); - - void TestIsLockFree(); - - void TestStore(); - - void TestLoad(); - - void TestExchange(); - - void TestCompareExchangeWeak(); - - void TestCompareExchangeStrong(); - - void TestAllMemoryOrders(); - -private: - - int nErrorCount = 0; -}; - -void AtomicBoolBasicTest::TestAtomicCtor() -{ - { - AtomicType atomic{ false }; - - BoolType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == false); - } - - { - AtomicType atomic{ true }; - - BoolType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == true); - } - - { - AtomicType atomic; - - BoolType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == false); - } - - { - AtomicType atomic{}; - - BoolType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == false); - } -} - -void AtomicBoolBasicTest::TestAssignmentOperators() -{ - { - AtomicType atomic; - - BoolType ret = atomic = true; - - VERIFY(ret == true); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == true); - } -} - -void AtomicBoolBasicTest::TestIsLockFree() -{ - { - AtomicType atomic; - - bool ret = atomic.is_lock_free(); - - VERIFY(ret == true); - - VERIFY(AtomicType::is_always_lock_free == true); - } -} - -void AtomicBoolBasicTest::TestStore() -{ - { - AtomicType atomic; - - atomic.store(true, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == true); - } -} - -void AtomicBoolBasicTest::TestLoad() -{ - { - AtomicType atomic; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == false); - - VERIFY(atomic == false); - } - - { - AtomicType atomic{ true }; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == true); - - VERIFY(atomic == true); - } -} - -void AtomicBoolBasicTest::TestExchange() -{ - { - AtomicType atomic; - - BoolType ret = atomic.exchange(false, eastl::memory_order_relaxed); - - VERIFY(ret == false); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == false); - } - - { - AtomicType atomic; - - BoolType ret = atomic.exchange(true, eastl::memory_order_relaxed); - - VERIFY(ret == false); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == true); - } -} - -void AtomicBoolBasicTest::TestCompareExchangeWeak() -{ - { - AtomicType atomic{ false }; - - BoolType observed = false; - bool ret = atomic.compare_exchange_weak(observed, false, eastl::memory_order_relaxed); - - if (ret) - { - VERIFY(ret == true); - VERIFY(observed == false); - VERIFY(atomic.load(eastl::memory_order_relaxed) == false); - } - } - - { - AtomicType atomic{ false }; - - BoolType observed = false; - bool ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_relaxed); - - if (ret) - { - VERIFY(ret == true); - VERIFY(observed == false); - VERIFY(atomic.load(eastl::memory_order_relaxed) == true); - } - } - - { - AtomicType atomic{ false }; - - BoolType observed = true; - bool ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_relaxed); - - VERIFY(ret == false); - VERIFY(observed == false); - } -} - -void AtomicBoolBasicTest::TestCompareExchangeStrong() -{ - { - AtomicType atomic{ false }; - - BoolType observed = false; - bool ret = atomic.compare_exchange_weak(observed, false, eastl::memory_order_relaxed); - - VERIFY(ret == true); - VERIFY(observed == false); - VERIFY(atomic.load(eastl::memory_order_relaxed) == false); - } - - { - AtomicType atomic{ false }; - - BoolType observed = false; - bool ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_relaxed); - - VERIFY(ret == true); - VERIFY(observed == false); - VERIFY(atomic.load(eastl::memory_order_relaxed) == true); - } - - { - AtomicType atomic{ false }; - - BoolType observed = true; - bool ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_relaxed); - - VERIFY(ret == false); - VERIFY(observed == false); - } -} - -void AtomicBoolBasicTest::TestAllMemoryOrders() -{ - { - AtomicType atomic; - - atomic.store(true); - - atomic.store(true, eastl::memory_order_relaxed); - - atomic.store(true, eastl::memory_order_release); - - atomic.store(true, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - BoolType ret = atomic.load(); - - ret = atomic.load(eastl::memory_order_relaxed); - - ret = atomic.load(eastl::memory_order_acquire); - - ret = atomic.load(eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - BoolType ret = atomic.exchange(true); - - ret = atomic.exchange(true, eastl::memory_order_relaxed); - - ret = atomic.exchange(true, eastl::memory_order_acquire); - - ret = atomic.exchange(true, eastl::memory_order_release); - - ret = atomic.exchange(true, eastl::memory_order_acq_rel); - - ret = atomic.exchange(true, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - BoolType observed = false; - bool ret = atomic.compare_exchange_weak(observed, true); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_release); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - BoolType observed = false; - bool ret = atomic.compare_exchange_strong(observed, true); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_release); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - BoolType observed = false; - bool ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_acquire, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_release, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, true, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic; - - BoolType observed = false; - bool ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_acquire, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_acquire, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_release, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_acq_rel, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_acq_rel, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_seq_cst, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_seq_cst, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, true, eastl::memory_order_seq_cst, eastl::memory_order_seq_cst); - } -} - - -template <typename T> -class AtomicIntegralBasicTest -{ -public: - - using AtomicType = eastl::atomic<T>; - using IntegralType = T; - - int RunTest() - { - TestAtomicCtor(); - - TestAtomicFetchAdd(); - TestAtomicAddFetch(); - - TestAtomicFetchSub(); - TestAtomicSubFetch(); - - TestAtomicFetchAnd(); - TestAtomicAndFetch(); - - TestAtomicFetchOr(); - TestAtomicOrFetch(); - - TestAtomicFetchXor(); - TestAtomicXorFetch(); - - TestAssignmentOperators(); - - TestIsLockFree(); - - TestStore(); - - TestLoad(); - - TestExchange(); - - TestCompareExchangeWeak(); - - TestCompareExchangeStrong(); - - TestAllMemoryOrders(); - - TestAtomicStandalone(); - - return nErrorCount; - } - -private: - - void TestAtomicCtor(); - - void TestAtomicFetchAdd(); - void TestAtomicAddFetch(); - - void TestAtomicFetchSub(); - void TestAtomicSubFetch(); - - void TestAtomicFetchAnd(); - void TestAtomicAndFetch(); - - void TestAtomicFetchOr(); - void TestAtomicOrFetch(); - - void TestAtomicFetchXor(); - void TestAtomicXorFetch(); - - void TestAssignmentOperators(); - - void TestIsLockFree(); - - void TestStore(); - - void TestLoad(); - - void TestExchange(); - - void TestCompareExchangeWeak(); - - void TestCompareExchangeStrong(); - - void TestAllMemoryOrders(); - - void TestAtomicStandalone(); - -private: - - int nErrorCount = 0; -}; - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicCtor() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 1); - } - - { - AtomicType atomic{ 20 }; - - IntegralType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 20); - } - - { - AtomicType atomic; - - IntegralType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicFetchAdd() -{ - { - AtomicType atomic; - - IntegralType ret = atomic.fetch_add(1, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic.fetch_add(0, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 5 }; - - IntegralType ret = atomic.fetch_add(0, eastl::memory_order_relaxed); - - VERIFY(ret == 5); - - ret = atomic.fetch_add(4, eastl::memory_order_relaxed); - - VERIFY(ret == 5); - - ret = atomic.fetch_add(1, eastl::memory_order_relaxed); - - VERIFY(ret == 9); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 10); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicAddFetch() -{ - { - AtomicType atomic; - - IntegralType ret = atomic.add_fetch(1, eastl::memory_order_relaxed); - - VERIFY(ret == 1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic.add_fetch(0, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 5 }; - - IntegralType ret = atomic.add_fetch(0, eastl::memory_order_relaxed); - - VERIFY(ret == 5); - - ret = atomic.add_fetch(4, eastl::memory_order_relaxed); - - VERIFY(ret == 9); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 9); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicFetchSub() -{ - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic.fetch_sub(1, eastl::memory_order_relaxed); - - VERIFY(ret == 1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic.fetch_sub(0, eastl::memory_order_relaxed); - - VERIFY(ret == 1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 1); - } - - { - AtomicType atomic{ 5 }; - - IntegralType ret = atomic.fetch_sub(2, eastl::memory_order_relaxed); - - VERIFY(ret == 5); - - ret = atomic.fetch_sub(1, eastl::memory_order_relaxed); - - VERIFY(ret == 3); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 2); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicSubFetch() -{ - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic.sub_fetch(1, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic.sub_fetch(0, eastl::memory_order_relaxed); - - VERIFY(ret == 1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 1); - } - - { - AtomicType atomic{ 5 }; - - IntegralType ret = atomic.sub_fetch(2, eastl::memory_order_relaxed); - - VERIFY(ret == 3); - - ret = atomic.sub_fetch(1, eastl::memory_order_relaxed); - - VERIFY(ret == 2); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 2); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicFetchAnd() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.fetch_and(0x0, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.fetch_and(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 0xF }; - - IntegralType ret = atomic.fetch_and(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0xF); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0X1); - } - - { - AtomicType atomic{ 0xF }; - - IntegralType ret = atomic.fetch_and(0xF0, eastl::memory_order_relaxed); - - VERIFY(ret == 0xF); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicAndFetch() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.and_fetch(0x0, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.and_fetch(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 0xF }; - - IntegralType ret = atomic.and_fetch(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } - - { - AtomicType atomic{ 0xF }; - - IntegralType ret = atomic.and_fetch(0xF0, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicFetchOr() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.fetch_or(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic.fetch_or(0x0, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic.fetch_or(0x2, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x3); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicOrFetch() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.or_fetch(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic.or_fetch(0x0, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic.or_fetch(0x2, eastl::memory_order_relaxed); - - VERIFY(ret == 0x3); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x3); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicFetchXor() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.fetch_xor(0x0, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic.fetch_xor(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - } - - { - AtomicType atomic{ 0x0 }; - - IntegralType ret = atomic.fetch_xor(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicXorFetch() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.xor_fetch(0x0, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic.xor_fetch(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - } - - { - AtomicType atomic{ 0x0 }; - - IntegralType ret = atomic.xor_fetch(0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAssignmentOperators() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = (atomic = 5); - - VERIFY(ret == 5); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 5); - } - - { - AtomicType atomic{ 0 }; - - IntegralType ret = ++atomic; - - VERIFY(ret == 1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 1); - } - - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic++; - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 1); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = --atomic; - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic--; - - VERIFY(ret == 1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic += 5; - - VERIFY(ret == 5); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 5); - } - - { - AtomicType atomic{ 5 }; - - IntegralType ret = atomic -= 3; - - VERIFY(ret == 2); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 2); - } - - { - AtomicType atomic{ 0x0 }; - - IntegralType ret = atomic |= 0x1; - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic &= 0x1; - - VERIFY(ret == 0x1); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic ^= 0x1; - - VERIFY(ret == 0x0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestIsLockFree() -{ - { - const AtomicType atomic{ 5 }; - - VERIFY(atomic.is_lock_free() == true); - - VERIFY(AtomicType::is_always_lock_free == true); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestStore() -{ - { - AtomicType atomic{ 0 }; - - atomic.store(0, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0); - } - - { - AtomicType atomic{ 0 }; - - atomic.store(1, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestLoad() -{ - { - AtomicType atomic{ 0 }; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0); - - bool ret = atomic == 0; - VERIFY(ret == true); - - VERIFY(atomic == 0); - } - - { - AtomicType atomic{ 5 }; - - VERIFY(atomic.load(eastl::memory_order_relaxed) == 5); - - bool ret = atomic == 5; - VERIFY(ret == true); - - VERIFY(atomic == 5); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestExchange() -{ - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.exchange(0, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic{ 0 }; - - IntegralType ret = atomic.exchange(1, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - - ret = atomic.load(eastl::memory_order_relaxed); - - VERIFY(ret == 1); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestCompareExchangeWeak() -{ - { - AtomicType atomic{ 0 }; - - IntegralType observed = 0; - bool ret = atomic.compare_exchange_weak(observed, 1, eastl::memory_order_relaxed); - - if (ret == true) - { - VERIFY(ret == true); - VERIFY(observed == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - } - - { - AtomicType atomic{ 0 }; - - IntegralType observed = 1; - bool ret = atomic.compare_exchange_weak(observed, 1, eastl::memory_order_relaxed); - - VERIFY(ret == false); - VERIFY(observed == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestCompareExchangeStrong() -{ - { - AtomicType atomic{ 0 }; - - IntegralType observed = 0; - bool ret = atomic.compare_exchange_strong(observed, 1, eastl::memory_order_relaxed); - - VERIFY(ret == true); - VERIFY(observed == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic{ 0 }; - - IntegralType observed = 1; - bool ret = atomic.compare_exchange_strong(observed, 1, eastl::memory_order_relaxed); - - VERIFY(ret == false); - VERIFY(observed == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0); - } -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAllMemoryOrders() -{ - { - AtomicType atomic{}; - - atomic.store(1); - - atomic.store(1, eastl::memory_order_relaxed); - - atomic.store(1, eastl::memory_order_release); - - atomic.store(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.load(); - - ret = atomic.load(eastl::memory_order_relaxed); - - ret = atomic.load(eastl::memory_order_acquire); - - ret = atomic.load(eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.exchange(1); - - ret = atomic.exchange(1, eastl::memory_order_relaxed); - - ret = atomic.exchange(1, eastl::memory_order_acquire); - - ret = atomic.exchange(1, eastl::memory_order_release); - - ret = atomic.exchange(1, eastl::memory_order_acq_rel); - - ret = atomic.exchange(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.fetch_add(1); - - ret = atomic.fetch_add(1, eastl::memory_order_relaxed); - - ret = atomic.fetch_add(1, eastl::memory_order_acquire); - - ret = atomic.fetch_add(1, eastl::memory_order_release); - - ret = atomic.fetch_add(1, eastl::memory_order_acq_rel); - - ret = atomic.fetch_add(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.add_fetch(1); - - ret = atomic.add_fetch(1, eastl::memory_order_relaxed); - - ret = atomic.add_fetch(1, eastl::memory_order_acquire); - - ret = atomic.add_fetch(1, eastl::memory_order_release); - - ret = atomic.add_fetch(1, eastl::memory_order_acq_rel); - - ret = atomic.add_fetch(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.fetch_sub(1); - - ret = atomic.fetch_sub(1, eastl::memory_order_relaxed); - - ret = atomic.fetch_sub(1, eastl::memory_order_acquire); - - ret = atomic.fetch_sub(1, eastl::memory_order_release); - - ret = atomic.fetch_sub(1, eastl::memory_order_acq_rel); - - ret = atomic.fetch_sub(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.sub_fetch(1); - - ret = atomic.sub_fetch(1, eastl::memory_order_relaxed); - - ret = atomic.sub_fetch(1, eastl::memory_order_acquire); - - ret = atomic.sub_fetch(1, eastl::memory_order_release); - - ret = atomic.sub_fetch(1, eastl::memory_order_acq_rel); - - ret = atomic.sub_fetch(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.fetch_and(1); - - ret = atomic.fetch_and(1, eastl::memory_order_relaxed); - - ret = atomic.fetch_and(1, eastl::memory_order_acquire); - - ret = atomic.fetch_and(1, eastl::memory_order_release); - - ret = atomic.fetch_and(1, eastl::memory_order_acq_rel); - - ret = atomic.fetch_and(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.and_fetch(1); - - ret = atomic.and_fetch(1, eastl::memory_order_relaxed); - - ret = atomic.and_fetch(1, eastl::memory_order_acquire); - - ret = atomic.and_fetch(1, eastl::memory_order_release); - - ret = atomic.and_fetch(1, eastl::memory_order_acq_rel); - - ret = atomic.and_fetch(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.fetch_or(1); - - ret = atomic.fetch_or(1, eastl::memory_order_relaxed); - - ret = atomic.fetch_or(1, eastl::memory_order_acquire); - - ret = atomic.fetch_or(1, eastl::memory_order_release); - - ret = atomic.fetch_or(1, eastl::memory_order_acq_rel); - - ret = atomic.fetch_or(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.or_fetch(1); - - ret = atomic.or_fetch(1, eastl::memory_order_relaxed); - - ret = atomic.or_fetch(1, eastl::memory_order_acquire); - - ret = atomic.or_fetch(1, eastl::memory_order_release); - - ret = atomic.or_fetch(1, eastl::memory_order_acq_rel); - - ret = atomic.or_fetch(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.fetch_xor(1); - - ret = atomic.fetch_xor(1, eastl::memory_order_relaxed); - - ret = atomic.fetch_xor(1, eastl::memory_order_acquire); - - ret = atomic.fetch_xor(1, eastl::memory_order_release); - - ret = atomic.fetch_xor(1, eastl::memory_order_acq_rel); - - ret = atomic.fetch_xor(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType ret = atomic.xor_fetch(1); - - ret = atomic.xor_fetch(1, eastl::memory_order_relaxed); - - ret = atomic.xor_fetch(1, eastl::memory_order_acquire); - - ret = atomic.xor_fetch(1, eastl::memory_order_release); - - ret = atomic.xor_fetch(1, eastl::memory_order_acq_rel); - - ret = atomic.xor_fetch(1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType observed = 0; - bool ret; - - ret = atomic.compare_exchange_weak(observed, 1); - - ret = atomic.compare_exchange_weak(observed, 1, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, 1, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, 1, eastl::memory_order_release); - - ret = atomic.compare_exchange_weak(observed, 1, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_weak(observed, 1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType observed = 0; - bool ret; - - ret = atomic.compare_exchange_strong(observed, 1); - - ret = atomic.compare_exchange_strong(observed, 1, eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, 1, eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, 1, eastl::memory_order_release); - - ret = atomic.compare_exchange_strong(observed, 1, eastl::memory_order_acq_rel); - - ret = atomic.compare_exchange_strong(observed, 1, eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType observed = 0; - bool ret; - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_relaxed, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_acquire, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_acquire, - eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_release, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_acq_rel, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_acq_rel, - eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_seq_cst, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_seq_cst, - eastl::memory_order_acquire); - - ret = atomic.compare_exchange_weak(observed, 1, - eastl::memory_order_seq_cst, - eastl::memory_order_seq_cst); - } - - { - AtomicType atomic{}; - - IntegralType observed = 0; - bool ret; - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_relaxed, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_acquire, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_acquire, - eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_release, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_acq_rel, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_acq_rel, - eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_seq_cst, - eastl::memory_order_relaxed); - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_seq_cst, - eastl::memory_order_acquire); - - ret = atomic.compare_exchange_strong(observed, 1, - eastl::memory_order_seq_cst, - eastl::memory_order_seq_cst); - } - -} - -template <typename T> -void AtomicIntegralBasicTest<T>::TestAtomicStandalone() -{ - { - AtomicType atomic; - - IntegralType expected = 0; - bool ret = atomic_compare_exchange_weak(&atomic, &expected, 1); - - if (ret) - { - VERIFY(ret == true); - - VERIFY(expected == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - } - - { - AtomicType atomic; - - IntegralType expected = 0; - bool ret = atomic_compare_exchange_weak_explicit(&atomic, &expected, 1, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - if (ret) - { - VERIFY(ret == true); - - VERIFY(expected == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - } - - { - AtomicType atomic; - - IntegralType expected = 0; - bool ret = atomic_compare_exchange_strong(&atomic, &expected, 1); - - VERIFY(ret == true); - - VERIFY(expected == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - IntegralType expected = 0; - bool ret = atomic_compare_exchange_strong_explicit(&atomic, &expected, 1, eastl::memory_order_relaxed, eastl::memory_order_relaxed); - - VERIFY(ret == true); - - VERIFY(expected == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_fetch_xor(&atomic, 0x1); - - VERIFY(ret == 0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_fetch_xor_explicit(&atomic, 0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_xor_fetch(&atomic, 0x1); - - VERIFY(ret == 0x1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_xor_fetch_explicit(&atomic, 0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_fetch_or(&atomic, 0x1); - - VERIFY(ret == 0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_fetch_or_explicit(&atomic, 0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_or_fetch(&atomic, 0x1); - - VERIFY(ret == 0x1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_or_fetch_explicit(&atomic, 0x1, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x1); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic_fetch_and(&atomic, 0x0); - - VERIFY(ret == 0x1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x0); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic_fetch_and_explicit(&atomic, 0x0, eastl::memory_order_relaxed); - - VERIFY(ret == 0x1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x0); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic_and_fetch(&atomic, 0x0); - - VERIFY(ret == 0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x0); - } - - { - AtomicType atomic{ 0x1 }; - - IntegralType ret = atomic_and_fetch_explicit(&atomic, 0x0, eastl::memory_order_relaxed); - - VERIFY(ret == 0x0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0x0); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic_fetch_sub(&atomic, 1); - - VERIFY(ret == 1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic_fetch_sub_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == 1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic_sub_fetch(&atomic, 1); - - VERIFY(ret == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0); - } - - { - AtomicType atomic{ 1 }; - - IntegralType ret = atomic_sub_fetch_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 0); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_fetch_add(&atomic, 1); - - VERIFY(ret == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_fetch_add_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_add_fetch(&atomic, 1); - - VERIFY(ret == 1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_add_fetch_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == 1); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_exchange(&atomic, 1); - - VERIFY(ret == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_exchange_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_load(&atomic); - - VERIFY(ret == 0); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_load_explicit(&atomic, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_load_cond(&atomic, [](IntegralType val) { return true; }); - - VERIFY(ret == 0); - } - - { - AtomicType atomic; - - IntegralType ret = atomic_load_cond_explicit(&atomic, [](IntegralType val) { return true; }, eastl::memory_order_relaxed); - - VERIFY(ret == 0); - } - - { - AtomicType atomic; - - atomic_store(&atomic, 1); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - atomic_store_explicit(&atomic, 1, eastl::memory_order_relaxed); - - VERIFY(atomic.load(eastl::memory_order_relaxed) == 1); - } - - { - AtomicType atomic; - - VERIFY(atomic_is_lock_free(&atomic) == true); - } -} - -struct AtomicNonDefaultConstructible -{ - AtomicNonDefaultConstructible(uint8_t a) - : a(a) - { - } - - friend bool operator==(const AtomicNonDefaultConstructible& a, const AtomicNonDefaultConstructible& b) - { - return a.a == b.a; - } - - uint8_t a; -}; - -#if defined(EASTL_ATOMIC_HAS_8BIT) - -int TestAtomicNonDefaultConstructible() -{ - int nErrorCount = 0; - - { - eastl::atomic<AtomicNonDefaultConstructible> atomic{AtomicNonDefaultConstructible{(uint8_t)3}}; - - VERIFY(atomic.load() == AtomicNonDefaultConstructible{(uint8_t)3}); - } - - { - eastl::atomic<AtomicNonDefaultConstructible> atomic{AtomicNonDefaultConstructible{(uint8_t)3}}; - - atomic.store(AtomicNonDefaultConstructible{(uint8_t)4}); - - VERIFY(atomic.load() == AtomicNonDefaultConstructible{(uint8_t)4}); - } - - { - eastl::atomic<AtomicNonDefaultConstructible> atomic{AtomicNonDefaultConstructible{(uint8_t)3}}; - - VERIFY(atomic_load_cond(&atomic, [] (AtomicNonDefaultConstructible) { return true; }) == AtomicNonDefaultConstructible{(uint8_t)3}); - } - - { - eastl::atomic<AtomicNonDefaultConstructible> atomic{AtomicNonDefaultConstructible{(uint8_t)3}}; - - VERIFY(atomic_load_cond_explicit(&atomic, [] (AtomicNonDefaultConstructible) { return true; }, eastl::memory_order_seq_cst) == AtomicNonDefaultConstructible{(uint8_t)3}); - } - - return nErrorCount; -} - -#endif - -struct Atomic128LoadType -{ - friend bool operator==(const Atomic128LoadType& a, const Atomic128LoadType& b) - { - return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d; - } - - uint32_t a, b, c, d; -}; - -#if defined(EASTL_ATOMIC_HAS_128BIT) - -int TestAtomic128Loads() -{ - int nErrorCount = 0; - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{1, 1, 0, 0}}; - - VERIFY((atomic.load() == Atomic128LoadType{1, 1, 0, 0})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{0, 0, 1, 1}}; - - VERIFY((atomic.load() == Atomic128LoadType{0, 0, 1, 1})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{0, 1, 0, 1}}; - - VERIFY((atomic.load() == Atomic128LoadType{0, 1, 0, 1})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{1, 0, 1, 0}}; - - VERIFY((atomic.load() == Atomic128LoadType{1, 0, 1, 0})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{1, 1, 0, 0}}; - - Atomic128LoadType expected{0, 0, 0, 0}; - atomic.compare_exchange_strong(expected, Atomic128LoadType{1, 1, 0, 0}); - - VERIFY((expected == Atomic128LoadType{1, 1, 0, 0})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{0, 0, 1, 1}}; - - Atomic128LoadType expected{0, 0, 0, 0}; - atomic.compare_exchange_strong(expected, Atomic128LoadType{0, 0, 1, 1}); - - VERIFY((expected == Atomic128LoadType{0, 0, 1, 1})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{0, 1, 0, 1}}; - - Atomic128LoadType expected{0, 0, 0, 0}; - atomic.compare_exchange_strong(expected, Atomic128LoadType{0, 1, 0, 1}); - - VERIFY((expected == Atomic128LoadType{0, 1, 0, 1})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{1, 0, 1, 0}}; - - Atomic128LoadType expected{0, 0, 0, 0}; - atomic.compare_exchange_strong(expected, Atomic128LoadType{1, 0, 1, 0}); - - VERIFY((expected == Atomic128LoadType{1, 0, 1, 0})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{0, 0, 0, 0}}; - - Atomic128LoadType expected{0, 0, 0, 0}; - atomic.compare_exchange_strong(expected, Atomic128LoadType{1, 1, 0, 0}); - - VERIFY((atomic.load() == Atomic128LoadType{1, 1, 0, 0})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{0, 0, 0, 0}}; - - Atomic128LoadType expected{0, 0, 0, 0}; - atomic.compare_exchange_strong(expected, Atomic128LoadType{0, 0, 1, 1}); - - VERIFY((atomic.load() == Atomic128LoadType{0, 0, 1, 1})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{0, 0, 0, 0}}; - - Atomic128LoadType expected{0, 0, 0, 0}; - atomic.compare_exchange_strong(expected, Atomic128LoadType{0, 1, 0, 1}); - - VERIFY((atomic.load() == Atomic128LoadType{0, 1, 0, 1})); - } - - { - eastl::atomic<Atomic128LoadType> atomic{Atomic128LoadType{0, 0, 0, 0}}; - - Atomic128LoadType expected{0, 0, 0, 0}; - atomic.compare_exchange_strong(expected, Atomic128LoadType{1, 0, 1, 0}); - - VERIFY((atomic.load() == Atomic128LoadType{1, 0, 1, 0})); - } - - return nErrorCount; -} - -#endif - -int TestAtomicBasic() -{ - int nErrorCount = 0; - - #if defined(EASTL_ATOMIC_HAS_8BIT) - { - AtomicIntegralBasicTest<uint8_t> u8AtomicTest; - - nErrorCount += u8AtomicTest.RunTest(); - } - #endif - - #if defined(EASTL_ATOMIC_HAS_16BIT) - { - AtomicIntegralBasicTest<uint16_t> u16AtomicTest; - - nErrorCount += u16AtomicTest.RunTest(); - } - #endif - - #if defined(EASTL_ATOMIC_HAS_32BIT) - { - AtomicIntegralBasicTest<uint32_t> u32AtomicTest; - - nErrorCount += u32AtomicTest.RunTest(); - } - #endif - - #if defined(EASTL_ATOMIC_HAS_64BIT) - { - AtomicIntegralBasicTest<uint64_t> u64AtomicTest; - - nErrorCount += u64AtomicTest.RunTest(); - } - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) && (defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_GNUC)) - { - AtomicIntegralBasicTest<__uint128_t> u128AtomicTest; - - nErrorCount += u128AtomicTest.RunTest(); - } - - { - AtomicIntegralBasicTest<eastl_uint128_t> u128AtomicTest; - - nErrorCount += u128AtomicTest.RunTest(); - } - #endif - - { - AtomicBoolBasicTest boolAtomicTest; - - nErrorCount += boolAtomicTest.RunTest(); - } - - #if defined(EASTL_ATOMIC_HAS_16BIT) - { - AtomicUserTypeBasicTest<AtomicUserType16> userTypeAtomicTest; - - nErrorCount += userTypeAtomicTest.RunTest(); - } - #endif - - #if defined(EASTL_ATOMIC_HAS_32BIT) - { - AtomicUserTypeBasicTest<AtomicNonTriviallyConstructible> userTypeAtomicTest; - - nErrorCount += userTypeAtomicTest.RunTest(); - } - - { - AtomicUserTypeBasicTest<AtomicNonTriviallyConstructibleNoExcept> userTypeAtomicTest; - - nErrorCount += userTypeAtomicTest.RunTest(); - } - #endif - - #if defined(EASTL_ATOMIC_HAS_128BIT) - { - AtomicUserTypeBasicTest<AtomicUserType128> userTypeAtomicTest; - - nErrorCount += userTypeAtomicTest.RunTest(); - } - #endif - - { - AtomicPointerBasicTest ptrAtomicTest; - - nErrorCount += ptrAtomicTest.RunTest(); - } - - { - AtomicVoidPointerBasicTest voidPtrAtomicTest; - - nErrorCount += voidPtrAtomicTest.RunTest(); - } - - { - AtomicFlagBasicTest atomicFlagBasicTest; - - nErrorCount += atomicFlagBasicTest.RunTest(); - } - - { - AtomicStandaloneBasicTest atomicStandaloneBasicTest; - - nErrorCount += atomicStandaloneBasicTest.RunTest(); - } - -#if defined(EASTL_ATOMIC_HAS_128BIT) - - nErrorCount += TestAtomic128Loads(); - -#endif - -#if defined(EASTL_ATOMIC_HAS_8BIT) - - nErrorCount += TestAtomicNonDefaultConstructible(); - -#endif - - nErrorCount += TestAtomicConstantInitialization(); - - return nErrorCount; -} diff --git a/test/source/TestBitVector.cpp b/test/source/TestBitVector.cpp deleted file mode 100644 index ba3ae8c..0000000 --- a/test/source/TestBitVector.cpp +++ /dev/null @@ -1,469 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EABase/eabase.h> -#include <EASTL/bitvector.h> -#include <EASTL/vector.h> -#include <EASTL/deque.h> -#include <EASTL/string.h> - - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::bitvector<>; -template class eastl::bitvector<MallocAllocator>; -template class eastl::bitvector<EASTLAllocatorType, uint8_t>; -template class eastl::bitvector<EASTLAllocatorType, int16_t>; -template class eastl::bitvector<EASTLAllocatorType, int32_t>; -template class eastl::bitvector<EASTLAllocatorType, int64_t, eastl::vector<int64_t, EASTLAllocatorType> >; - -// bitvector doesn't yet support deque. -//template class eastl::bitvector<EASTLAllocatorType, uint8_t, eastl::deque<uint64_t, EASTLAllocatorType> >; -//template class eastl::bitvector<EASTLAllocatorType, uint8_t, eastl::deque<int32_t, EASTLAllocatorType, 64> >; - - - -int TestBitVector() -{ - using namespace eastl; - - int nErrorCount = 0; - - { - // typedef bitvector<Allocator, Element> this_type; - // typedef bool value_type; - // typedef bitvector_reference<Element> reference; - // typedef bool const_reference; - // typedef bitvector_iterator<Element> iterator; - // typedef bitvector_const_iterator<Element> const_iterator; - // typedef eastl::reverse_iterator<iterator> reverse_iterator; - // typedef eastl::reverse_iterator<const_iterator> const_reverse_iterator; - // typedef Allocator allocator_type; - // typedef Element element_type; - // typedef Container container_type; - // typedef eastl_size_t size_type; - - bitvector<>::this_type this_typeVariable; - bitvector<>::value_type value_typeVariable = 0; - bitvector<>::const_reference const_referenceVariable(false); - bitvector<>::iterator iteratorVariable(NULL, 0); - bitvector<>::const_iterator const_iteratorVariable(NULL, 0); - bitvector<>::reverse_iterator reverse_iteratorVariable(iteratorVariable); - bitvector<>::const_reverse_iterator const_reverse_iteratorVariable(const_iteratorVariable); - bitvector<>::allocator_type allocator_typeVariable; - bitvector<>::element_type element_typeVariable = 0; - bitvector<>::container_type container_typeVariable; - bitvector<>::size_type size_typeVariable = 0; - - string sAddresses(string::CtorSprintf(), "%p %p %p %p %p %p %p %p %p %p %p", - &this_typeVariable, &value_typeVariable, &const_referenceVariable, &iteratorVariable, - &const_iteratorVariable, &reverse_iteratorVariable,&const_reverse_iteratorVariable, - &allocator_typeVariable, &element_typeVariable, &container_typeVariable, &size_typeVariable); - EATEST_VERIFY(sAddresses.size() > 0); - } - - { - // bitvector(); - // explicit bitvector(const allocator_type& allocator); - // explicit bitvector(size_type n, const allocator_type& allocator = EASTL_BITVECTOR_DEFAULT_ALLOCATOR); - // bitvector(size_type n, value_type value, const allocator_type& allocator = EASTL_BITVECTOR_DEFAULT_ALLOCATOR); - // bitvector(const bitvector& copy); - // template <typename InputIterator> bitvector(InputIterator first, InputIterator last); - // bitvector& operator=(const bitvector& x); - // reference operator[](size_type n); // behavior is undefined if n is invalid. - // const_reference operator[](size_type n) const; - MallocAllocator mallocAllocator; - bitvector<> bv0; - bitvector<MallocAllocator> bv1(mallocAllocator); - bitvector<> bv2(200); - bitvector<> bv3(300, true); - bitvector<MallocAllocator> bv4(400, false, mallocAllocator); - const bitvector<> bv5(bv2); - bool boolArray[] = { true, false, true }; - bitvector<> bv6(boolArray, boolArray + EAArrayCount(boolArray)); - bitvector<> bv7(bv3.begin(), bv3.end()); - - { - // Validate the above constructions - EATEST_VERIFY(bv0.validate()); - EATEST_VERIFY(bv0.empty()); - - EATEST_VERIFY(bv1.validate()); - EATEST_VERIFY(bv1.empty()); - - EATEST_VERIFY(bv2.validate()); - EATEST_VERIFY(bv2.size() == 200); - for(eastl_size_t i = 0; i < bv2.size(); i++) - EATEST_VERIFY(bv2[i] == false); - - EATEST_VERIFY(bv3.validate()); - EATEST_VERIFY(bv3.size() == 300); - for(eastl_size_t i = 0; i < bv3.size(); i++) - EATEST_VERIFY(bv3[i] == true); - - EATEST_VERIFY(bv4.validate()); - EATEST_VERIFY(bv4.size() == 400); - for(eastl_size_t i = 0; i < bv4.size(); i++) - EATEST_VERIFY(bv4[i] == false); - - EATEST_VERIFY(bv5.validate()); - EATEST_VERIFY(bv5 == bv2); - for(eastl_size_t i = 0; i < bv5.size(); i++) - EATEST_VERIFY(bv5[i] == false); - - EATEST_VERIFY(bv6.validate()); - EATEST_VERIFY(bv6.size() == EAArrayCount(boolArray)); - for(eastl_size_t i = 0; i < bv6.size(); i++) - EATEST_VERIFY(bv6[i] == boolArray[i]); - - EATEST_VERIFY(bv7.validate()); - EATEST_VERIFY(bv7.size() == bv3.size()); // The == test theoretically includes this test, be we check anyway. - for(eastl_size_t j = 0; j < bv7.size(); j++) - EATEST_VERIFY(bv7[j] == bv3[j]); - EATEST_VERIFY(bv7 == bv3); - for(eastl_size_t i = 0; (i < bv3.size()) && (i < bv7.size()); i++) - EATEST_VERIFY(bv3[i] == bv7[i]); - } - - { - // void swap(this_type& x); - - bv7.swap(bv7); // Test swapping against self. - EATEST_VERIFY(bv7.validate()); - EATEST_VERIFY(bv7 == bv3); - EATEST_VERIFY(bv7.size() == bv3.size()); // The == test theoretically includes this test, be we check anyway. - for(eastl_size_t i = 0; (i < bv3.size()) && (i < bv7.size()); i++) - EATEST_VERIFY(bv3[i] == bv7[i]); - - bv3.swap(bv2); // Note that bv3 and bv4 use different allocators, so we are exercizing that. - EATEST_VERIFY(bv3.validate()); - EATEST_VERIFY(bv3.size() == 200); - for(eastl_size_t i = 0; i < bv3.size(); i++) - EATEST_VERIFY(bv3[i] == false); - - EATEST_VERIFY(bv2.validate()); - EATEST_VERIFY(bv2.size() == 300); - for(eastl_size_t i = 0; i < bv2.size(); i++) - EATEST_VERIFY(bv2[i] == true); - - - // bitvector& operator=(const bitvector& x); - - bv6 = bv7; - EATEST_VERIFY(bv6.validate()); - EATEST_VERIFY(bv6 == bv7); - - - // template <typename InputIterator> void assign(InputIterator first, InputIterator last); - bv0.assign(bv3.begin(), bv3.end()); - EATEST_VERIFY(bv0 == bv3); - - bv0.assign(boolArray, boolArray + EAArrayCount(boolArray)); - EATEST_VERIFY(bv0 == bitvector<>(boolArray, boolArray + EAArrayCount(boolArray))); - - bv0.resize(0); - EATEST_VERIFY(bv0.begin()==bv0.end());//should not crash - bv3.resize(0); - EATEST_VERIFY(bv0 == bv3); - } - } - - - { - // iterator begin(); - // const_iterator begin() const; - // iterator end(); - // const_iterator end() const; - - bool boolArray[] = { true, false, true, true, false, true }; - const bitvector<> bv0(boolArray, boolArray + EAArrayCount(boolArray)); - bitvector<>::const_iterator it; - eastl_size_t i; - - for(it = bv0.begin(), i = 0; it != bv0.end(); ++it, ++i) // Iterate forward by 1. - { - const bool value = *it; - EATEST_VERIFY(value == boolArray[i]); - } - - for(--it, --i; (eastl_ssize_t)i >= 0; --it, --i) // Iterate backward by 1. Problem: this test code does --it for it == begin(), which isn't strictly allowed. - { - const bool value = *it; - EATEST_VERIFY(value == boolArray[i]); - } - - // The following code asssumes an even number of elements. - EASTL_CT_ASSERT((EAArrayCount(boolArray) % 2) == 0); - for(it = bv0.begin(), ++i; it != bv0.end(); it += 2, i += 2) // Iterate forward by 2. - { - const bool value = *it; - EATEST_VERIFY(value == boolArray[i]); - } - - for(it -= 2, i -= 2; (eastl_ssize_t)i >= 0; it -= 2, i -= 2) // Iterate backward by 1. Problem: this test code does it -= 2 for it == begin(), which isn't strictly allowed. - { - const bool value = *it; - EATEST_VERIFY(value == boolArray[i]); - } - - - // reverse_iterator rbegin(); - // const_reverse_iterator rbegin() const; - // reverse_iterator rend(); - // const_reverse_iterator rend() const; - - bitvector<>::const_reverse_iterator rit; - i = (bv0.size() - 1); - - for(rit = bv0.rbegin(); rit != bv0.rend(); ++rit, --i) // Reverse-iterate forward by 1. - { - //const bool value = *rit; // This is currently broken and will require a bit of work to fix. - const bool value = *--rit.base(); - EATEST_VERIFY(value == boolArray[i]); - } - - for(--rit, ++i; i < bv0.size(); --rit, ++i) // Reverse-iterate backward by 1. - { - //const bool value = *rit; // This is currently broken and will require a bit of work to fix. - const bool value = *--rit.base(); - EATEST_VERIFY(value == boolArray[i]); - } - - // The following code asssumes an even number of elements. - EASTL_CT_ASSERT((EAArrayCount(boolArray) % 2) == 0); - for(rit = bv0.rbegin(), --i; rit != bv0.rend(); rit += 2, i -= 2) // Reverse-iterate forward by 2. - { - //const bool value = *rit; // This is currently broken and will require a bit of work to fix. - const bool value = *--rit.base(); - EATEST_VERIFY(value == boolArray[i]); - } - - for(rit -= 2, i += 2; i < bv0.size(); rit -= 2, i += 2) // Reverse-iterate backward by 2. - { - //const bool value = *rit; // This is currently broken and will require a bit of work to fix. - const bool value = *--rit.base(); - EATEST_VERIFY(value == boolArray[i]); - } - - - // find_first, etc. - /* This work is not complete. - { - bitvector<> bv(30, false); - - bitvector<>::iterator it = bv.find_first(); - EATEST_VERIFY(it == bv.begin()); - } - */ - } - - { - MallocAllocator mallocAllocator; - bitvector<MallocAllocator> bv0(mallocAllocator); - - // bool empty() const; - // size_type size() const; - // size_type capacity() const; - - EATEST_VERIFY(bv0.empty()); - EATEST_VERIFY(bv0.size() == 0); - EATEST_VERIFY(bv0.capacity() == 0); // EASTL requires that newly constructed containers have 0 capacity. - - bool boolArray[] = { false, true, true }; - bv0.assign(boolArray, boolArray + EAArrayCount(boolArray)); - - EATEST_VERIFY(!bv0.empty()); - EATEST_VERIFY(bv0.size() == EAArrayCount(boolArray)); - EATEST_VERIFY((bv0.capacity() > 0) && (bv0.capacity() <= (8 * sizeof(bitvector<>::element_type)))); - - - // reference front(); - // const_reference front() const; - // reference back(); - // const_reference back() const; - - EATEST_VERIFY(bv0.front() == false); - EATEST_VERIFY(bv0.back() == true); - bv0.erase(bv0.begin()); - EATEST_VERIFY(bv0.front() == true); - bv0.erase(bv0.rbegin()); - EATEST_VERIFY(bv0.back() == true); - - // void set_capacity(size_type n = npos); - - bv0.reserve(17); - EATEST_VERIFY((bv0.capacity() >= 17) && (bv0.capacity() <= 100)); // It's hard to make a unit test to portably test an upper limit. - - int allocCountBefore = MallocAllocator::mAllocCountAll; - while(bv0.size() < 17) - bv0.push_back(false); - EATEST_VERIFY(allocCountBefore == MallocAllocator::mAllocCountAll); // Verify no new memory was allocated. - - bv0.set_capacity(); - EATEST_VERIFY(bv0.capacity() >= bv0.size()); - - bv0.set_capacity(0); - EATEST_VERIFY(bv0.capacity() == 0); - EATEST_VERIFY(bv0.empty()); - - - // void resize(size_type n, value_type value); - // void resize(size_type n); - // void reserve(size_type n); - - bv0.reserve(800); - EATEST_VERIFY(bv0.capacity() >= 800); - allocCountBefore = MallocAllocator::mAllocCountAll; - bv0.resize(800, true); - EATEST_VERIFY(allocCountBefore == MallocAllocator::mAllocCountAll); // Verify no new memory was allocated. - - - // void push_back(); - // void push_back(value_type value); - // void pop_back(); - // reference operator[](size_type n); - // const_reference operator[](size_type n) const; - - bv0.push_back(); - bv0.back() = true; - bv0.push_back(false); - bv0.push_back(true); - - EATEST_VERIFY(bv0[bv0.size()-1] == true); - EATEST_VERIFY(bv0[bv0.size()-2] == false); - EATEST_VERIFY(bv0[bv0.size()-3] == true); - - - // reference at(size_type n); - // const_reference at(size_type n) const; - - EATEST_VERIFY(bv0.at(bv0.size()-1) == true); - EATEST_VERIFY(bv0.at(bv0.size()-2) == false); - EATEST_VERIFY(bv0.at(bv0.size()-3) == true); - - - // void clear(); - // bool test(size_type n, bool defaultValue) const; - // void set(bool value, size_type n); - - bv0.clear(); - bv0.resize(17, true); - EATEST_VERIFY(bv0.test(0, false) == true); - EATEST_VERIFY(bv0.test(17, false) == false); // Test past the end. - EATEST_VERIFY(bv0.test(17, true) == true); - - bv0.set(3, false); - EATEST_VERIFY(bv0.test(3, true) == false); - - bv0.set(100, true); - EATEST_VERIFY(bv0.test(100, false) == true); - - - // container_type& get_container(); - // const container_type& get_container() const; - - EATEST_VERIFY(!bv0.get_container().empty()); - - - // bool validate() const; - // int validate_iterator(const_iterator i) const; - - EATEST_VERIFY(bv0.validate()); - bitvector<>::iterator it; - EATEST_VERIFY(bv0.validate_iterator(it) == isf_none); - for(it = bv0.begin(); it != bv0.end(); ++it) - EATEST_VERIFY(bv0.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - EATEST_VERIFY(bv0.validate_iterator(it) == (isf_valid | isf_current)); - - - - // iterator insert(iterator position, value_type value); - // void insert(iterator position, size_type n, value_type value); - - bv0.clear(); - bv0.resize(17, true); - bv0.insert(bv0.begin() + 5, false); - EATEST_VERIFY(bv0[5] == false); - bv0[5] = true; - EATEST_VERIFY(bv0[5] == true); - - bv0.insert(bv0.begin() + 5, 7, false); - EATEST_VERIFY((bv0[5] == false) && (bv0[11] == false)); - - EATEST_VERIFY(bv0.back() == true); - bv0.insert(bv0.end(), false); - EATEST_VERIFY(bv0.back() == false); - - - // iterator erase(iterator position); - // iterator erase(iterator first, iterator last); - - EATEST_VERIFY((bv0[10] == false) && (bv0[11] == false)); - bv0.erase(bv0.begin() + 11); - EATEST_VERIFY((bv0[10] == false) && (bv0[11] == true)); - - EATEST_VERIFY(bv0[5] == false); - bool bv06 = bv0[6]; - bv0.erase(bv0.begin() + 5, bv0.begin() + 6); - EATEST_VERIFY(bv0[5] == bv06); - - - // reverse_iterator erase(reverse_iterator position); - // reverse_iterator erase(reverse_iterator first, reverse_iterator last); - - bv0.clear(); - bv0.resize(10, true); - bv0.back() = false; - bv0.erase(bv0.rbegin()); - EATEST_VERIFY((bv0.size() == 9) && (bv0.back() == true)); - - bv0.erase(bv0.rbegin(), bv0.rend()); - EATEST_VERIFY(bv0.empty()); - - - // template <typename InputIterator> Not yet implemented. See below for disabled definition. - // void insert(iterator position, InputIterator first, InputIterator last); - // - // Disabled because insert isn't implemented yet. - // const bool boolArray2[4] = { false, true, false, true }; - // bv0.insert(bv0.end(), boolArray2, boolArray2 + EAArrayCount(boolArray)); - // EATEST_VERIFY(bv0.size() == EAArrayCount(boolArray2)); - - - // element_type* data(); - // const element_type* data() const; - - EATEST_VERIFY(bv0.data() != NULL); - bv0.set_capacity(0); - EATEST_VERIFY(bv0.data() == NULL); - - - // void reset_lose_memory(); // This is a unilateral reset to an initially empty state. No destructors are called, no deallocation occurs. - - bv0.resize(100, true); - void* pSaved = MallocAllocator::mpLastAllocation; - bv0.reset_lose_memory(); - EATEST_VERIFY(bv0.validate()); - free(pSaved); // Call the C free function. - MallocAllocator::mpLastAllocation = NULL; - } - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestBitcast.cpp b/test/source/TestBitcast.cpp deleted file mode 100644 index d6f0840..0000000 --- a/test/source/TestBitcast.cpp +++ /dev/null @@ -1,52 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/bit.h> - -using namespace eastl; - - -int TestBitcast() -{ - int nErrorCount = 0; - - { - uint32_t int32Value = 0x12345678; - float floatValue = eastl::bit_cast<float>(int32Value); - VERIFY(memcmp(&int32Value, &floatValue, sizeof(float)) == 0); - } - - { - struct IntFloatStruct - { - uint32_t i = 0x87654321; - float f = 10.f; - }; - struct CharIntStruct - { - char c1; - char c2; - char c3; - char c4; - uint32_t i; - }; - - IntFloatStruct ifStruct; - CharIntStruct ciStruct = eastl::bit_cast<CharIntStruct>(ifStruct); - VERIFY(memcmp(&ifStruct, &ciStruct, sizeof(IntFloatStruct)) == 0); - } - -#if EASTL_CONSTEXPR_BIT_CAST_SUPPORTED - { - constexpr uint32_t int32Value = 40; - constexpr float floatValue = eastl::bit_cast<float>(int32Value); - VERIFY(memcmp(&int32Value, &floatValue, sizeof(float)) == 0); - } -#endif - - - return nErrorCount; -} diff --git a/test/source/TestBitset.cpp b/test/source/TestBitset.cpp deleted file mode 100644 index ef97489..0000000 --- a/test/source/TestBitset.cpp +++ /dev/null @@ -1,1327 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/bitset.h> -#include <EABase/eabase.h> - -#ifdef _MSC_VER - #pragma warning(push, 0) -#endif - -#include <stdio.h> -#include <stdlib.h> - -#if defined(_MSC_VER) - #pragma warning(pop) - #pragma warning(disable: 4310) // Cast truncates constant value -#endif - - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. - -#if (EASTL_BITSET_WORD_SIZE_DEFAULT != 1) - template class eastl::bitset<1, uint8_t>; - template class eastl::bitset<33, uint8_t>; - template class eastl::bitset<65, uint8_t>; - template class eastl::bitset<129, uint8_t>; -#endif - -#if (EASTL_BITSET_WORD_SIZE_DEFAULT != 2) - template class eastl::bitset<1, uint16_t>; - template class eastl::bitset<33, uint16_t>; - template class eastl::bitset<65, uint16_t>; - template class eastl::bitset<129, uint16_t>; -#endif - -#if (EASTL_BITSET_WORD_SIZE_DEFAULT != 4) // If not already represented - template class eastl::bitset<1, uint32_t>; - template class eastl::bitset<33, uint32_t>; - template class eastl::bitset<65, uint32_t>; - template class eastl::bitset<129, uint32_t>; -#endif - -#if (EASTL_BITSET_WORD_SIZE_DEFAULT != 8) - template class eastl::bitset<1, uint64_t>; - template class eastl::bitset<33, uint64_t>; - template class eastl::bitset<65, uint64_t>; - template class eastl::bitset<129, uint64_t>; -#endif - -#if (EASTL_BITSET_WORD_SIZE_DEFAULT != 16) - #if EASTL_INT128_SUPPORTED - template class eastl::bitset<1, eastl_uint128_t>; - template class eastl::bitset<33, eastl_uint128_t>; - template class eastl::bitset<65, eastl_uint128_t>; - template class eastl::bitset<129, eastl_uint128_t>; - #endif -#endif - - -int TestBitset() -{ - int nErrorCount = 0; - - { - // bitset<0> tests - #if !defined(__GNUC__) || (__GNUC__ >= 3) // GCC before v3.0 can't handle our bitset<0>. - bitset<0> b0(0x10101010); - EATEST_VERIFY(b0.count() == 0); - EATEST_VERIFY(b0.to_ulong() == 0x00000000); - EATEST_VERIFY(b0.to_uint32() == 0x00000000); - EATEST_VERIFY(b0.to_uint64() == 0x00000000); - - b0.flip(); - EATEST_VERIFY(b0.count() == 0); - EATEST_VERIFY(b0.to_ulong() == 0x00000000); - EATEST_VERIFY(b0.to_uint32() == 0x00000000); - EATEST_VERIFY(b0.to_uint64() == 0x00000000); - - b0 <<= 1; - EATEST_VERIFY(b0.count() == 0); - EATEST_VERIFY(b0.to_ulong() == 0x00000000); - EATEST_VERIFY(b0.to_uint32() == 0x00000000); - EATEST_VERIFY(b0.to_uint64() == 0x00000000); - - // Disabled because currently bitset<0> instances can't be modified without triggering asserts. - //b0.from_uint32(0x10101010); - //EATEST_VERIFY(b0.to_uint32() == 0x00000000); - //b0.from_uint64(UINT64_C(0x1010101010101010)); - //EATEST_VERIFY(b0.to_uint64() == UINT64_C(0x0000000000000000)); - #endif - - // bitset<8> tests - bitset<8> b8(0x10101010); - EATEST_VERIFY(b8.count() == 1); - EATEST_VERIFY(b8.to_ulong() == 0x00000010); - EATEST_VERIFY(b8.to_uint32() == 0x00000010); - EATEST_VERIFY(b8.to_uint64() == 0x00000010); - - b8.flip(); - EATEST_VERIFY(b8.count() == 7); - EATEST_VERIFY(b8.to_ulong() == 0x000000ef); - EATEST_VERIFY(b8.to_uint32() == 0x000000ef); - EATEST_VERIFY(b8.to_uint64() == 0x000000ef); - - b8 <<= 1; - EATEST_VERIFY(b8.count() == 6); - EATEST_VERIFY(b8.to_ulong() == 0x000000de); - EATEST_VERIFY(b8.to_uint32() == 0x000000de); - EATEST_VERIFY(b8.to_uint64() == 0x000000de); - - b8.reset(); - b8.flip(); - b8 >>= 33; - EATEST_VERIFY(b8.count() == 0); - - b8.reset(); - b8.flip(); - b8 >>= 65; - EATEST_VERIFY(b8.count() == 0); - - b8.from_uint32(0x10101010); - EATEST_VERIFY(b8.to_uint32() == 0x00000010); - b8.from_uint64(UINT64_C(0x0000000000000010)); - EATEST_VERIFY(b8.to_uint64() == UINT64_C(0x0000000000000010)); - - - - // bitset<16> tests - bitset<16> b16(0x10101010); - EATEST_VERIFY(b16.count() == 2); - EATEST_VERIFY(b16.to_ulong() == 0x00001010); - EATEST_VERIFY(b16.to_uint32() == 0x00001010); - EATEST_VERIFY(b16.to_uint64() == 0x00001010); - - b16.flip(); - EATEST_VERIFY(b16.count() == 14); - EATEST_VERIFY(b16.to_ulong() == 0x0000efef); - EATEST_VERIFY(b16.to_uint32() == 0x0000efef); - EATEST_VERIFY(b16.to_uint64() == 0x0000efef); - - b16 <<= 1; - EATEST_VERIFY(b16.count() == 13); - EATEST_VERIFY(b16.to_ulong() == 0x0000dfde); - EATEST_VERIFY(b16.to_uint32() == 0x0000dfde); - EATEST_VERIFY(b16.to_uint64() == 0x0000dfde); - - b16.reset(); - b16.flip(); - b16 >>= 33; - EATEST_VERIFY(b16.count() == 0); - - b16.reset(); - b16.flip(); - b16 >>= 65; - EATEST_VERIFY(b16.count() == 0); - - b16.from_uint32(0x10101010); - EATEST_VERIFY(b16.to_uint32() == 0x00001010); - b16.from_uint64(UINT64_C(0x0000000000001010)); - EATEST_VERIFY(b16.to_uint64() == UINT64_C(0x0000000000001010)); - - - - // bitset<32> tests - bitset<32> b32(0x10101010); - EATEST_VERIFY(b32.count() == 4); - EATEST_VERIFY(b32.to_ulong() == 0x10101010); - EATEST_VERIFY(b32.to_uint32() == 0x10101010); - EATEST_VERIFY(b32.to_uint64() == 0x10101010); - - b32.flip(); - EATEST_VERIFY(b32.count() == 28); - EATEST_VERIFY(b32.to_ulong() == 0xefefefef); - EATEST_VERIFY(b32.to_uint32() == 0xefefefef); - EATEST_VERIFY(b32.to_uint64() == 0xefefefef); - - b32 <<= 1; - EATEST_VERIFY(b32.count() == 27); - EATEST_VERIFY(b32.to_ulong() == 0xdfdfdfde); - EATEST_VERIFY(b32.to_uint32() == 0xdfdfdfde); - EATEST_VERIFY(b32.to_uint64() == 0xdfdfdfde); - - b32.reset(); - b32.flip(); - b32 >>= 33; - EATEST_VERIFY(b32.count() == 0); - - b32.reset(); - b32.flip(); - b32 >>= 65; - EATEST_VERIFY(b32.count() == 0); - - b32.from_uint32(0x10101010); - EATEST_VERIFY(b32.to_uint32() == 0x10101010); - b32.from_uint64(UINT64_C(0x0000000010101010)); - EATEST_VERIFY(b32.to_uint64() == UINT64_C(0x0000000010101010)); - - - - // bitset<64> tests - bitset<64> b64(0x10101010); // b64 => 00000000 00000000 00000000 00000000 00010000 00010000 00010000 00010000 - EATEST_VERIFY(b64.count() == 4); - EATEST_VERIFY(b64.to_ulong() == 0x10101010); - EATEST_VERIFY(b64.to_uint32() == 0x10101010); - EATEST_VERIFY(b64.to_uint64() == 0x10101010); - - b64.flip(); // b64 => 11111111 11111111 11111111 11111111 11101111 11101111 11101111 11101111 - EATEST_VERIFY(b64.count() == 60); - if(sizeof(unsigned long) + nErrorCount - nErrorCount == 4) // We have this no-op math here in order to avoid compiler warnings about constant expressions. - { - #if EASTL_EXCEPTIONS_ENABLED - try { - EATEST_VERIFY(b64.to_ulong() == 0xefefefef); - EATEST_VERIFY(false); - } - catch(std::overflow_error&) - { - EATEST_VERIFY(true); // This pathway should be taken. - } - catch(...) - { - EATEST_VERIFY(false); - } - #else - EATEST_VERIFY(b64.to_ulong() == 0xefefefef); - #endif - } - else - { - EATEST_VERIFY(b64.to_ulong() == (unsigned long)UINT64_C(0xffffffffefefefef)); - } - - b64 <<= 1; // b64 => 11111111 11111111 11111111 11111111 11011111 11011111 11011111 11011110 - EATEST_VERIFY(b64.count() == 59); - if(sizeof(unsigned long) + nErrorCount - nErrorCount == 4) - { - #if !EASTL_EXCEPTIONS_ENABLED - EATEST_VERIFY(b64.to_ulong() == 0xdfdfdfde); - #endif - } - else - { - EATEST_VERIFY(b64.to_ulong() == (unsigned long)UINT64_C(0xffffffffdfdfdfde)); - } - - b64.reset(); // b64 => 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 - EATEST_VERIFY(b64.count() == 0); - EATEST_VERIFY(b64.to_ulong() == 0); - - b64 <<= 1; // b64 => 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 - EATEST_VERIFY(b64.count() == 0); - EATEST_VERIFY(b64.to_ulong() == 0); - - b64.flip(); // b64 => 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 - EATEST_VERIFY(b64.count() == 64); - if(sizeof(unsigned long) + nErrorCount - nErrorCount == 4) - { - #if !EASTL_EXCEPTIONS_ENABLED - EATEST_VERIFY(b64.to_ulong() == 0xffffffff); - #endif - } - else - EATEST_VERIFY(b64.to_ulong() == (unsigned long)UINT64_C(0xffffffffffffffff)); - - b64 <<= 1; // b64 => 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111110 - EATEST_VERIFY(b64.count() == 63); - if(sizeof(unsigned long) + nErrorCount - nErrorCount == 4) - { - #if !EASTL_EXCEPTIONS_ENABLED - EATEST_VERIFY(b64.to_ulong() == 0xfffffffe); - #endif - } - else - EATEST_VERIFY(b64.to_ulong() == (unsigned long)UINT64_C(0xfffffffffffffffe)); - - b64.reset(); - b64.flip(); - b64 >>= 33; - EATEST_VERIFY(b64.count() == 31); - - b64.reset(); - b64.flip(); - b64 >>= 65; - EATEST_VERIFY(b64.count() == 0); - - b64.from_uint32(0x10101010); - EATEST_VERIFY(b64.to_uint32() == 0x10101010); - b64.from_uint64(UINT64_C(0x1010101010101010)); - EATEST_VERIFY(b64.to_uint64() == UINT64_C(0x1010101010101010)); - } - - - { - bitset<1> b1; - bitset<1> b1A(1); - - EATEST_VERIFY(b1.size() == 1); - EATEST_VERIFY(b1.any() == false); - EATEST_VERIFY(b1.all() == false); - EATEST_VERIFY(b1.none() == true); - EATEST_VERIFY(b1.to_ulong() == 0); - EATEST_VERIFY(b1A.any() == true); - EATEST_VERIFY(b1A.all() == true); - EATEST_VERIFY(b1A.none() == false); - EATEST_VERIFY(b1A.to_ulong() == 1); - EATEST_VERIFY(b1A.to_uint32() == 1); - EATEST_VERIFY(b1A.to_uint64() == 1); - - - bitset<33> b33; - bitset<33> b33A(1); - - EATEST_VERIFY(b33.size() == 33); - EATEST_VERIFY(b33.any() == false); - EATEST_VERIFY(b33.all() == false); - EATEST_VERIFY(b33.none() == true); - EATEST_VERIFY(b33.to_ulong() == 0); - EATEST_VERIFY(b33A.any() == true); - EATEST_VERIFY(b33A.all() == false); - EATEST_VERIFY(b33A.none() == false); - EATEST_VERIFY(b33A.to_ulong() == 1); - - - bitset<65> b65; - bitset<65> b65A(1); - - EATEST_VERIFY(b65.size() == 65); - EATEST_VERIFY(b65.any() == false); - EATEST_VERIFY(b65.all() == false); - EATEST_VERIFY(b65.none() == true); - EATEST_VERIFY(b65.to_ulong() == 0); - EATEST_VERIFY(b65A.any() == true); - EATEST_VERIFY(b65A.all() == false); - EATEST_VERIFY(b65A.none() == false); - EATEST_VERIFY(b65A.to_ulong() == 1); - - - bitset<129> b129; - bitset<129> b129A(1); - - EATEST_VERIFY(b129.size() == 129); - EATEST_VERIFY(b129.any() == false); - EATEST_VERIFY(b129.all() == false); - EATEST_VERIFY(b129.none() == true); - EATEST_VERIFY(b129.to_ulong() == 0); - EATEST_VERIFY(b129A.any() == true); - EATEST_VERIFY(b129A.all() == false); - EATEST_VERIFY(b129A.none() == false); - EATEST_VERIFY(b129A.to_ulong() == 1); - - - // operator[], data, test, to_ulong, count - b1[0] = true; - EATEST_VERIFY(b1.test(0) == true); - EATEST_VERIFY(b1.count() == 1); - - b33[0] = true; - b33[32] = true; - EATEST_VERIFY(b33.test(0) == true); - EATEST_VERIFY(b33.test(15) == false); - EATEST_VERIFY(b33.test(32) == true); - EATEST_VERIFY(b33.count() == 2); - - b65[0] = true; - b65[32] = true; - b65[64] = true; - EATEST_VERIFY(b65.test(0) == true); - EATEST_VERIFY(b65.test(15) == false); - EATEST_VERIFY(b65.test(32) == true); - EATEST_VERIFY(b65.test(47) == false); - EATEST_VERIFY(b65.test(64) == true); - EATEST_VERIFY(b65.count() == 3); - - b129[0] = true; - b129[32] = true; - b129[64] = true; - b129[128] = true; - EATEST_VERIFY(b129.test(0) == true); - EATEST_VERIFY(b129.test(15) == false); - EATEST_VERIFY(b129.test(32) == true); - EATEST_VERIFY(b129.test(47) == false); - EATEST_VERIFY(b129.test(64) == true); - EATEST_VERIFY(b129.test(91) == false); - EATEST_VERIFY(b129.test(128) == true); - EATEST_VERIFY(b129.count() == 4); - - bitset<1>::word_type* pWordArray; - - pWordArray = b1.data(); - EATEST_VERIFY(pWordArray != NULL); - pWordArray = b33.data(); - EATEST_VERIFY(pWordArray != NULL); - pWordArray = b65.data(); - EATEST_VERIFY(pWordArray != NULL); - pWordArray = b129.data(); - EATEST_VERIFY(pWordArray != NULL); - - - // bitset<1> set, reset, flip, ~ - b1.reset(); - EATEST_VERIFY(b1.count() == 0); - - b1.set(); - EATEST_VERIFY(b1.count() == b1.size()); - EATEST_VERIFY(b1.all()); - - b1.flip(); - EATEST_VERIFY(b1.count() == 0); - EATEST_VERIFY(!b1.all()); - EATEST_VERIFY(b1.none()); - - b1.set(0, true); - EATEST_VERIFY(b1[0] == true); - - b1.reset(0); - EATEST_VERIFY(b1[0] == false); - - b1.flip(0); - EATEST_VERIFY(b1[0] == true); - - bitset<1> b1Not = ~b1; - EATEST_VERIFY(b1[0] == true); - EATEST_VERIFY(b1Not[0] == false); - - - // bitset<33> set, reset, flip, ~ - b33.reset(); - EATEST_VERIFY(b33.count() == 0); - - b33.set(); - EATEST_VERIFY(b33.count() == b33.size()); - EATEST_VERIFY(b33.all()); - - - b33.flip(); - EATEST_VERIFY(b33.count() == 0); - EATEST_VERIFY(!b33.all()); - - b33.set(0, true); - b33.set(32, true); - EATEST_VERIFY(b33[0] == true); - EATEST_VERIFY(b33[15] == false); - EATEST_VERIFY(b33[32] == true); - - b33.reset(0); - b33.reset(32); - EATEST_VERIFY(b33[0] == false); - EATEST_VERIFY(b33[32] == false); - - b33.flip(0); - b33.flip(32); - EATEST_VERIFY(b33[0] == true); - EATEST_VERIFY(b33[32] == true); - - bitset<33> b33Not(~b33); - EATEST_VERIFY(b33[0] == true); - EATEST_VERIFY(b33[32] == true); - EATEST_VERIFY(b33Not[0] == false); - EATEST_VERIFY(b33Not[32] == false); - - - // bitset<65> set, reset, flip, ~ - b65.reset(); - EATEST_VERIFY(b65.count() == 0); - EATEST_VERIFY(!b65.all()); - EATEST_VERIFY(b65.none()); - - b65.set(); - EATEST_VERIFY(b65.count() == b65.size()); - EATEST_VERIFY(b65.all()); - EATEST_VERIFY(!b65.none()); - - b65.flip(); - EATEST_VERIFY(b65.count() == 0); - EATEST_VERIFY(!b65.all()); - EATEST_VERIFY(b65.none()); - - - b65.set(0, true); - b65.set(32, true); - b65.set(64, true); - EATEST_VERIFY(b65[0] == true); - EATEST_VERIFY(b65[15] == false); - EATEST_VERIFY(b65[32] == true); - EATEST_VERIFY(b65[50] == false); - EATEST_VERIFY(b65[64] == true); - - b65.reset(0); - b65.reset(32); - b65.reset(64); - EATEST_VERIFY(b65[0] == false); - EATEST_VERIFY(b65[32] == false); - EATEST_VERIFY(b65[64] == false); - - b65.flip(0); - b65.flip(32); - b65.flip(64); - EATEST_VERIFY(b65[0] == true); - EATEST_VERIFY(b65[32] == true); - EATEST_VERIFY(b65[64] == true); - - bitset<65> b65Not(~b65); - EATEST_VERIFY(b65[0] == true); - EATEST_VERIFY(b65[32] == true); - EATEST_VERIFY(b65[64] == true); - EATEST_VERIFY(b65Not[0] == false); - EATEST_VERIFY(b65Not[32] == false); - EATEST_VERIFY(b65Not[64] == false); - - - // bitset<65> set, reset, flip, ~ - b129.reset(); - EATEST_VERIFY(b129.count() == 0); - - b129.set(); - EATEST_VERIFY(b129.count() == b129.size()); - EATEST_VERIFY(b129.all()); - - b129.flip(); - EATEST_VERIFY(b129.count() == 0); - EATEST_VERIFY(!b129.all()); - EATEST_VERIFY(b129.none()); - - b129.set(0, true); - b129.set(32, true); - b129.set(64, true); - b129.set(128, true); - EATEST_VERIFY(b129[0] == true); - EATEST_VERIFY(b129[15] == false); - EATEST_VERIFY(b129[32] == true); - EATEST_VERIFY(b129[50] == false); - EATEST_VERIFY(b129[64] == true); - EATEST_VERIFY(b129[90] == false); - EATEST_VERIFY(b129[128] == true); - - b129.reset(0); - b129.reset(32); - b129.reset(64); - b129.reset(128); - EATEST_VERIFY(b129[0] == false); - EATEST_VERIFY(b129[32] == false); - EATEST_VERIFY(b129[64] == false); - EATEST_VERIFY(b129[128] == false); - - b129.flip(0); - b129.flip(32); - b129.flip(64); - b129.flip(128); - EATEST_VERIFY(b129[0] == true); - EATEST_VERIFY(b129[32] == true); - EATEST_VERIFY(b129[64] == true); - EATEST_VERIFY(b129[128] == true); - - bitset<129> b129Not(~b129); - EATEST_VERIFY(b129[0] == true); - EATEST_VERIFY(b129[32] == true); - EATEST_VERIFY(b129[64] == true); - EATEST_VERIFY(b129[128] == true); - EATEST_VERIFY(b129Not[0] == false); - EATEST_VERIFY(b129Not[32] == false); - EATEST_VERIFY(b129Not[64] == false); - EATEST_VERIFY(b129Not[128] == false); - - - // operator ==, != - bitset<1> b1Equal(b1); - EATEST_VERIFY(b1Equal == b1); - EATEST_VERIFY(b1Equal != b1Not); - - bitset<33> b33Equal(b33); - EATEST_VERIFY(b33Equal == b33); - EATEST_VERIFY(b33Equal != b33Not); - - bitset<65> b65Equal(b65); - EATEST_VERIFY(b65Equal == b65); - EATEST_VERIFY(b65Equal != b65Not); - - bitset<129> b129Equal(b129); - EATEST_VERIFY(b129Equal == b129); - EATEST_VERIFY(b129Equal != b129Not); - - - // bitset<1> operator<<=, operator>>=, operator<<, operator>> - b1.reset(); - - b1[0] = true; - b1 >>= 0; - EATEST_VERIFY(b1[0] == true); - b1 >>= 1; - EATEST_VERIFY(b1[0] == false); - - b1[0] = true; - b1 <<= 0; - EATEST_VERIFY(b1[0] == true); - b1 <<= 1; - EATEST_VERIFY(b1[0] == false); - - b1[0] = true; - b1Equal = b1 >> 0; - EATEST_VERIFY(b1Equal == b1); - b1Equal = b1 >> 1; - EATEST_VERIFY(b1Equal[0] == false); - - b1[0] = true; - b1Equal = b1 << 0; - EATEST_VERIFY(b1Equal[0] == true); - b1Equal = b1 << 1; - EATEST_VERIFY(b1Equal[0] == false); - - b1.reset(); - b1.flip(); - b1 >>= 33; - EATEST_VERIFY(b1.count() == 0); - EATEST_VERIFY(!b1.all()); - EATEST_VERIFY(b1.none()); - - b1.reset(); - b1.flip(); - b1 <<= 33; - EATEST_VERIFY(b1.count() == 0); - EATEST_VERIFY(!b1.all()); - EATEST_VERIFY(b1.none()); - - b1.reset(); - b1.flip(); - b1 >>= 65; - EATEST_VERIFY(b1.count() == 0); - EATEST_VERIFY(!b1.all()); - EATEST_VERIFY(b1.none()); - - b1.reset(); - b1.flip(); - b1 <<= 65; - EATEST_VERIFY(b1.count() == 0); - EATEST_VERIFY(!b1.all()); - EATEST_VERIFY(b1.none()); - - - // bitset<33> operator<<=, operator>>=, operator<<, operator>> - b33.reset(); - - b33[0] = true; - b33[32] = true; - b33 >>= 0; - EATEST_VERIFY(b33[0] == true); - EATEST_VERIFY(b33[32] == true); - b33 >>= 10; - EATEST_VERIFY(b33[22] == true); - - b33.reset(); - b33[0] = true; - b33[32] = true; - b33 <<= 0; - EATEST_VERIFY(b33[0] == true); - EATEST_VERIFY(b33[32] == true); - b33 <<= 10; - EATEST_VERIFY(b33[10] == true); - - b33.reset(); - b33[0] = true; - b33[32] = true; - b33Equal = b33 >> 0; - EATEST_VERIFY(b33Equal == b33); - b33Equal = b33 >> 10; - EATEST_VERIFY(b33Equal[22] == true); - - b33.reset(); - b33[0] = true; - b33[32] = true; - b33Equal = b33 << 10; - EATEST_VERIFY(b33Equal[10] == true); - - b33.reset(); - b33.flip(); - b33 >>= 33; - EATEST_VERIFY(b33.count() == 0); - EATEST_VERIFY(!b33.all()); - EATEST_VERIFY(b33.none()); - - b33.reset(); - b33.flip(); - b33 <<= 33; - EATEST_VERIFY(b33.count() == 0); - EATEST_VERIFY(!b33.all()); - EATEST_VERIFY(b33.none()); - - b33.reset(); - b33.flip(); - b33 >>= 65; - EATEST_VERIFY(b33.count() == 0); - EATEST_VERIFY(!b33.all()); - EATEST_VERIFY(b33.none()); - - b33.reset(); - b33.flip(); - b33 <<= 65; - EATEST_VERIFY(b33.count() == 0); - EATEST_VERIFY(!b33.all()); - EATEST_VERIFY(b33.none()); - - - // bitset<65> operator<<=, operator>>=, operator<<, operator>> - b65.reset(); - - b65[0] = true; - b65[32] = true; - b65[64] = true; - b65 >>= 0; - EATEST_VERIFY(b65[0] == true); - EATEST_VERIFY(b65[32] == true); - EATEST_VERIFY(b65[64] == true); - b65 >>= 10; - EATEST_VERIFY(b65[22] == true); - EATEST_VERIFY(b65[54] == true); - - b65.reset(); - b65[0] = true; - b65[32] = true; - b65[64] = true; - b65 <<= 0; - EATEST_VERIFY(b65[0] == true); - EATEST_VERIFY(b65[32] == true); - EATEST_VERIFY(b65[64] == true); - b65 <<= 10; - EATEST_VERIFY(b65[10] == true); - EATEST_VERIFY(b65[42] == true); - - b65.reset(); - b65[0] = true; - b65[32] = true; - b65[64] = true; - b65Equal = b65 >> 0; - EATEST_VERIFY(b65Equal == b65); - b65Equal = b65 >> 10; - EATEST_VERIFY(b65Equal[22] == true); - EATEST_VERIFY(b65Equal[54] == true); - - b65.reset(); - b65[0] = true; - b65[32] = true; - b65[64] = true; - b65Equal = b65 << 10; - EATEST_VERIFY(b65Equal[10] == true); - EATEST_VERIFY(b65Equal[42] == true); - - b65.reset(); - b65.flip(); - b65 >>= 33; - EATEST_VERIFY(b65.count() == 32); - - b65.reset(); - b65.flip(); - b65 <<= 33; - EATEST_VERIFY(b65.count() == 32); - - b65.reset(); - b65.flip(); - b65 >>= 65; - EATEST_VERIFY(b65.count() == 0); - - b65.reset(); - b65.flip(); - b65 <<= 65; - EATEST_VERIFY(b65.count() == 0); - - - // bitset<129> operator<<=, operator>>=, operator<<, operator>> - b129.reset(); - - b129[0] = true; - b129[32] = true; - b129[64] = true; - b129[128] = true; - b129 >>= 0; - EATEST_VERIFY(b129[0] == true); - EATEST_VERIFY(b129[32] == true); - EATEST_VERIFY(b129[64] == true); - EATEST_VERIFY(b129[128] == true); - b129 >>= 10; - EATEST_VERIFY(b129[22] == true); - EATEST_VERIFY(b129[54] == true); - EATEST_VERIFY(b129[118] == true); - - b129.reset(); - b129[0] = true; - b129[32] = true; - b129[64] = true; - b129[128] = true; - b129 <<= 0; - EATEST_VERIFY(b129[0] == true); - EATEST_VERIFY(b129[32] == true); - EATEST_VERIFY(b129[64] == true); - EATEST_VERIFY(b129[128] == true); - b129 <<= 10; - EATEST_VERIFY(b129[10] == true); - EATEST_VERIFY(b129[42] == true); - EATEST_VERIFY(b129[74] == true); - - b129.reset(); - b129[0] = true; - b129[32] = true; - b129[64] = true; - b129[128] = true; - b129Equal = b129 >> 0; - EATEST_VERIFY(b129Equal == b129); - b129Equal = b129 >> 10; - EATEST_VERIFY(b129Equal[22] == true); - EATEST_VERIFY(b129Equal[54] == true); - EATEST_VERIFY(b129Equal[118] == true); - - b129.reset(); - b129[0] = true; - b129[32] = true; - b129[64] = true; - b129[128] = true; - b129Equal = b129 << 10; - EATEST_VERIFY(b129Equal[10] == true); - EATEST_VERIFY(b129Equal[42] == true); - EATEST_VERIFY(b129Equal[74] == true); - - b129.reset(); - b129.flip(); - b129 >>= 33; - EATEST_VERIFY(b129.count() == 96); - - b129.reset(); - b129.flip(); - b129 <<= 33; - EATEST_VERIFY(b129.count() == 96); - - b129.reset(); - b129.flip(); - b129 >>= 65; - EATEST_VERIFY(b129.count() == 64); - - b129.reset(); - b129.flip(); - b129 <<= 65; - EATEST_VERIFY(b129.count() == 64); - - - // operator&=(const this_type& x), operator|=(const this_type& x), operator^=(const this_type& x) - b1.set(); - b1[0] = false; - b1A[0] = true; - b1 &= b1A; - EATEST_VERIFY(b1[0] == false); - b1 |= b1A; - EATEST_VERIFY(b1[0] == true); - b1 ^= b1A; - EATEST_VERIFY(b1[0] == false); - b1 |= b1A; - EATEST_VERIFY(b1[0] == true); - - b33.set(); - b33[0] = false; - b33[32] = false; - b33A[0] = true; - b33A[32] = true; - b33 &= b33A; - EATEST_VERIFY((b33[0] == false) && (b33[32] == false)); - b33 |= b33A; - EATEST_VERIFY((b33[0] == true) && (b33[32] == true)); - b33 ^= b33A; - EATEST_VERIFY((b33[0] == false) && (b33[32] == false)); - b33 |= b33A; - EATEST_VERIFY((b33[0] == true) && (b33[32] == true)); - - b65.set(); - b65[0] = false; - b65[32] = false; - b65[64] = false; - b65A[0] = true; - b65A[32] = true; - b65A[64] = true; - b65 &= b65A; - EATEST_VERIFY((b65[0] == false) && (b65[32] == false) && (b65[64] == false)); - b65 |= b65A; - EATEST_VERIFY((b65[0] == true) && (b65[32] == true) && (b65[64] == true)); - b65 ^= b65A; - EATEST_VERIFY((b65[0] == false) && (b65[32] == false) && (b65[64] == false)); - b65 |= b65A; - EATEST_VERIFY((b65[0] == true) && (b65[32] == true) && (b65[64] == true)); - - b129.set(); - b129[0] = false; - b129[32] = false; - b129[64] = false; - b129[128] = false; - b129A[0] = true; - b129A[32] = true; - b129A[64] = true; - b129A[128] = true; - b129 &= b129A; - EATEST_VERIFY((b129[0] == false) && (b129[32] == false) && (b129[64] == false) && (b129[128] == false)); - b129 |= b129A; - EATEST_VERIFY((b129[0] == true) && (b129[32] == true) && (b129[64] == true) && (b129[128] == true)); - b129 ^= b129A; - EATEST_VERIFY((b129[0] == false) && (b129[32] == false) && (b129[64] == false) && (b129[128] == false)); - b129 |= b129A; - EATEST_VERIFY((b129[0] == true) && (b129[32] == true) && (b129[64] == true) && (b129[128] == true)); - } - - { // Test bitset::reference - bitset<65> b65; - bitset<65>::reference r = b65[33]; - - r = true; - EATEST_VERIFY(r == true); - } - - { // Test find_first, find_next - size_t i, j; - - // bitset<1> - bitset<1> b1; - - i = b1.find_first(); - EATEST_VERIFY(i == b1.kSize); - b1.set(0, true); - i = b1.find_first(); - EATEST_VERIFY(i == 0); - i = b1.find_next(i); - EATEST_VERIFY(i == b1.kSize); - - b1.set(); - for(i = 0, j = b1.find_first(); j != b1.kSize; j = b1.find_next(j)) - ++i; - EATEST_VERIFY(i == 1); - - // bitset<7> - bitset<7> b7; - - i = b7.find_first(); - EATEST_VERIFY(i == b7.kSize); - b7.set(0, true); - b7.set(5, true); - i = b7.find_first(); - EATEST_VERIFY(i == 0); - i = b7.find_next(i); - EATEST_VERIFY(i == 5); - i = b7.find_next(i); - EATEST_VERIFY(i == b7.kSize); - - b7.set(); - for(i = 0, j = b7.find_first(); j != b7.kSize; j = b7.find_next(j)) - ++i; - EATEST_VERIFY(i == 7); - - // bitset<32> - bitset<32> b32; - - i = b32.find_first(); - EATEST_VERIFY(i == b32.kSize); - b32.set(0, true); - b32.set(27, true); - i = b32.find_first(); - EATEST_VERIFY(i == 0); - i = b32.find_next(i); - EATEST_VERIFY(i == 27); - i = b32.find_next(i); - EATEST_VERIFY(i == b32.kSize); - - b32.set(); - for(i = 0, j = b32.find_first(); j != b32.kSize; j = b32.find_next(j)) - ++i; - EATEST_VERIFY(i == 32); - - // bitset<41> - bitset<41> b41; - - i = b41.find_first(); - EATEST_VERIFY(i == b41.kSize); - b41.set(0, true); - b41.set(27, true); - b41.set(37, true); - i = b41.find_first(); - EATEST_VERIFY(i == 0); - i = b41.find_next(i); - EATEST_VERIFY(i == 27); - i = b41.find_next(i); - EATEST_VERIFY(i == 37); - i = b41.find_next(i); - EATEST_VERIFY(i == b41.kSize); - - b41.set(); - for(i = 0, j = b41.find_first(); j != b41.kSize; j = b41.find_next(j)) - ++i; - EATEST_VERIFY(i == 41); - - // bitset<64> - bitset<64> b64; - - i = b64.find_first(); - EATEST_VERIFY(i == b64.kSize); - b64.set(0, true); - b64.set(27, true); - b64.set(37, true); - i = b64.find_first(); - EATEST_VERIFY(i == 0); - i = b64.find_next(i); - EATEST_VERIFY(i == 27); - i = b64.find_next(i); - EATEST_VERIFY(i == 37); - i = b64.find_next(i); - EATEST_VERIFY(i == b64.kSize); - - b64.set(); - for(i = 0, j = b64.find_first(); j != b64.kSize; j = b64.find_next(j)) - ++i; - EATEST_VERIFY(i == 64); - - // bitset<79> - bitset<79> b79; - - i = b79.find_first(); - EATEST_VERIFY(i == b79.kSize); - b79.set(0, true); - b79.set(27, true); - b79.set(37, true); - i = b79.find_first(); - EATEST_VERIFY(i == 0); - i = b79.find_next(i); - EATEST_VERIFY(i == 27); - i = b79.find_next(i); - EATEST_VERIFY(i == 37); - i = b79.find_next(i); - EATEST_VERIFY(i == b79.kSize); - - b79.set(); - for(i = 0, j = b79.find_first(); j != b79.kSize; j = b79.find_next(j)) - ++i; - EATEST_VERIFY(i == 79); - - // bitset<128> - bitset<128> b128; - - i = b128.find_first(); - EATEST_VERIFY(i == b128.kSize); - b128.set(0, true); - b128.set(27, true); - b128.set(37, true); - b128.set(77, true); - i = b128.find_first(); - EATEST_VERIFY(i == 0); - i = b128.find_next(i); - EATEST_VERIFY(i == 27); - i = b128.find_next(i); - EATEST_VERIFY(i == 37); - i = b128.find_next(i); - EATEST_VERIFY(i == 77); - i = b128.find_next(i); - EATEST_VERIFY(i == b128.kSize); - - b128.set(); - for(i = 0, j = b128.find_first(); j != b128.kSize; j = b128.find_next(j)) - ++i; - EATEST_VERIFY(i == 128); - - // bitset<137> - bitset<137> b137; - - i = b137.find_first(); - EATEST_VERIFY(i == b137.kSize); - b137.set(0, true); - b137.set(27, true); - b137.set(37, true); - b137.set(77, true); - b137.set(99, true); - b137.set(136, true); - i = b137.find_first(); - EATEST_VERIFY(i == 0); - i = b137.find_next(i); - EATEST_VERIFY(i == 27); - i = b137.find_next(i); - EATEST_VERIFY(i == 37); - i = b137.find_next(i); - EATEST_VERIFY(i == 77); - i = b137.find_next(i); - EATEST_VERIFY(i == 99); - i = b137.find_next(i); - EATEST_VERIFY(i == 136); - i = b137.find_next(i); - EATEST_VERIFY(i == b137.kSize); - - b137.set(); - for(i = 0, j = b137.find_first(); j != b137.kSize; j = b137.find_next(j)) - ++i; - EATEST_VERIFY(i == 137); - } - - { // Test find_last, find_prev - size_t i, j; - - // bitset<1> - bitset<1> b1; - - i = b1.find_last(); - EATEST_VERIFY(i == b1.kSize); - b1.set(0, true); - i = b1.find_last(); - EATEST_VERIFY(i == 0); - i = b1.find_prev(i); - EATEST_VERIFY(i == b1.kSize); - - b1.set(); - for(i = 0, j = b1.find_last(); j != b1.kSize; j = b1.find_prev(j)) - ++i; - EATEST_VERIFY(i == 1); - - // bitset<7> - bitset<7> b7; - - i = b7.find_last(); - EATEST_VERIFY(i == b7.kSize); - b7.set(0, true); - b7.set(5, true); - i = b7.find_last(); - EATEST_VERIFY(i == 5); - i = b7.find_prev(i); - EATEST_VERIFY(i == 0); - i = b7.find_prev(i); - EATEST_VERIFY(i == b7.kSize); - - b7.set(); - for(i = 0, j = b7.find_last(); j != b7.kSize; j = b7.find_prev(j)) - ++i; - EATEST_VERIFY(i == 7); - - // bitset<32> - bitset<32> b32; - - i = b32.find_last(); - EATEST_VERIFY(i == b32.kSize); - b32.set(0, true); - b32.set(27, true); - i = b32.find_last(); - EATEST_VERIFY(i == 27); - i = b32.find_prev(i); - EATEST_VERIFY(i == 0); - i = b32.find_prev(i); - EATEST_VERIFY(i == b32.kSize); - - b32.set(); - for(i = 0, j = b32.find_last(); j != b32.kSize; j = b32.find_prev(j)) - ++i; - EATEST_VERIFY(i == 32); - - // bitset<41> - bitset<41> b41; - - i = b41.find_last(); - EATEST_VERIFY(i == b41.kSize); - b41.set(0, true); - b41.set(27, true); - b41.set(37, true); - i = b41.find_last(); - EATEST_VERIFY(i == 37); - i = b41.find_prev(i); - EATEST_VERIFY(i == 27); - i = b41.find_prev(i); - EATEST_VERIFY(i == 0); - i = b41.find_prev(i); - EATEST_VERIFY(i == b41.kSize); - - b41.set(); - for(i = 0, j = b41.find_last(); j != b41.kSize; j = b41.find_prev(j)) - ++i; - EATEST_VERIFY(i == 41); - - // bitset<64> - bitset<64> b64; - - i = b64.find_last(); - EATEST_VERIFY(i == b64.kSize); - b64.set(0, true); - b64.set(27, true); - b64.set(37, true); - i = b64.find_last(); - EATEST_VERIFY(i == 37); - i = b64.find_prev(i); - EATEST_VERIFY(i == 27); - i = b64.find_prev(i); - EATEST_VERIFY(i == 0); - i = b64.find_prev(i); - EATEST_VERIFY(i == b64.kSize); - - b64.set(); - for(i = 0, j = b64.find_last(); j != b64.kSize; j = b64.find_prev(j)) - ++i; - EATEST_VERIFY(i == 64); - - // bitset<79> - bitset<79> b79; - - i = b79.find_last(); - EATEST_VERIFY(i == b79.kSize); - b79.set(0, true); - b79.set(27, true); - b79.set(37, true); - i = b79.find_last(); - EATEST_VERIFY(i == 37); - i = b79.find_prev(i); - EATEST_VERIFY(i == 27); - i = b79.find_prev(i); - EATEST_VERIFY(i == 0); - i = b79.find_prev(i); - EATEST_VERIFY(i == b79.kSize); - - b79.set(); - for(i = 0, j = b79.find_last(); j != b79.kSize; j = b79.find_prev(j)) - ++i; - EATEST_VERIFY(i == 79); - - // bitset<128> - bitset<128> b128; - - i = b128.find_last(); - EATEST_VERIFY(i == b128.kSize); - b128.set(0, true); - b128.set(27, true); - b128.set(37, true); - b128.set(77, true); - i = b128.find_last(); - EATEST_VERIFY(i == 77); - i = b128.find_prev(i); - EATEST_VERIFY(i == 37); - i = b128.find_prev(i); - EATEST_VERIFY(i == 27); - i = b128.find_prev(i); - EATEST_VERIFY(i == 0); - i = b128.find_prev(i); - EATEST_VERIFY(i == b128.kSize); - - b128.set(); - for(i = 0, j = b128.find_last(); j != b128.kSize; j = b128.find_prev(j)) - ++i; - EATEST_VERIFY(i == 128); - - // bitset<137> - bitset<137> b137; - - i = b137.find_last(); - EATEST_VERIFY(i == b137.kSize); - b137.set(0, true); - b137.set(27, true); - b137.set(37, true); - b137.set(77, true); - b137.set(99, true); - b137.set(136, true); - i = b137.find_last(); - EATEST_VERIFY(i == 136); - i = b137.find_prev(i); - EATEST_VERIFY(i == 99); - i = b137.find_prev(i); - EATEST_VERIFY(i == 77); - i = b137.find_prev(i); - EATEST_VERIFY(i == 37); - i = b137.find_prev(i); - EATEST_VERIFY(i == 27); - i = b137.find_prev(i); - EATEST_VERIFY(i == 0); - i = b137.find_prev(i); - EATEST_VERIFY(i == b137.kSize); - - b137.set(); - for(i = 0, j = b137.find_last(); j != b137.kSize; j = b137.find_prev(j)) - ++i; - EATEST_VERIFY(i == 137); - } - - // test BITSET_WORD_COUNT macro - { - { - typedef eastl::bitset<32, char> bitset_t; - static_assert(bitset_t::kWordCount == BITSET_WORD_COUNT(bitset_t::kSize, bitset_t::word_type), "bitset failure"); - } - { - typedef eastl::bitset<32, int> bitset_t; - static_assert(bitset_t::kWordCount == BITSET_WORD_COUNT(bitset_t::kSize, bitset_t::word_type), "bitset failure"); - } - { - typedef eastl::bitset<32, int16_t> bitset_t; - static_assert(bitset_t::kWordCount == BITSET_WORD_COUNT(bitset_t::kSize, bitset_t::word_type), "bitset failure"); - } - { - typedef eastl::bitset<32, int32_t> bitset_t; - static_assert(bitset_t::kWordCount == BITSET_WORD_COUNT(bitset_t::kSize, bitset_t::word_type), "bitset failure"); - } - { - typedef eastl::bitset<128, int64_t> bitset_t; - static_assert(bitset_t::kWordCount == BITSET_WORD_COUNT(bitset_t::kSize, bitset_t::word_type), "bitset failure"); - } - { - typedef eastl::bitset<256, int64_t> bitset_t; - static_assert(bitset_t::kWordCount == BITSET_WORD_COUNT(bitset_t::kSize, bitset_t::word_type), "bitset failure"); - } - } - - return nErrorCount; -} - - - - - - - - - - - - - - - - - - - diff --git a/test/source/TestCharTraits.cpp b/test/source/TestCharTraits.cpp deleted file mode 100644 index bbcab54..0000000 --- a/test/source/TestCharTraits.cpp +++ /dev/null @@ -1,39 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EABase/eabase.h> -#include <EASTL/internal/char_traits.h> - - -template<typename CharT> -int TestCharTraits() -{ - int nErrorCount = 0; - return nErrorCount; -} - - -int TestCharTraits() -{ - using namespace eastl; - - int nErrorCount = 0; - - nErrorCount += TestCharTraits<char>(); - nErrorCount += TestCharTraits<wchar_t>(); - nErrorCount += TestCharTraits<char16_t>(); - nErrorCount += TestCharTraits<char32_t>(); - - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestChrono.cpp b/test/source/TestChrono.cpp deleted file mode 100644 index a56b934..0000000 --- a/test/source/TestChrono.cpp +++ /dev/null @@ -1,220 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EABase/eabase.h> -#include <EASTL/chrono.h> -#include <EASTL/numeric.h> -#include <EASTL/string.h> - - -using namespace eastl; -using namespace eastl::chrono; - - -////////////////////////////////////////////////////////////////////////////////////////////////// -// TestDuration -// -int TestDuration() -{ - int nErrorCount = 0; - - { - hours h{1}; // 1 hour - milliseconds ms{3}; // 3 milliseconds - duration<int, kilo> ks{3}; // 3000 seconds - - duration<double, ratio<1, 30>> hz30{3.5}; - microseconds us = ms; - duration<double, milli> ms2 = us; // 3.0 milliseconds - - EA_UNUSED(h); - EA_UNUSED(ms2); - EA_UNUSED(ks); - EA_UNUSED(hz30); - EA_UNUSED(us); - } - - { - typedef duration<double, ratio<1, 30>> dur_t; - VERIFY(dur_t::min() < dur_t::zero()); - VERIFY(dur_t::zero() < dur_t::max()); - VERIFY(dur_t::min() < dur_t::max()); - } - - { - seconds s1(10); - seconds s2 = -s1; - VERIFY(s1.count() == 10); - VERIFY(s2.count() == -10); - } - - { - { - hours h(1); - minutes m = ++h; - m--; - VERIFY(m.count() == 119); - } - - { - hours h(24); - minutes m = h; - seconds s = m; - milliseconds ms = s; - - VERIFY(h.count() == 24); - VERIFY(m.count() == 1440); - VERIFY(s.count() == 86400); - VERIFY(ms.count() == 86400000); - } - - { - minutes m(11); - m *= 2; - VERIFY(m.count() == 22); - m += hours(10); - VERIFY(m.count() == 622); - VERIFY(duration_cast<hours>(m).count() == 10); - m %= hours(1); - VERIFY(duration_cast<hours>(m).count() == 0); - VERIFY(m.count() == 22); - } - - { - milliseconds ms(3); // 3 milliseconds - VERIFY(ms.count() == 3); - - microseconds us = 2 * ms; // 6000 microseconds constructed from 3 milliseconds - VERIFY(us.count() == 6000); - - microseconds us2 = ms * 2; // 6000 microseconds constructed from 3 milliseconds - VERIFY(us2.count() == 6000); - - microseconds us3 = us / 2; - VERIFY(us3.count() == 3000); - - microseconds us4 = us % 2; - VERIFY(us4.count() == 0); - } - } - - return nErrorCount; -} - - -////////////////////////////////////////////////////////////////////////////////////////////////// -// TestTimePoint -// -int TestTimePoint() -{ - int nErrorCount = 0; - { - { - system_clock::time_point t0 = system_clock::now(); - auto tomorrow = t0 + hours(24); - auto today = tomorrow - system_clock::now(); - auto hours_count = duration_cast<hours>(today).count(); - - VERIFY(hours_count == 24 || hours_count == 23); // account for time flux - } - - { - time_point<system_clock, hours> hour1(hours(1)); - - auto hour_to_min = time_point_cast<minutes>(hour1); - auto hour_to_sec = time_point_cast<seconds>(hour1); - auto hour_to_millisec = time_point_cast<milliseconds>(hour1); - auto hour_to_microsec = time_point_cast<microseconds>(hour1); - auto hour_to_nanosec = time_point_cast<nanoseconds>(hour1); - - VERIFY(hour_to_min.time_since_epoch().count() == 60); - VERIFY(hour_to_sec.time_since_epoch().count() == 3600); - VERIFY(hour_to_millisec.time_since_epoch().count() == 3600000ll); - VERIFY(hour_to_microsec.time_since_epoch().count() == 3600000000ll); - VERIFY(hour_to_nanosec.time_since_epoch().count() == 3600000000000ll); - } - } - return nErrorCount; -} - - -////////////////////////////////////////////////////////////////////////////////////////////////// -// TestClocks -// -int TestClocks() -{ - int nErrorCount = 0; - { - { - auto sys = system_clock::now(); - VERIFY(sys.time_since_epoch().count() > 0); - - auto stdy = steady_clock::now(); - VERIFY(stdy.time_since_epoch().count() > 0); - - auto hrc = high_resolution_clock::now(); - VERIFY(hrc.time_since_epoch().count() > 0); - } - - { - auto start = system_clock::now(); - auto end = system_clock::now(); - auto d = end - start; - EA_UNUSED(d); - VERIFY(d.count() >= 0); - } - - { - auto start = steady_clock::now(); - auto end = steady_clock::now(); - auto d = end - start; - EA_UNUSED(d); - VERIFY(d.count() >= 0); - } - - { - auto start = high_resolution_clock::now(); - auto end = high_resolution_clock::now(); - auto d = end - start; - EA_UNUSED(d); - VERIFY(d.count() >= 0); - } - - { - typedef duration<int, ratio<1, 100000000>> shakes; - typedef duration<int, centi> jiffies; - typedef duration<float, ratio<12096, 10000>> microfortnights; - typedef duration<float, ratio<3155, 1000>> nanocenturies; - - seconds sec(1); - - VERIFY(duration_cast<shakes>(sec).count() == 100000000); - VERIFY(duration_cast<jiffies>(sec).count() == 100); - VERIFY(microfortnights(sec).count() > 0.82f); - VERIFY(nanocenturies(sec).count() > 0.31f); - } - } - return nErrorCount; -} - - -int TestChrono() -{ - int nErrorCount = 0; - nErrorCount += TestDuration(); - nErrorCount += TestTimePoint(); - nErrorCount += TestClocks(); - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestCppCXTypeTraits.cpp b/test/source/TestCppCXTypeTraits.cpp deleted file mode 100644 index ab03aa7..0000000 --- a/test/source/TestCppCXTypeTraits.cpp +++ /dev/null @@ -1,35 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/type_traits.h> - -using namespace eastl; - -#if defined(__cplusplus_winrt) - ref class Foo - { - - }; -#endif - -int TestCppCXTypeTraits() -{ - int nErrorCount = 0; - - // We can only build this code if C++/CX is enabled -#if defined(__cplusplus_winrt) - { - Foo^ foo = ref new Foo(); - static_assert(eastl::is_pod<Foo^>::value == false, "Ref types are not POD"); - static_assert(eastl::is_trivially_destructible<Foo^>::value == false, "Ref types cannot be trivially destructible"); - static_assert(eastl::is_trivially_constructible<Foo^>::value == false, "Ref types cannot be trivially constructible"); - static_assert(eastl::is_trivially_copy_constructible<Foo^>::value == false, "Ref types cannot be trivially copyable"); - static_assert(eastl::is_trivially_copy_assignable<Foo^>::value == false, "Ref types cannot be trivially copyable"); - } -#endif - - return nErrorCount; -} diff --git a/test/source/TestDeque.cpp b/test/source/TestDeque.cpp deleted file mode 100644 index e3f4ab6..0000000 --- a/test/source/TestDeque.cpp +++ /dev/null @@ -1,1146 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EABase/eabase.h> -#include <EASTL/deque.h> -#include <EASTL/list.h> -#include <EASTL/vector.h> -#include <EASTL/string.h> -#include <EASTL/algorithm.h> -#include <EASTL/unique_ptr.h> -#include "ConceptImpls.h" - -#if !defined(EA_COMPILER_NO_STANDARD_CPP_LIBRARY) - EA_DISABLE_ALL_VC_WARNINGS() - #include <deque> - #include <list> - #include <vector> - #include <algorithm> - #include <stdio.h> - EA_RESTORE_ALL_VC_WARNINGS() -#endif - - -using namespace eastl; - - - - -/////////////////////////////////////////////////////////////////////////////// -// DequeObject -// -struct DequeObject -{ - int mX; // Value for the DequeObject. - uint32_t mMagicValue; // - static int sDOCount; // Count of all current existing DequeObjects. - static int sMagicErrorCount; // Number of magic number mismatch errors. - - DequeObject(int x = 0) : mX(x), mMagicValue(kMagicValue) - { ++sDOCount; } - - DequeObject(const DequeObject& dequeObject) : mX(dequeObject.mX), mMagicValue(kMagicValue) - { ++sDOCount; } - - DequeObject& operator=(const DequeObject& dequeObject) - { - mX = dequeObject.mX; - return *this; - } - - ~DequeObject() - { - if(mMagicValue != kMagicValue) - ++sMagicErrorCount; - mMagicValue = 0; - --sDOCount; - } -}; - -int DequeObject::sDOCount = 0; -int DequeObject::sMagicErrorCount = 0; - - -bool operator==(const DequeObject& de1, const DequeObject& de2) - { return de1.mX == de2.mX; } - -bool operator<(const DequeObject& de1, const DequeObject& de2) - { return de1.mX < de2.mX; } -/////////////////////////////////////////////////////////////////////////////// - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::deque<int>; -template class eastl::deque<DequeObject>; - - -// Test compiler issue that appeared in VS2012 relating to deque::kAlignment. -struct StructWithContainerOfStructs -{ - eastl::deque<StructWithContainerOfStructs, EASTLAllocatorType, 16> children; -}; - -// The following will not compile because the default value of kDequeSubarraySize -// relies on sizeof(T). Thus, a non-default value must be provided, or the full type -// will be required at the time of instantiation, but it is not available. -// struct StructWithContainerOfStructsDefault -// { -// eastl::deque<StructWithContainerOfStructsDefault> children; -// }; - - -/////////////////////////////////////////////////////////////////////////////// -typedef eastl::deque<int> EIntDeque; -typedef eastl::deque<int, EASTLAllocatorType, 1> EIntDeque1; -typedef eastl::deque<int, EASTLAllocatorType, 32768> EIntDeque32768; - - -typedef eastl::deque<DequeObject> EDODeque; -typedef eastl::deque<DequeObject, EASTLAllocatorType, 1> EDODeque1; -typedef eastl::deque<DequeObject, EASTLAllocatorType, 32768> EDODeque32768; - - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - typedef std::deque<int> SIntDeque; - typedef std::deque<DequeObject> SDODeque; -#endif -/////////////////////////////////////////////////////////////////////////////// - - - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - -template <typename D1, typename D2> -int CompareDeques(const D1& d1, const D2& d2, const char* pTestName) -{ - int nErrorCount = 0; - - // Compare emptiness. - VERIFY(d1.empty() == d2.empty()); - - // Compare sizes. - const size_t nSize1 = d1.size(); - const size_t nSize2 = d2.size(); - - VERIFY(nSize1 == nSize2); - if(nSize1 != nSize2) - EASTLTest_Printf("%s: Deque size difference: %u, %u", pTestName, (unsigned)nSize1, (unsigned)nSize2); - - // Compare values. - if(nSize1 == nSize2) - { - // Test operator[] - for(unsigned i = 0; i < nSize1; i++) - { - const typename D1::value_type& t1 = d1[i]; - const typename D2::value_type& t2 = d2[i]; - - VERIFY(t1 == t2); - if(!(t1 == t2)) - { - EASTLTest_Printf("%s: Deque index difference at index %d", pTestName, i); - break; - } - } - - // Test iteration - typename D1::const_iterator it1 = d1.begin(); - typename D2::const_iterator it2 = d2.begin(); - - for(unsigned j = 0; it1 != d1.end(); ++it1, ++it2, ++j) - { - const typename D1::value_type& t1 = *it1; - const typename D2::value_type& t2 = *it2; - - VERIFY(t1 == t2); - if(!(t1 == t2)) - { - EASTLTest_Printf("%s: Deque iterator difference at index %d", pTestName, j); - break; - } - } - - // Test reverse iteration - typename D1::const_reverse_iterator itr1 = d1.rbegin(); - typename D2::const_reverse_iterator itr2 = d2.rbegin(); - - for(typename D1::size_type j = d1.size() - 1; itr1 != d1.rend(); ++itr1, ++itr2, --j) - { - const typename D1::value_type& t1 = *itr1; - const typename D2::value_type& t2 = *itr2; - - VERIFY(t1 == t2); - if(!(t1 == t2)) - { - EASTLTest_Printf("%s: Deque reverse iterator difference at index %u", pTestName, (unsigned)j); - break; - } - } - } - - return nErrorCount; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// TestDequeConstruction -// -template <typename D1, typename D2> -int TestDequeConstruction() -{ - int nErrorCount = 0; - - { - D1 d1A; - D2 d2A; - nErrorCount += CompareDeques(d1A, d2A, "Deque ctor"); - - D1 d1B((typename D1::size_type)0); - D2 d2B((typename D2::size_type)0); - nErrorCount += CompareDeques(d1B, d2B, "Deque ctor"); - - D1 d1C(1000); - D2 d2C(1000); - nErrorCount += CompareDeques(d1C, d2C, "Deque ctor"); - - D1 d1D(2000, 1); - D2 d2D(2000, 1); - nErrorCount += CompareDeques(d1D, d2D, "Deque ctor"); - - D1 d1E(d1C); - D2 d2E(d2C); - nErrorCount += CompareDeques(d1E, d2E, "Deque ctor"); - - D1 d1F(d1C.begin(), d1C.end()); - D2 d2F(d2C.begin(), d2C.end()); - nErrorCount += CompareDeques(d1F, d2F, "Deque ctor"); - - // operator= - d1E = d1D; - d2E = d2D; - nErrorCount += CompareDeques(d1D, d2D, "Deque operator="); - nErrorCount += CompareDeques(d1E, d2E, "Deque operator="); - - // swap - d1E.swap(d1D); - d2E.swap(d2D); - nErrorCount += CompareDeques(d1D, d2D, "Deque swap"); - nErrorCount += CompareDeques(d1E, d2E, "Deque swap"); - - // clear - d1A.clear(); - d2A.clear(); - nErrorCount += CompareDeques(d1A, d2A, "Deque clear"); - - d1B.clear(); - d2B.clear(); - nErrorCount += CompareDeques(d1B, d2B, "Deque clear"); - } - - VERIFY(DequeObject::sDOCount == 0); - VERIFY(DequeObject::sMagicErrorCount == 0); - - return nErrorCount; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// TestDequeSimpleMutation -// -template <typename D1, typename D2> -int TestDequeSimpleMutation() -{ - int nErrorCount = 0; - - { - D1 d1; - D2 d2; - - // push_back(value_type&) - // front - // back - for(int i = 0; i < 1000; i++) - { - d1.push_back(i); - d2.push_back(i); - VERIFY(d1.front() == d2.front()); - VERIFY(d1.back() == d2.back()); - } - nErrorCount += CompareDeques(d1, d2, "Deque push_back(value_type&)"); - - // operator[] - // at() - for(typename D1::size_type i = 0, iEnd = d1.size(); i < iEnd; i++) - { - VERIFY(d1[(unsigned)i] == d2[(unsigned)i]); - VERIFY(d1.at((unsigned)i) == d2.at((unsigned)i)); - } - - // push_back() - for(int i = 0; i < 1000; i++) - { - d1.push_back(int()); - typename D2::value_type& ref = d2.push_back(); // d2 here must be the EASTL version. - VERIFY(d1.front() == d2.front()); - VERIFY(d1.back() == d2.back()); - VERIFY(&ref == &d2.back()); - } - nErrorCount += CompareDeques(d1, d2, "Deque push_back()"); - - // operator[] - // at() - for(typename D1::size_type i = 0, iEnd = d1.size(); i < iEnd; i++) - { - VERIFY(d1[(unsigned)i] == d2[(unsigned)i]); - VERIFY(d1.at((unsigned)i) == d2.at((unsigned)i)); - } - - // push_front(value_type&) - for(int i = 0; i < 1000; i++) - { - d1.push_front(i); - d2.push_front(i); - VERIFY(d1.front() == d2.front()); - VERIFY(d1.back() == d2.back()); - } - nErrorCount += CompareDeques(d1, d2, "Deque push_front(value_type&)"); - - // operator[] - // at() - for(typename D1::size_type i = 0, iEnd = d1.size(); i < iEnd; i++) - { - VERIFY(d1[(unsigned)i] == d2[(unsigned)i]); - VERIFY(d1.at((unsigned)i) == d2.at((unsigned)i)); - } - - // push_front() - for(int i = 0; i < 1000; i++) - { - d1.push_front(int()); - typename D2::value_type& ref = d2.push_front(); - VERIFY(d1.front() == d2.front()); - VERIFY(d1.back() == d2.back()); - VERIFY(&ref == &d2.front()); - } - nErrorCount += CompareDeques(d1, d2, "Deque push_front()"); - - // operator[] - // at() - for(typename D1::size_type i = 0, iEnd = d1.size(); i < iEnd; i++) - { - VERIFY(d1[(unsigned)i] == d2[(unsigned)i]); - VERIFY(d1.at((unsigned)i) == d2.at((unsigned)i)); - } - - // pop_back() - for(int i = 0; i < 500; i++) - { - d1.pop_back(); - d2.pop_back(); - VERIFY(d1.front() == d2.front()); - VERIFY(d1.back() == d2.back()); - } - nErrorCount += CompareDeques(d1, d2, "Deque pop_back()"); - - // operator[] - // at() - for(typename D1::size_type i = 0, iEnd = d1.size(); i < iEnd; i++) - { - VERIFY(d1[(unsigned)i] == d2[(unsigned)i]); - VERIFY(d1.at((unsigned)i) == d2.at((unsigned)i)); - } - - // pop_front() - for(int i = 0; i < 500; i++) - { - d1.pop_front(); - d2.pop_front(); - VERIFY(d1.front() == d2.front()); - VERIFY(d1.back() == d2.back()); - } - nErrorCount += CompareDeques(d1, d2, "Deque pop_front()"); - - // operator[] - // at() - for(typename D1::size_type i = 0, iEnd = d1.size(); i < iEnd; i++) - { - VERIFY(d1[(unsigned)i] == d2[(unsigned)i]); - VERIFY(d1.at((unsigned)i) == d2.at((unsigned)i)); - } - - // resize(value_type&) - for(int i = 0; i < 500; i++) - { - d1.resize(d1.size() + 3, i); - d2.resize(d2.size() + 3, i); - VERIFY(d1.front() == d2.front()); - VERIFY(d1.back() == d2.back()); - } - nErrorCount += CompareDeques(d1, d2, "Deque resize(value_type&)"); - - // operator[] - // at() - for(typename D1::size_type i = 0, iEnd = d1.size(); i < iEnd; i++) - { - VERIFY(d1[(unsigned)i] == d2[(unsigned)i]); - VERIFY(d1.at((unsigned)i) == d2.at((unsigned)i)); - } - - // resize() - for(int i = 0; i < 500; i++) - { - d1.resize(d1.size() - 2); - d2.resize(d2.size() - 2); - VERIFY(d1.front() == d2.front()); - VERIFY(d1.back() == d2.back()); - } - nErrorCount += CompareDeques(d1, d2, "Deque resize()"); - - // operator[] - // at() - for(typename D1::size_type i = 0, iEnd = d1.size(); i < iEnd; i++) - { - VERIFY(d1[(unsigned)i] == d2[(unsigned)i]); - VERIFY(d1.at((unsigned)i) == d2.at((unsigned)i)); - } - } - - VERIFY(DequeObject::sDOCount == 0); - VERIFY(DequeObject::sMagicErrorCount == 0); - - return nErrorCount; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// TestDequeComplexMutation -// -template <typename D1, typename D2> -int TestDequeComplexMutation() -{ - int nErrorCount = 0; - - { - D1 d1; - D2 d2; - - - ////////////////////////////////////////////////////////////////// - // void assign(size_type n, const value_type& value); - ////////////////////////////////////////////////////////////////// - - d1.assign(100, 1); - d2.assign(100, 1); - nErrorCount += CompareDeques(d1, d2, "Deque assign(size_type n, const value_type& value)"); - - d1.assign(50, 2); - d2.assign(50, 2); - nErrorCount += CompareDeques(d1, d2, "Deque assign(size_type n, const value_type& value)"); - - d1.assign(150, 2); - d2.assign(150, 2); - nErrorCount += CompareDeques(d1, d2, "Deque assign(size_type n, const value_type& value)"); - - - - ////////////////////////////////////////////////////////////////// - // template <typename InputIterator> - // void assign(InputIterator first, InputIterator last); - ////////////////////////////////////////////////////////////////// - - std::list<int> intList1; - for(int i = 0; i < 100; i++) - intList1.push_back(i); - - eastl::list<int> intList2; - for(int i = 0; i < 100; i++) - intList2.push_back(i); - - d1.assign(intList1.begin(), intList1.end()); - d2.assign(intList2.begin(), intList2.end()); - nErrorCount += CompareDeques(d1, d2, "Deque assign(InputIterator first, InputIterator last)"); - - - - ////////////////////////////////////////////////////////////////// - // iterator insert(iterator position, const value_type& value); - ////////////////////////////////////////////////////////////////// - - d1.insert(d1.begin(), d1[1]); - d2.insert(d2.begin(), d2[1]); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, const value_type& value)"); - - d1.insert(d1.end(), d1[d1.size() - 2]); - d2.insert(d2.end(), d2[d2.size() - 2]); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, const value_type& value)"); - - typename D1::iterator itD1NearBegin = d1.begin(); - typename D2::iterator itD2NearBegin = d2.begin(); - - std::advance(itD1NearBegin, 1); - eastl::advance(itD2NearBegin, 1); - - d1.insert(itD1NearBegin, d1[3]); - d2.insert(itD2NearBegin, d2[3]); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, const value_type& value)"); - - typename D1::iterator itD1NearEnd = d1.begin(); - typename D2::iterator itD2NearEnd = d2.begin(); - - std::advance(itD1NearEnd, d1.size() - 1); - eastl::advance(itD2NearEnd, d2.size() - 1); - - d1.insert(itD1NearEnd, d1[d1.size() - 2]); - d2.insert(itD2NearEnd, d2[d2.size() - 2]); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, const value_type& value)"); - - - ////////////////////////////////////////////////////////////////// - // void insert(iterator position, size_type n, const value_type& value); - ////////////////////////////////////////////////////////////////// - - d1.insert(d1.begin(), d1.size() * 2, 3); // Insert a large number of items at the front. - d2.insert(d2.begin(), d2.size() * 2, 3); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, size_type n, const value_type& value)"); - - d1.insert(d1.end(), d1.size() * 2, 3); // Insert a large number of items at the end. - d2.insert(d2.end(), d2.size() * 2, 3); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, size_type n, const value_type& value)"); - - itD1NearBegin = d1.begin(); - itD2NearBegin = d2.begin(); - - std::advance(itD1NearBegin, 3); - eastl::advance(itD2NearBegin, 3); - - d1.insert(itD1NearBegin, 3, 4); - d2.insert(itD2NearBegin, 3, 4); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, size_type n, const value_type& value)"); - - itD1NearEnd = d1.begin(); - itD2NearEnd = d2.begin(); - - std::advance(itD1NearEnd, d1.size() - 1); - eastl::advance(itD2NearEnd, d2.size() - 1); - - d1.insert(d1.end(), 5, 6); - d2.insert(d2.end(), 5, 6); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, size_type n, const value_type& value)"); - - - - ////////////////////////////////////////////////////////////////// - // template <typename InputIterator> - // void insert(iterator position, InputIterator first, InputIterator last); - ////////////////////////////////////////////////////////////////// - - itD1NearBegin = d1.begin(); - itD2NearBegin = d2.begin(); - - std::advance(itD1NearBegin, 3); - eastl::advance(itD2NearBegin, 3); - - d1.insert(itD1NearBegin, intList1.begin(), intList1.end()); - d2.insert(itD2NearBegin, intList2.begin(), intList2.end()); - nErrorCount += CompareDeques(d1, d2, "Deque insert(iterator position, InputIterator first, InputIterator last)"); - - - - ////////////////////////////////////////////////////////////////// - // iterator erase(iterator position); - ////////////////////////////////////////////////////////////////// - - itD1NearBegin = d1.begin(); - itD2NearBegin = d2.begin(); - - while(itD1NearBegin != d1.end()) // Run a loop whereby we erase every third element. - { - for(int i = 0; (i < 3) && (itD1NearBegin != d1.end()); ++i) - { - ++itD1NearBegin; - ++itD2NearBegin; - } - - if(itD1NearBegin != d1.end()) - { - itD1NearBegin = d1.erase(itD1NearBegin); - itD2NearBegin = d2.erase(itD2NearBegin); - nErrorCount += CompareDeques(d1, d2, "Deque erase(iterator position)"); - } - } - - - ////////////////////////////////////////////////////////////////// - // iterator erase(iterator first, iterator last); - ////////////////////////////////////////////////////////////////// - - itD1NearBegin = d1.begin(); - itD2NearBegin = d2.begin(); - - while(itD1NearBegin != d1.end()) // Run a loop whereby we erase spans of elements. - { - typename D1::iterator itD1Saved = itD1NearBegin; - typename D2::iterator itD2Saved = itD2NearBegin; - - for(int i = 0; (i < 11) && (itD1NearBegin != d1.end()); ++i) - { - ++itD1NearBegin; - ++itD2NearBegin; - } - - if(itD1NearBegin != d1.end()) - { - itD1NearBegin = d1.erase(itD1Saved, itD1NearBegin); - itD2NearBegin = d2.erase(itD2Saved, itD2NearBegin); - nErrorCount += CompareDeques(d1, d2, "Deque erase(iterator position)"); - } - - for(int i = 0; (i < 17) && (itD1NearBegin != d1.end()); ++i) - { - ++itD1NearBegin; - ++itD2NearBegin; - } - - } - - } - - - { - ////////////////////////////////////////////////////////////////// - // reverse_iterator erase(reverse_iterator position); - // reverse_iterator erase(reverse_iterator first, reverse_iterator last); - ////////////////////////////////////////////////////////////////// - - //D1 d1Erase; - D2 d2Erase; - - for(int i = 0; i < 20; i++) - { - typename D2::value_type val(i); - d2Erase.push_back(val); - } - VERIFY((d2Erase.size() == 20) && (d2Erase[0] == 0) && (d2Erase[19] == 19)); - - - typename D2::reverse_iterator r2A = d2Erase.rbegin(); - typename D2::reverse_iterator r2B = r2A + 3; - d2Erase.erase(r2A, r2B); - VERIFY((d2Erase.size() == 17)); - VERIFY((d2Erase[0] == 0)); - VERIFY((d2Erase[16] == 16)); - - - r2B = d2Erase.rend(); - r2A = r2B - 3; - d2Erase.erase(r2A, r2B); - VERIFY((d2Erase.size() == 14)); - VERIFY((d2Erase[0] == 3)); - VERIFY((d2Erase[13] == 16)); - - - r2B = d2Erase.rend() - 1; - d2Erase.erase(r2B); - VERIFY((d2Erase.size() == 13)); - VERIFY((d2Erase[0] == 4)); - VERIFY((d2Erase[12] == 16)); - - - r2B = d2Erase.rbegin(); - d2Erase.erase(r2B); - VERIFY((d2Erase.size() == 12)); - VERIFY((d2Erase[0] == 4)); - VERIFY((d2Erase[11] == 15)); - - - r2A = d2Erase.rbegin(); - r2B = d2Erase.rend(); - d2Erase.erase(r2A, r2B); - VERIFY(d2Erase.size() == 0); - } - - - VERIFY(DequeObject::sDOCount == 0); - VERIFY(DequeObject::sMagicErrorCount == 0); - - return nErrorCount; -} - -#endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - -int TestDeque() -{ - int nErrorCount = 0; - - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - { // Test construction - nErrorCount += TestDequeConstruction<SIntDeque, EIntDeque>(); - nErrorCount += TestDequeConstruction<SIntDeque, EIntDeque1>(); - nErrorCount += TestDequeConstruction<SIntDeque, EIntDeque32768>(); - - nErrorCount += TestDequeConstruction<SIntDeque, EDODeque>(); - nErrorCount += TestDequeConstruction<SIntDeque, EDODeque1>(); - nErrorCount += TestDequeConstruction<SIntDeque, EDODeque32768>(); - } - - - { // Test simple mutating functionality. - nErrorCount += TestDequeSimpleMutation<SIntDeque, EIntDeque>(); - nErrorCount += TestDequeSimpleMutation<SIntDeque, EIntDeque1>(); - nErrorCount += TestDequeSimpleMutation<SIntDeque, EIntDeque32768>(); - - nErrorCount += TestDequeSimpleMutation<SIntDeque, EDODeque>(); - nErrorCount += TestDequeSimpleMutation<SIntDeque, EDODeque1>(); - nErrorCount += TestDequeSimpleMutation<SIntDeque, EDODeque32768>(); - } - - { // Test complex mutating functionality. - nErrorCount += TestDequeComplexMutation<SIntDeque, EIntDeque>(); - nErrorCount += TestDequeComplexMutation<SIntDeque, EIntDeque1>(); - nErrorCount += TestDequeComplexMutation<SIntDeque, EIntDeque32768>(); - - nErrorCount += TestDequeComplexMutation<SIntDeque, EDODeque>(); - nErrorCount += TestDequeComplexMutation<SIntDeque, EDODeque1>(); - nErrorCount += TestDequeComplexMutation<SIntDeque, EDODeque32768>(); - } - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - // test deque support of move-only types - { - { - eastl::deque<MoveAssignable> d; - d.emplace_back(MoveAssignable::Create()); - d.emplace_front(MoveAssignable::Create()); - - auto cd = eastl::move(d); - EATEST_VERIFY( d.size() == 0); - EATEST_VERIFY(cd.size() == 2); - } - - { - // User regression but passing end() to deque::erase is not valid. - // Iterator passed to deque::erase but must valid and dereferencable. - // - // eastl::deque<MoveAssignable> d; // empty deque - // d.erase(d.begin()); - // EATEST_VERIFY(d.size() == 0); - } - - // simply test the basic api of deque with a move-only type - { - eastl::deque<MoveAssignable> d; - - // emplace_back - d.emplace_back(MoveAssignable::Create()); - d.emplace_back(MoveAssignable::Create()); - d.emplace_back(MoveAssignable::Create()); - - // erase - d.erase(d.begin()); - EATEST_VERIFY(d.size() == 2); - - // at / front / back / operator[] - EATEST_VERIFY(d[0].value == 42); - EATEST_VERIFY(d.at(0).value == 42); - EATEST_VERIFY(d.front().value == 42); - EATEST_VERIFY(d.back().value == 42); - - // clear - d.clear(); - EATEST_VERIFY(d.size() == 0); - - // emplace - d.emplace(d.begin(), MoveAssignable::Create()); - d.emplace(d.begin(), MoveAssignable::Create()); - EATEST_VERIFY(d.size() == 2); - - // pop_back - d.pop_back(); - EATEST_VERIFY(d.size() == 1); - - // push_back / push_front / resize requires T be 'CopyConstructible' - - { - eastl::deque<MoveAssignable> swapped_d; - - // emplace_front - swapped_d.emplace_front(MoveAssignable::Create()); - swapped_d.emplace_front(MoveAssignable::Create()); - swapped_d.emplace_front(MoveAssignable::Create()); - - // swap - swapped_d.swap(d); - EATEST_VERIFY(swapped_d.size() == 1); - EATEST_VERIFY(d.size() == 3); - } - - // pop_front - d.pop_front(); - EATEST_VERIFY(d.size() == 2); - - // insert - d.insert(d.end(), MoveAssignable::Create()); - EATEST_VERIFY(d.size() == 3); - } - } - - { - // deque(std::initializer_list<value_type> ilist, const allocator_type& allocator = EASTL_DEQUE_DEFAULT_ALLOCATOR); - // this_type& operator=(std::initializer_list<value_type> ilist); - // void assign(std::initializer_list<value_type> ilist); - // iterator insert(iterator position, std::initializer_list<value_type> ilist); - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - eastl::deque<int> intDeque = { 0, 1, 2 }; - EATEST_VERIFY(VerifySequence(intDeque.begin(), intDeque.end(), int(), "deque std::initializer_list", 0, 1, 2, -1)); - - intDeque = { 13, 14, 15 }; - EATEST_VERIFY(VerifySequence(intDeque.begin(), intDeque.end(), int(), "deque std::initializer_list", 13, 14, 15, -1)); - - intDeque.assign({ 16, 17, 18 }); - EATEST_VERIFY(VerifySequence(intDeque.begin(), intDeque.end(), int(), "deque std::initializer_list", 16, 17, 18, -1)); - - eastl::deque<int>::iterator it = intDeque.insert(intDeque.begin(), { 14, 15 }); - EATEST_VERIFY(VerifySequence(intDeque.begin(), intDeque.end(), int(), "deque std::initializer_list", 14, 15, 16, 17, 18, -1)); - EATEST_VERIFY(*it == 14); - #endif - } - - - { // C++11 functionality - // deque(this_type&& x); - // deque(this_type&& x, const allocator_type& allocator); - // this_type& operator=(this_type&& x); - // void push_front(value_type&& value); - // void push_back(value_type&& value); - // iterator insert(const_iterator position, value_type&& value); - - using namespace eastl; - - deque<TestObject> deque3TO33(3, TestObject(33)); - deque<TestObject> toDequeA(eastl::move(deque3TO33)); - EATEST_VERIFY((toDequeA.size() == 3) && (toDequeA.front().mX == 33) && (deque3TO33.size() == 0)); - - // The following is not as strong a test of this ctor as it could be. A stronger test would be to use IntanceAllocator with different instances. - deque<TestObject, MallocAllocator> deque4TO44(4, TestObject(44)); - deque<TestObject, MallocAllocator> toDequeB(eastl::move(deque4TO44), MallocAllocator()); - EATEST_VERIFY((toDequeB.size() == 4) && (toDequeB.front().mX == 44) && (deque4TO44.size() == 0)); - - deque<TestObject, MallocAllocator> deque5TO55(5, TestObject(55)); - toDequeB = eastl::move(deque5TO55); - EATEST_VERIFY((toDequeB.size() == 5) && (toDequeB.front().mX == 55) && (deque5TO55.size() == 0)); - } - - - { // C++11 functionality - // template<class... Args> - // iterator emplace(const_iterator position, Args&&... args); - - // template<class... Args> - // void emplace_front(Args&&... args); - - // template<class... Args> - // void emplace_back(Args&&... args); - TestObject::Reset(); - - deque<TestObject, eastl::allocator, 16> toDequeA; - - toDequeA.emplace_back(2, 3, 4); - EATEST_VERIFY_F((toDequeA.size() == 1) && (toDequeA.back().mX == (2+3+4)) && (TestObject::sTOCtorCount == 1), "size: %u, mX: %u, count: %d", (unsigned)toDequeA.size(), (unsigned)toDequeA.back().mX, (int)TestObject::sTOCtorCount); - - toDequeA.emplace(toDequeA.begin(), 3, 4, 5); // This is 3 because of how subarray allocation works. - EATEST_VERIFY_F((toDequeA.size() == 2) && (toDequeA.front().mX == (3+4+5)) && (TestObject::sTOCtorCount == 3), "size: %u, mX: %u, count: %d", (unsigned)toDequeA.size(), (unsigned)toDequeA.front().mX, (int)TestObject::sTOCtorCount); - - toDequeA.emplace_front(6, 7, 8); - EATEST_VERIFY_F((toDequeA.size() == 3) && (toDequeA.front().mX == (6+7+8)) && (TestObject::sTOCtorCount == 4), "size: %u, mX: %u, count: %d", (unsigned)toDequeA.size(), (unsigned)toDequeA.front().mX, (int)TestObject::sTOCtorCount); - - - // This test is similar to the emplace pathway above. - TestObject::Reset(); - - //void push_front(T&& x); - //void push_back(T&& x); - //iterator insert(const_iterator position, T&& x); - - deque<TestObject, eastl::allocator, 16> toDequeC; // Specify a non-small kSubarrayCount of 16 because the move count tests below assume there is no reallocation. - - toDequeC.push_back(TestObject(2, 3, 4)); - EATEST_VERIFY((toDequeC.size() == 1) && (toDequeC.back().mX == (2+3+4)) && (TestObject::sTOMoveCtorCount == 1)); - - toDequeC.insert(toDequeC.begin(), TestObject(3, 4, 5)); - EATEST_VERIFY((toDequeC.size() == 2) && (toDequeC.front().mX == (3+4+5)) && (TestObject::sTOMoveCtorCount == 3)); - - toDequeC.push_front(TestObject(6, 7, 8)); - EATEST_VERIFY((toDequeC.size() == 3) && (toDequeC.front().mX == (6+7+8)) && (TestObject::sTOMoveCtorCount == 4)); - } - - - { - // Regression of deque::operator= for the case of EASTL_ALLOCATOR_COPY_ENABLED=1 - // For this test we need to use InstanceAllocator to create two containers of the same - // type but with different and unequal allocator instances. The bug was that when - // EASTL_ALLOCATOR_COPY_ENABLED was enabled operator=(this_type& x) assigned x.mAllocator - // to this and then proceeded to assign member elements from x to this. That's invalid - // because the existing elements of this were allocated by a different allocator and - // will be freed in the future with the allocator copied from x. - // The test below should work for the case of EASTL_ALLOCATOR_COPY_ENABLED == 0 or 1. - InstanceAllocator::reset_all(); - - InstanceAllocator ia0((uint8_t)0); - InstanceAllocator ia1((uint8_t)1); - - eastl::deque<int, InstanceAllocator> v0((eastl_size_t)1, (int)0, ia0); - eastl::deque<int, InstanceAllocator> v1((eastl_size_t)1, (int)1, ia1); - - EATEST_VERIFY((v0.front() == 0) && (v1.front() == 1)); - #if EASTL_ALLOCATOR_COPY_ENABLED - EATEST_VERIFY(v0.get_allocator() != v1.get_allocator()); - #endif - v0 = v1; - EATEST_VERIFY((v0.front() == 1) && (v1.front() == 1)); - EATEST_VERIFY(InstanceAllocator::mMismatchCount == 0); - EATEST_VERIFY(v0.validate()); - EATEST_VERIFY(v1.validate()); - #if EASTL_ALLOCATOR_COPY_ENABLED - EATEST_VERIFY(v0.get_allocator() == v1.get_allocator()); - #endif - } - - - { // Regression of kDequeSubarraySize calculations - VERIFY(EIntDeque::kSubarraySize >= 4); - VERIFY(EIntDeque1::kSubarraySize == 1); - VERIFY(EIntDeque32768::kSubarraySize == 32768); - - VERIFY(EDODeque::kSubarraySize >= 2); - VERIFY(EDODeque1::kSubarraySize == 1); - VERIFY(EDODeque32768::kSubarraySize == 32768); - } - - - { // Regression of user-reported bug - - // The following was reported by Nicolas Mercier on April 9, 2008 as causing a crash: - // This code breaks on our machines because it overwrites the - // first 4 bytes before the beginning of the memory that was - // allocated for mpPtrArray. So when temp goes out of scope, - // it will free this pointer and the debug allocator will detect - // that these bytes have been changed. - - eastl::deque<eastl::string> testArray; - eastl::string s("a"); - - for(int j = 0; j < 65; j++) - testArray.push_back(s); - - eastl::deque<eastl::string> temp; - temp = testArray; // This is where the corruption occurred. - } - - - { // Regression of user-reported bug - - // The problem is that the pointer arrays on the deques are growing without bound. - // This is causing our game to crash on a soak test due to its frame event queues - // consuming inordinate amounts of memory. It looks like the current version of - // eastl::deque is missing logic to recenter the pointer array, so it keeps growing - // slowly as blocks are allocated on the tail and removed from the head. - // Note: This bug was introduced by the (mistaken) fix for April 9 bug above. - - eastl::deque<int, MallocAllocator> x; - eastl::deque<int, MallocAllocator> y; - - const MallocAllocator& maX = x.get_allocator(); - const MallocAllocator& maY = y.get_allocator(); - - size_t allocVolumeX1 = 0; - size_t allocVolumeY1 = 0; - size_t allocVolumeX2 = 0; - size_t allocVolumeY2 = 0; - - for(int i = 0; i < 1001; ++i) // With the bug, each time through this loop the containers mistakenly allocate more memory. - { - if(i == 100) // Save the allocated volume after 50 iterations. - { - allocVolumeX1 = maX.mAllocVolume; - allocVolumeY1 = maY.mAllocVolume; - } - - for(int j = 0; j < 5; ++j) - x.push_back(0); - - x.swap(y); - - while(!x.empty()) - x.pop_front(); - } - - allocVolumeX2 = maX.mAllocVolume; // Save the allocated volume after 1001 iterations. - allocVolumeY2 = maY.mAllocVolume; - - VERIFY((allocVolumeX1 == allocVolumeX2) && (allocVolumeX2 < 350)); // Test that the volume has not changed and is below some nominal value. - VERIFY((allocVolumeY1 == allocVolumeY2) && (allocVolumeY2 < 350)); // This value is somewhat arbitrary and slightly hardware dependent (e.g. 32 vs. 64 bit). I bumped it up from 300 to 350 when Linux64 showed it to be 320, which was ~still OK. - } - - - { // Regression of user error report for the case of deque<const type>. - eastl::vector<int> ctorValues; - - for(int v = 0; v < 10; v++) - ctorValues.push_back(v); - - eastl::deque<const ConstType> testStruct(ctorValues.begin(), ctorValues.end()); - eastl::deque<const int> testInt(ctorValues.begin(), ctorValues.end()); - } - - - { // Regression to verify that const deque works. - const eastl::deque<int> constIntDeque1; - VERIFY(constIntDeque1.empty()); - - int intArray[3] = { 37, 38, 39 }; - const eastl::deque<int> constIntDeque2(intArray, intArray + 3); - VERIFY(constIntDeque2.size() == 3); - - const eastl::deque<int> constIntDeque3(4, 37); - VERIFY(constIntDeque3.size() == 4); - - const eastl::deque<int> constIntDeque4; - const eastl::deque<int> constIntDeque5 = constIntDeque4; - } - - { - // test shrink_to_fit - eastl::deque<int, CountingAllocator> d(4096); - d.erase(d.begin(), d.end()); - - auto prev = d.get_allocator().getActiveAllocationSize(); - d.shrink_to_fit(); - VERIFY(d.get_allocator().getActiveAllocationSize() < prev); - } - - { - #ifndef EASTL_OPENSOURCE - auto prevAllocCount = gEASTLTest_AllocationCount; - #endif - { - EA_DISABLE_VC_WARNING(4625 4626) - struct a - { - a(int* p) - : ptr(p) { } - - eastl::unique_ptr<int> ptr; - }; - EA_RESTORE_VC_WARNING() - - static_assert(eastl::has_trivial_relocate<a>::value == false, "failure"); - - eastl::deque<a> d; - - d.emplace_back(new int(1)); - d.emplace_back(new int(2)); - d.emplace_back(new int(3)); - - d.erase(d.begin() + 1); - } - #ifndef EASTL_OPENSOURCE - VERIFY(gEASTLTest_AllocationCount == prevAllocCount); - #endif - } - - - { // Test erase / erase_if - { - eastl::deque<int> d = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto numErased = eastl::erase(d, 2); - VERIFY((d == eastl::deque<int>{1, 3, 4, 5, 6, 7, 8, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase(d, 7); - VERIFY((d == eastl::deque<int>{1, 3, 4, 5, 6, 8, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase(d, 9); - VERIFY((d == eastl::deque<int>{1, 3, 4, 5, 6, 8})); - VERIFY(numErased == 1); - - numErased = eastl::erase(d, 5); - VERIFY((d == eastl::deque<int>{1, 3, 4, 6, 8})); - VERIFY(numErased == 1); - - numErased = eastl::erase(d, 3); - VERIFY((d == eastl::deque<int>{1, 4, 6, 8})); - VERIFY(numErased == 1); - } - - { - eastl::deque<int> d = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - auto numErased = eastl::erase_if(d, [](auto i) { return i % 2 == 0; }); - VERIFY((d == eastl::deque<int>{1, 3, 5, 7, 9})); - VERIFY(numErased == 4); - } - } - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - - { // Test <=> - eastl::deque<int> d1 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::deque<int> d2 = {9, 8, 7, 6, 5, 4, 3, 2, 1}; - eastl::deque<int> d3 = {1, 2, 3, 4, 5}; - eastl::deque<int> d4 = {10}; - - VERIFY(d1 != d2); - VERIFY(d1 < d2); - VERIFY(d1 != d3); - VERIFY(d1 > d3); - VERIFY(d4 > d1); - VERIFY(d4 > d2); - VERIFY(d4 > d3); - - VERIFY((d1 <=> d2) != 0); - VERIFY((d1 <=> d2) < 0); - VERIFY((d1 <=> d3) != 0); - VERIFY((d1 <=> d3) > 0); - VERIFY((d4 <=> d1) > 0); - VERIFY((d4 <=> d2) > 0); - VERIFY((d4 <=> d3) > 0); - } -#endif - - return nErrorCount; -} - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/source/TestExtra.cpp b/test/source/TestExtra.cpp deleted file mode 100644 index 52fbd62..0000000 --- a/test/source/TestExtra.cpp +++ /dev/null @@ -1,1554 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// Test forward delcarations -///////////////////////////////////////////////////////////////////////////// - -namespace eastl -{ - class allocator; - - template <typename T, typename Allocator> class basic_string; - typedef basic_string<char, allocator> local_string8; // collides with eastl::string8 in bulkbuilds - - template <typename T> struct local_less {}; - - static void UseForwardDeclaredString(local_string8*) - { - } - - - template <typename T, typename Allocator> class vector; - typedef vector<char, allocator> vector8; - - static void UseForwardDeclaredVector(vector8*) - { - } - - - template <typename Value, typename Hash, typename Predicate, typename Allocator, bool bCacheHashCode> class hash_set; - typedef hash_set<char, char, local_less<char>, allocator, false> hash_set8; - - static void UseForwardDeclaredHashSet(hash_set8*) - { - } - - - template <typename Key, typename T, typename Compare, typename Allocator> class map; - typedef map<char, char, local_less<char>, allocator> map8; - - static void UseForwardDeclaredMap(map8*) - { - } -} - - -#include "EASTLTest.h" -#include <EASTL/functional.h> -#include <EASTL/utility.h> -#include <EASTL/memory.h> -#include <EASTL/allocator.h> -#include <EASTL/allocator_malloc.h> -#include <EASTL/fixed_allocator.h> -#include <EASTL/intrusive_list.h> -#include <EASTL/numeric.h> -#include <EASTL/queue.h> -#include <EASTL/priority_queue.h> -#include <EASTL/stack.h> -#include <EASTL/heap.h> -#include <EASTL/vector.h> -#include <EASTL/deque.h> -#include <EASTL/list.h> -#include <EASTL/map.h> -#include <EASTL/string.h> -#include <EASTL/hash_set.h> -#include <EASTL/random.h> -#include <EASTL/bit.h> -#include <EASTL/core_allocator_adapter.h> -#include <EASTL/bonus/call_traits.h> -#include <EASTL/bonus/compressed_pair.h> -#include <EASTL/bonus/adaptors.h> -#include <EAStdC/EAAlignment.h> -#include <EAStdC/EAMemory.h> -#include <EAStdC/EAString.h> - -#ifdef _MSC_VER - #pragma warning(push, 0) -#endif - -#include <stdio.h> -#include <string.h> - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <algorithm> - #include <utility> - #include <stack> - #include <queue> - #include <vector> - #include <deque> - #include <math.h> -#endif - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - - -using namespace eastl; - - - -namespace -{ - /// IntNode - /// - /// Test intrusive_list node. - /// - struct IntNode : public eastl::intrusive_list_node - { - int mX; - - IntNode(int x = 0) - : mX(x) { } - - operator int() const - { return mX; } - }; - - bool operator<(const IntNode& a, const IntNode& b) - { return a.mX < b.mX; } -} - - - - - - -struct TestClass -{ - mutable int mX; - - TestClass() : mX(37) { } - - void Increment() - { - mX++; - } - - void IncrementConst() const - { - mX++; - } - - int MultiplyBy(int x) - { - return mX * x; - } - - int MultiplyByConst(int x) const - { - return mX * x; - } -}; - - - - -/////////////////////////////////////////////////////////////////////////////// -// TestForwardDeclarations -// -static int TestForwardDeclarations() -{ - int nErrorCount = 0; - - eastl::local_string8 s8; - UseForwardDeclaredString(&s8); - - eastl::vector8 v8; - UseForwardDeclaredVector(&v8); - - eastl::hash_set8 h8; - UseForwardDeclaredHashSet(&h8); - - eastl::map8 m8; - UseForwardDeclaredMap(&m8); - - return nErrorCount; -} - - - - -/////////////////////////////////////////////////////////////////////////////// -// fixed_pool_reference -// -struct fixed_pool_reference -{ -public: - fixed_pool_reference(const char* = NULL) - { - mpFixedPool = NULL; - } - - fixed_pool_reference(eastl::fixed_pool& fixedPool) - { - mpFixedPool = &fixedPool; - } - - fixed_pool_reference(const fixed_pool_reference& x) - { - mpFixedPool = x.mpFixedPool; - } - - fixed_pool_reference& operator=(const fixed_pool_reference& x) - { - mpFixedPool = x.mpFixedPool; - return *this; - } - - void* allocate(size_t /*n*/, int /*flags*/ = 0) - { - return mpFixedPool->allocate(); - } - - void* allocate(size_t /*n*/, size_t /*alignment*/, size_t /*offset*/, int /*flags*/ = 0) - { - return mpFixedPool->allocate(); - } - - void deallocate(void* p, size_t /*n*/) - { - return mpFixedPool->deallocate(p); - } - - const char* get_name() const - { - return "fixed_pool_reference"; - } - - void set_name(const char* /*pName*/) - { - } - -protected: - friend bool operator==(const fixed_pool_reference& a, const fixed_pool_reference& b); - friend bool operator!=(const fixed_pool_reference& a, const fixed_pool_reference& b); - - eastl::fixed_pool* mpFixedPool; -}; - - -inline bool operator==(const fixed_pool_reference& a, const fixed_pool_reference& b) -{ - return (a.mpFixedPool == b.mpFixedPool); -} - -inline bool operator!=(const fixed_pool_reference& a, const fixed_pool_reference& b) -{ - return (a.mpFixedPool != b.mpFixedPool); -} - - - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::queue<int, deque<int> >; -template class eastl::queue<Align64, deque<Align64> >; -template class eastl::queue<TestObject, list<TestObject> >; -//template class eastl::queue<IntNode, intrusive_list<IntNode> >;// This test has been disabled as of the addition of initializer_list support to eastl::queue. initializer_lists have const nodes, which is incompatible with intrusive_list. You can use eastl::queue<IntNode, intrusive_list<IntNode> > as long as you don't use initializer_list with it. The problem with this line of code is that it forces compilation of the entire class. - - -/////////////////////////////////////////////////////////////////////////////// -// TestQueue -// -static int TestQueue() -{ - int nErrorCount = 0; - - { - // Exercise IntNode. - IntNode x, y; - EATEST_VERIFY((x < y) || !(x < y) || ((int)x < (int)y)); - } - - TestObject::Reset(); - - { - // queue(const Sequence& x = Sequence()); - queue<TestObject, list<TestObject>> toListQueue; - queue<TestObject, list<TestObject>> toListQueue2; - - - // global operators - EATEST_VERIFY( (toListQueue == toListQueue2)); - EATEST_VERIFY(!(toListQueue != toListQueue2)); - EATEST_VERIFY( (toListQueue <= toListQueue2)); - EATEST_VERIFY( (toListQueue >= toListQueue2)); - EATEST_VERIFY(!(toListQueue < toListQueue2)); - EATEST_VERIFY(!(toListQueue > toListQueue2)); - - // bool empty() const; - // size_type size() const; - EATEST_VERIFY(toListQueue.empty()); - EATEST_VERIFY(toListQueue.size() == 0); - - - // void push(const value_type& value); - // reference front(); - // const_reference front() const; - // reference back(); - // const_reference back() const; - toListQueue.push(TestObject(0)); - EATEST_VERIFY(toListQueue.front() == TestObject(0)); - EATEST_VERIFY(toListQueue.back() == TestObject(0)); - - toListQueue.push(TestObject(1)); - EATEST_VERIFY(toListQueue.front() == TestObject(0)); - EATEST_VERIFY(toListQueue.back() == TestObject(1)); - - toListQueue.push(TestObject(2)); - EATEST_VERIFY(toListQueue.front() == TestObject(0)); - EATEST_VERIFY(toListQueue.back() == TestObject(2)); - EATEST_VERIFY(!toListQueue.empty()); - EATEST_VERIFY(toListQueue.size() == 3); - - - // void pop(); - toListQueue.pop(); - EATEST_VERIFY(toListQueue.front() == TestObject(1)); - EATEST_VERIFY(toListQueue.back() == TestObject(2)); - - toListQueue.pop(); - EATEST_VERIFY(toListQueue.front() == TestObject(2)); - EATEST_VERIFY(toListQueue.back() == TestObject(2)); - - toListQueue.pop(); - EATEST_VERIFY(toListQueue.empty()); - EATEST_VERIFY(toListQueue.size() == 0); - - - // decltype(auto) emplace(Args&&... args); - toListQueue.emplace(1); - EATEST_VERIFY(!toListQueue.empty()); - EATEST_VERIFY(toListQueue.front() == TestObject(1)); - EATEST_VERIFY(toListQueue.size() == 1); - - - // container_type& get_container(); - // const container_type& get_container() const; - list<TestObject>& ref = toListQueue.get_container(); - EATEST_VERIFY(ref.size() == toListQueue.size()); - - - // queue(std::initializer_list<value_type> ilist); - queue<int> intQueue = { 3, 4, 5 }; - EATEST_VERIFY(intQueue.size() == 3); - EATEST_VERIFY(intQueue.front() == 3); - intQueue.pop(); - EATEST_VERIFY(intQueue.front() == 4); - intQueue.pop(); - EATEST_VERIFY(intQueue.front() == 5); - } - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - // queue(const Sequence& x = Sequence()); - queue<TestObject, list<TestObject>> toListQueue; - queue<TestObject, list<TestObject>> toListQueue2; - - - // global operators - EATEST_VERIFY( ((toListQueue <=> toListQueue2) == 0)); - EATEST_VERIFY(!((toListQueue <=> toListQueue2) != 0)); - EATEST_VERIFY( ((toListQueue <=> toListQueue2) <= 0)); - EATEST_VERIFY( ((toListQueue <=> toListQueue2) >= 0)); - EATEST_VERIFY(!((toListQueue <=> toListQueue2) < 0)); - EATEST_VERIFY(!((toListQueue <=> toListQueue2) > 0)); - - // bool empty() const; - // size_type size() const; - EATEST_VERIFY(toListQueue.empty()); - EATEST_VERIFY(toListQueue.size() == 0); - - // Verify toListQueue > toListQueue2 - toListQueue.push(TestObject(0)); - toListQueue.push(TestObject(1)); - toListQueue2.push(TestObject(0)); - - EATEST_VERIFY(!((toListQueue <=> toListQueue2) == 0)); - EATEST_VERIFY( ((toListQueue <=> toListQueue2) != 0)); - EATEST_VERIFY( ((toListQueue <=> toListQueue2) >= 0)); - EATEST_VERIFY(!((toListQueue <=> toListQueue2) <= 0)); - EATEST_VERIFY( ((toListQueue <=> toListQueue2) > 0)); - EATEST_VERIFY(!((toListQueue <=> toListQueue2) < 0)); - - // Verify toListQueue2 > toListQueue by element size - toListQueue2.push(TestObject(3)); - EATEST_VERIFY(!((toListQueue <=> toListQueue2) == 0)); - EATEST_VERIFY( ((toListQueue <=> toListQueue2) != 0)); - EATEST_VERIFY( ((toListQueue <=> toListQueue2) <= 0)); - EATEST_VERIFY(!((toListQueue <=> toListQueue2) >= 0)); - EATEST_VERIFY( ((toListQueue <=> toListQueue2) < 0)); - EATEST_VERIFY(!((toListQueue <=> toListQueue2) > 0)); - - queue<TestObject, list<TestObject>> toListQueue3; - queue<TestObject, list<TestObject>> toListQueue4; - - for (int i = 0; i < 10; i++) - { - toListQueue3.push(TestObject(i)); - if (i < 5) - toListQueue4.push(TestObject(i)); - } - - // Verify toListQueue4 is a strict subset of toListQueue3 - EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) == 0)); - EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) != 0)); - EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) >= 0)); - EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) <= 0)); - EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) > 0)); - EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) < 0)); - - // Verify that even thoughn toListQueue4 has a smaller size, it's lexicographically larger - toListQueue4.push(TestObject(11)); - EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) == 0)); - EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) != 0)); - EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) <= 0)); - EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) >= 0)); - EATEST_VERIFY( ((toListQueue3 <=> toListQueue4) < 0)); - EATEST_VERIFY(!((toListQueue3 <=> toListQueue4) > 0)); - - } - - { - queue<TestObject, list<TestObject>> toListQueue1; - queue<TestObject, list<TestObject>> toListQueue2; - queue<TestObject, list<TestObject>> toListQueue3; - - for (int i = 0; i < 10; i++) - { - toListQueue1.push(TestObject(i)); - toListQueue2.push(TestObject(9-i)); - if (i < 5) - toListQueue3.push(TestObject(i)); - } - - struct weak_ordering_queue - { - queue<TestObject, list<TestObject>> queue; - inline std::weak_ordering operator<=>(const weak_ordering_queue& b) const { return queue <=> b.queue; } - }; - - EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue1}, weak_ordering_queue{toListQueue2}) == std::weak_ordering::less); - EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue3}, weak_ordering_queue{toListQueue1}) == std::weak_ordering::less); - EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue2}, weak_ordering_queue{toListQueue1}) == std::weak_ordering::greater); - EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue2}, weak_ordering_queue{toListQueue3}) == std::weak_ordering::greater); - EATEST_VERIFY(synth_three_way{}(weak_ordering_queue{toListQueue1}, weak_ordering_queue{toListQueue1}) == std::weak_ordering::equivalent); - } - #endif - - { - vector<TestObject> toVector; - for(int i = 0; i < 100; i++) - toVector.push_back(TestObject(i)); - - // template <class Allocator> - // queue(this_type&& x, const Allocator& allocator, typename eastl::enable_if<eastl::uses_allocator<container_type, Allocator>::value>::type* = NULL); - // - // explicit queue(container_type&& x); - // - // void push(value_type&& x); - - queue<TestObject, vector<TestObject> > toQ_0; - queue<TestObject, vector<TestObject> > toQ_A(eastl::move(toQ_0), toQ_0.get_container().get_allocator()); // It would be better if we also tested an alternative allocator. - EATEST_VERIFY(toQ_A.size() == 0); - toQ_A.push(TestObject(1000)); - EATEST_VERIFY(toQ_A.size() == 1); - - queue<TestObject, vector<TestObject> > toQ_B(eastl::move(toQ_A), toQ_A.get_container().get_allocator()); // It would be better if we also tested an alternative allocator. - EATEST_VERIFY((toQ_B.size() == 1) && toQ_A.empty()); - - eastl::vector<TestObject> toVectorM(toVector); - queue<TestObject, vector<TestObject> > toQ_C(eastl::move(toVectorM)); - EATEST_VERIFY((toQ_C.size() == toVector.size()) && toVectorM.empty()); - - // template <class... Args> - // void emplace_back(Args&&... args); - - queue<TestObject, vector<TestObject> > toQ_D; - toQ_D.emplace(0, 1, 2); - EATEST_VERIFY(toQ_D.size() == 1) && (toQ_D.back() == TestObject(0, 1, 2)); - } - - - { // Test std namespace elements contained in queue - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - eastl::queue< std::pair<int, int> > stlQueue; - stlQueue.push(std::make_pair(1, 1)); - EATEST_VERIFY(stlQueue.size() == 1); - #endif - } - - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - return nErrorCount; -} - - - - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::priority_queue<int, vector<int> >; -template class eastl::priority_queue<Align64, deque<Align64> >; -template class eastl::priority_queue<TestObject, vector<TestObject> >; -template class eastl::priority_queue<float, vector<float>, less<float> >; - - -/////////////////////////////////////////////////////////////////////////////// -// TestPriorityQueue -// -static int TestPriorityQueue() -{ - int nErrorCount = 0; - - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - - TestObject::Reset(); - - { - less<TestObject> toLess; - - vector<TestObject> toVector; - for(int i = 0; i < 100; i++) - toVector.push_back(TestObject(i)); - random_shuffle(toVector.begin(), toVector.end(), rng); - - list<TestObject> toList; - for(eastl_size_t j = 0; j < 100; j++) - toList.push_back(toVector[j]); - - - // priority_queue(const Compare& compare = Compare(), const Sequence& x = Sequence()); - // template <typename InputIterator> - // priority_queue(InputIterator first, InputIterator last, const Compare& compare = Compare(), const Sequence& x = Sequence()); - priority_queue<TestObject, vector<TestObject> > toPQ; - priority_queue<TestObject, vector<TestObject> > toPQV(toLess, toVector); - priority_queue<TestObject, vector<TestObject> > toPQL(toList.begin(), toList.end()); - - EATEST_VERIFY(toPQ.empty()); - EATEST_VERIFY(toPQ.size() == 0); - - EATEST_VERIFY(!toPQV.empty()); - EATEST_VERIFY( toPQV.size() == toVector.size()); - - EATEST_VERIFY(!toPQL.empty()); - EATEST_VERIFY( toPQL.size() == toList.size()); - - - // global operators - EATEST_VERIFY( (toPQ != toPQL)); - EATEST_VERIFY( (toPQV == toPQL)); - EATEST_VERIFY(!(toPQV != toPQL)); - EATEST_VERIFY( (toPQV <= toPQL)); - EATEST_VERIFY( (toPQV >= toPQL)); - EATEST_VERIFY(!(toPQV < toPQL)); - EATEST_VERIFY(!(toPQV > toPQL)); - - - // container_type& get_container(); - // const container_type& get_container() const; - vector<TestObject>& ref = toPQL.get_container(); - EATEST_VERIFY(ref.size() == toPQL.size()); - EATEST_VERIFY(is_heap(ref.begin(), ref.end())); - - // bool validate() const; - EATEST_VERIFY(toPQL.validate()); - // To consider: Verify that validate detects an invalid heap. - // Testing this might be an issue if the validation function actively complains in some way. - - - // const_reference top() const; - // void pop(); - const TestObject& to1 = toPQL.top(); - EATEST_VERIFY(to1 == TestObject(99)); - - toPQL.pop(); - EATEST_VERIFY(!toPQL.empty()); - EATEST_VERIFY( toPQL.size() == toList.size() - 1); - EATEST_VERIFY(to1 == TestObject(98)); - EATEST_VERIFY(is_heap(ref.begin(), ref.end())); - - - // void push(const value_type& value); - toPQL.push(TestObject(1000)); - EATEST_VERIFY(toPQL.size() == toList.size()); - const TestObject& to2 = toPQL.top(); - EATEST_VERIFY(to2 == TestObject(1000)); - toPQL.pop(); - const TestObject& to3 = toPQL.top(); - EATEST_VERIFY(to3 == TestObject(98)); - EATEST_VERIFY(is_heap(ref.begin(), ref.end())); - - - // void change(size_type n); - TestObject& to4 = ref[50]; - to4 = TestObject(2000); - toPQL.change(50); - const TestObject& to5 = toPQL.top(); - EATEST_VERIFY(to5 == TestObject(2000)); - EATEST_VERIFY(is_heap(ref.begin(), ref.end())); - - - // void remove(size_type n); - TestObject to6 = ref[20]; - toPQL.remove(20); - EATEST_VERIFY( toPQL.size() == toList.size() - 2); - TestObject& to7 = ref[20]; - EATEST_VERIFY(!(to6 == to7)); - EATEST_VERIFY(is_heap(ref.begin(), ref.end())); - - - // priority_queue(std::initializer_list<value_type> ilist, const compare_type& compare = compare_type()); - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - priority_queue<int, vector<int> > intPQ = { 3, 4, 5 }; - EATEST_VERIFY(intPQ.size() == 3); - EATEST_VERIFY(intPQ.top() == 5); - intPQ.pop(); - EATEST_VERIFY(intPQ.top() == 4); - intPQ.pop(); - EATEST_VERIFY(intPQ.top() == 3); - #endif - } - - { - vector<TestObject> toVector; - for(int i = 0; i < 100; i++) - toVector.push_back(TestObject(i)); - - // template <class Allocator> - // priority_queue(this_type&& x, const Allocator& allocator, typename eastl::enable_if<eastl::uses_allocator<container_type, Allocator>::value>::type* = NULL); - // - // explicit priority_queue(const compare_type& compare, container_type&& x); - // - // template <class InputIterator> - // priority_queue(InputIterator first, InputIterator last, const compare_type& compare, container_type&& x); - // - // void push(value_type&& x); - - priority_queue<TestObject, vector<TestObject> > toPQ_0; - priority_queue<TestObject, vector<TestObject> > toPQ_A(toPQ_0.get_container().begin(), toPQ_0.get_container().begin(), eastl::less<TestObject>(), toPQ_0.get_container()); - EATEST_VERIFY(toPQ_A.size() == 0); - toPQ_A.push(TestObject(1000)); - EATEST_VERIFY(toPQ_A.size() == 1); - - priority_queue<TestObject, vector<TestObject> > toPQ_B(eastl::move(toPQ_A), toPQ_A.get_container().get_allocator()); // It would be better if we also tested an alternative allocator. - EATEST_VERIFY((toPQ_B.size() == 1) && toPQ_A.empty()); - - eastl::vector<TestObject> toVectorM(toVector); - priority_queue<TestObject, vector<TestObject> > toPQ_C(eastl::less<TestObject>(), eastl::move(toVectorM)); - EATEST_VERIFY((toPQ_C.size() == toVector.size()) && toVectorM.empty()); - - // template <class... Args> - // void emplace(Args&&... args); - priority_queue<TestObject, vector<TestObject> > toPQ_D; - toPQ_D.emplace(0, 1, 2); - EATEST_VERIFY(toPQ_D.size() == 1) && (toPQ_D.top() == TestObject(0, 1, 2)); - } - - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - return nErrorCount; -} - - - - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::stack<int, vector<int> >; -template class eastl::stack<Align64, list<Align64> >; -template class eastl::stack<TestObject, vector<TestObject> >; -//template class eastl::stack<IntNode, intrusive_list<IntNode> >; // This test has been disabled as of the addition of initializer_list support to eastl::stack. initializer_lists have const nodes, which is incompatible with intrusive_list. You can use eastl::stack<IntNode, intrusive_list<IntNode> > as long as you don't use initializer_list with it. The problem with this line of code is that it forces compilation of the entire class. - - -/////////////////////////////////////////////////////////////////////////////// -// TestStack -// -static int TestStack() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { - // stack(const Sequence& x = Sequence()); - stack<TestObject, list<TestObject> > toListStack; - stack<TestObject, list<TestObject> > toListStack2; - - - // bool empty() const; - // size_type size() const; - EATEST_VERIFY(toListStack.empty()); - EATEST_VERIFY(toListStack.size() == 0); - - - // global operators - EATEST_VERIFY( (toListStack == toListStack2)); - EATEST_VERIFY(!(toListStack != toListStack2)); - EATEST_VERIFY( (toListStack <= toListStack2)); - EATEST_VERIFY( (toListStack >= toListStack2)); - EATEST_VERIFY(!(toListStack < toListStack2)); - EATEST_VERIFY(!(toListStack > toListStack2)); - - // void push(const value_type& value); - // reference top(); - // const_reference top() const; - toListStack.push(TestObject(0)); - EATEST_VERIFY(toListStack.top() == TestObject(0)); - - toListStack.push(TestObject(1)); - EATEST_VERIFY(toListStack.top() == TestObject(1)); - - toListStack.push(TestObject(2)); - EATEST_VERIFY( toListStack.top() == TestObject(2)); - EATEST_VERIFY(!toListStack.empty()); - EATEST_VERIFY( toListStack.size() == 3); - - // void pop(); - toListStack.pop(); - EATEST_VERIFY(toListStack.top() == TestObject(1)); - - toListStack.pop(); - EATEST_VERIFY(toListStack.top() == TestObject(0)); - - toListStack.pop(); - EATEST_VERIFY(toListStack.empty()); - EATEST_VERIFY(toListStack.size() == 0); - - - // container_type& get_container(); - // const container_type& get_container() const; - list<TestObject>& ref = toListStack.get_container(); - EATEST_VERIFY(ref.size() == toListStack.size()); - - - // stack(std::initializer_list<value_type> ilist); - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - stack<int> intStack = { 3, 4, 5 }; - EATEST_VERIFY(intStack.size() == 3); - EATEST_VERIFY(intStack.top() == 5); - intStack.pop(); - EATEST_VERIFY(intStack.top() == 4); - intStack.pop(); - EATEST_VERIFY(intStack.top() == 3); - #endif - } - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - // stack(const Sequence& x = Sequence()); - stack<TestObject, list<TestObject> > toListStack; - stack<TestObject, list<TestObject> > toListStack2; - - // bool empty() const; - // size_type size() const; - EATEST_VERIFY(toListStack.empty()); - EATEST_VERIFY(toListStack.size() == 0); - - - // global operators - EATEST_VERIFY( ((toListStack <=> toListStack2) == 0)); - EATEST_VERIFY(!((toListStack <=> toListStack2) != 0)); - EATEST_VERIFY( ((toListStack <=> toListStack2) <= 0)); - EATEST_VERIFY( ((toListStack <=> toListStack2) >= 0)); - EATEST_VERIFY(!((toListStack <=> toListStack2) < 0)); - EATEST_VERIFY(!((toListStack <=> toListStack2) > 0)); - - toListStack.push(TestObject(0)); - toListStack.push(TestObject(1)); - toListStack2.push(TestObject(0)); - - EATEST_VERIFY(!((toListStack <=> toListStack2) == 0)); - EATEST_VERIFY( ((toListStack <=> toListStack2) != 0)); - EATEST_VERIFY( ((toListStack <=> toListStack2) >= 0)); - EATEST_VERIFY(!((toListStack <=> toListStack2) <= 0)); - EATEST_VERIFY( ((toListStack <=> toListStack2) > 0)); - EATEST_VERIFY(!((toListStack <=> toListStack2) < 0)); - - // Verify toListStack2 > toListStack by element size - toListStack2.push(TestObject(3)); - EATEST_VERIFY(!((toListStack <=> toListStack2) == 0)); - EATEST_VERIFY( ((toListStack <=> toListStack2) != 0)); - EATEST_VERIFY( ((toListStack <=> toListStack2) <= 0)); - EATEST_VERIFY(!((toListStack <=> toListStack2) >= 0)); - EATEST_VERIFY( ((toListStack <=> toListStack2) < 0)); - EATEST_VERIFY(!((toListStack <=> toListStack2) > 0)); - - stack<TestObject, list<TestObject> > toListStack3; - stack<TestObject, list<TestObject> > toListStack4; - - for (int i = 0; i < 10; i++) - { - toListStack3.push(TestObject(i)); - if (i < 5) - toListStack4.push(TestObject(i)); - } - - // Verify toListStack4 is a strict subset of toListStack3 - EATEST_VERIFY(!((toListStack3 <=> toListStack4) == 0)); - EATEST_VERIFY( ((toListStack3 <=> toListStack4) != 0)); - EATEST_VERIFY( ((toListStack3 <=> toListStack4) >= 0)); - EATEST_VERIFY(!((toListStack3 <=> toListStack4) <= 0)); - EATEST_VERIFY( ((toListStack3 <=> toListStack4) > 0)); - EATEST_VERIFY(!((toListStack3 <=> toListStack4) < 0)); - - // Verify that even thoughn toListQueue4 has a smaller size, it's lexicographically larger - toListStack4.push(TestObject(11)); - EATEST_VERIFY(!((toListStack3 <=> toListStack4) == 0)); - EATEST_VERIFY( ((toListStack3 <=> toListStack4) != 0)); - EATEST_VERIFY( ((toListStack3 <=> toListStack4) <= 0)); - EATEST_VERIFY(!((toListStack3 <=> toListStack4) >= 0)); - EATEST_VERIFY( ((toListStack3 <=> toListStack4) < 0)); - EATEST_VERIFY(!((toListStack3 <=> toListStack4) > 0)); - } - - { - stack<TestObject, list<TestObject> > toListStack1; - stack<TestObject, list<TestObject> > toListStack2; - stack<TestObject, list<TestObject> > toListStack3; - - for (int i = 0; i < 10; i++) - { - toListStack1.push(TestObject(i)); - toListStack2.push(TestObject(9-i)); - if (i < 5) - toListStack3.push(TestObject(i)); - } - - struct weak_ordering_stack - { - stack<TestObject, list<TestObject> > stack; - inline std::weak_ordering operator<=>(const weak_ordering_stack& b) const { return stack <=> b.stack; } - }; - - EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack1}, weak_ordering_stack{toListStack2}) == std::weak_ordering::less); - EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack3}, weak_ordering_stack{toListStack1}) == std::weak_ordering::less); - EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack2}, weak_ordering_stack{toListStack1}) == std::weak_ordering::greater); - EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack2}, weak_ordering_stack{toListStack3}) == std::weak_ordering::greater); - EATEST_VERIFY(synth_three_way{}(weak_ordering_stack{toListStack1}, weak_ordering_stack{toListStack1}) == std::weak_ordering::equivalent); - } -#endif - - - { - vector<TestObject> toVector; - for(int i = 0; i < 100; i++) - toVector.push_back(TestObject(i)); - - // template <class Allocator> - // stack(this_type&& x, const Allocator& allocator, typename eastl::enable_if<eastl::uses_allocator<container_type, Allocator>::value>::type* = NULL); - // - // explicit stack(container_type&& x); - // - // void push(value_type&& x); - stack<TestObject, vector<TestObject> > toS_0; - stack<TestObject, vector<TestObject> > toS_A(eastl::move(toS_0), toS_0.get_container().get_allocator()); // It would be better if we also tested an alternative allocator. - EATEST_VERIFY(toS_A.size() == 0); - toS_A.push(TestObject(1000)); - EATEST_VERIFY(toS_A.size() == 1); - - stack<TestObject, vector<TestObject> > toS_B(eastl::move(toS_A), toS_A.get_container().get_allocator()); // It would be better if we also tested an alternative allocator. - EATEST_VERIFY((toS_B.size() == 1) && toS_A.empty()); - - eastl::vector<TestObject> toVectorM(toVector); - stack<TestObject, vector<TestObject> > toS_C(eastl::move(toVectorM)); - EATEST_VERIFY((toS_C.size() == toVector.size()) && toVectorM.empty()); - - { - // template <class... Args> - // void emplace_back(Args&&... args); - stack<TestObject, vector<TestObject>> toS_D; - toS_D.emplace_back(0, 1, 2); - EATEST_VERIFY(toS_D.size() == 1) && (toS_D.top() == TestObject(0, 1, 2)); - } - - { - // template <class... Args> - // decltype(auto) emplace(Args&&... args); - stack<TestObject, vector<TestObject>> toS_D; - auto it = toS_D.emplace(0, 1, 2); - EATEST_VERIFY(toS_D.size() == 1) && (toS_D.top() == TestObject(0, 1, 2)); - EATEST_VERIFY(it == TestObject(0, 1, 2)); - } - } - - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - return nErrorCount; -} - - - - - -struct Size0 -{ - // Empty -}; - -struct Size4 -{ - uint32_t m32; -}; - - -/////////////////////////////////////////////////////////////////////////////// -// TestCompressedPair -// -static int TestCompressedPair() -{ - int nErrorCount = 0; - - compressed_pair<Size0, Size0> cp00; - compressed_pair<Size0, Size4> cp04; - compressed_pair<Size4, Size0> cp40; - compressed_pair<Size4, Size4> cp44; - - EATEST_VERIFY(sizeof(cp00) <= 4); - EATEST_VERIFY(sizeof(cp04) <= 4); - EATEST_VERIFY(sizeof(cp40) <= 4); - EATEST_VERIFY(sizeof(cp44) <= 8); - - return nErrorCount; -} - - - - - - -template <typename T> -struct CallTraitsContainer -{ - typedef typename eastl::call_traits<T>::param_type param_type; - typedef typename eastl::call_traits<T>::reference reference; - typedef typename eastl::call_traits<T>::const_reference const_reference; - typedef typename eastl::call_traits<T>::value_type result_type; - typedef T value_type; - -public: - value_type mValue; - - - CallTraitsContainer() { } - CallTraitsContainer(param_type p) : mValue(p) { } - - CallTraitsContainer<T>& operator=(const CallTraitsContainer<T>&) { } // Defined simply to prevent possible compiler warnings. - - result_type value() { return mValue; } - - reference get() { return mValue; } - const_reference const_get() const { return mValue; } - - void call(param_type p){ } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// TestCallTraits -// -static int TestCallTraits() -{ - int nErrorCount = 0; - - CallTraitsContainer<int> ctcInt; - CallTraitsContainer<int*> ctcIntPtr; - CallTraitsContainer<int&> ctcVoid(nErrorCount); - CallTraitsContainer<int[3]> ctcIntArray; - - char buffer[128]; - sprintf(buffer, "%p %p %p %p", &ctcInt, &ctcIntPtr, &ctcVoid, &ctcIntArray); - - return nErrorCount; -} - - -static int AccumulateMultiply(int x, int y) -{ - return (x * y); -} - -static eastl::string AccumulateString(eastl::string s, int x) -{ - s += '0' + static_cast<char>(x); - return s; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// TestNumeric -// -static int TestNumeric() -{ - int nErrorCount = 0; - - //template <typename InputIterator, typename T> - //T accumulate(InputIterator first, InputIterator last, T init); - eastl::vector<int> v(5, 0); - eastl::generate(v.begin(), v.end(), GenerateIncrementalIntegers<int>(1)); - - int sum = eastl::accumulate(v.begin(), v.end(), 100); - EATEST_VERIFY(sum == (100 + 1 + 2 + 3 + 4 + 5)); - - - // template <typename InputIterator, typename T, typename BinaryOperation> - //T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); - - eastl::generate(v.begin(), v.end(), GenerateIncrementalIntegers<int>(1)); - int product = eastl::accumulate(v.begin(), v.end(), 100, AccumulateMultiply); - EATEST_VERIFY(product == (100 * 1 * 2 * 3 * 4 * 5)); - - eastl::generate(v.begin(), v.end(), GenerateIncrementalIntegers<int>(1)); - eastl::string s = eastl::accumulate(v.begin(), v.end(), eastl::string("0"), AccumulateString); - EATEST_VERIFY(s == "012345"); - - - //template <typename InputIterator1, typename InputIterator2, typename T> - //T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); - // To do. - - //template <typename InputIterator1, typename InputIterator2, typename T, typename BinaryOperation1, typename BinaryOperation2> - //T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2) - // To do. - - //template <typename InputIterator, typename OutputIterator> - //OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result); - // To do. - - //template <typename InputIterator, typename OutputIterator, typename BinaryOperation> - //OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); - // To do. - - return nErrorCount; -} - -#if defined(EA_COMPILER_CPP20_ENABLED) -template <typename T> -static constexpr int SignedIntMidpoint() -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::midpoint(T(0), T(0)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(0), T(2)) == T(1)); - EATEST_VERIFY(eastl::midpoint(T(0), T(4)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(0), T(8)) == T(4)); - EATEST_VERIFY(eastl::midpoint(T(2), T(0)) == T(1)); - EATEST_VERIFY(eastl::midpoint(T(4), T(0)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(8), T(0)) == T(4)); - - EATEST_VERIFY(eastl::midpoint(T(1), T(1)) == T(1)); - EATEST_VERIFY(eastl::midpoint(T(1), T(3)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(3), T(1)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(2), T(6)) == T(4)); - EATEST_VERIFY(eastl::midpoint(T(6), T(2)) == T(4)); - - EATEST_VERIFY(eastl::midpoint(T(-1), T(-1)) == T(-1)); - EATEST_VERIFY(eastl::midpoint(T(-1), T(-3)) == T(-2)); - EATEST_VERIFY(eastl::midpoint(T(-3), T(-1)) == T(-2)); - EATEST_VERIFY(eastl::midpoint(T(-2), T(-6)) == T(-4)); - EATEST_VERIFY(eastl::midpoint(T(-6), T(-2)) == T(-4)); - - EATEST_VERIFY(eastl::midpoint(T(-0), T(0)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(0), T(-0)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(-0), T(-0)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(-1), T(1)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(-10), T(10)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(-3), T(7)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(-7), T(3)) == T(-2)); - EATEST_VERIFY(eastl::midpoint(T(-2), T(6)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(-6), T(2)) == T(-2)); - EATEST_VERIFY(eastl::midpoint(T(2), T(-6)) == T(-2)); - EATEST_VERIFY(eastl::midpoint(T(6), T(-2)) == T(2)); - - // If an odd sum, midpoint should round towards the LHS operand. - EATEST_VERIFY(eastl::midpoint(T(0), T(5)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(5), T(0)) == T(3)); - EATEST_VERIFY(eastl::midpoint(T(1), T(4)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(4), T(1)) == T(3)); - EATEST_VERIFY(eastl::midpoint(T(7), T(10)) == T(8)); - EATEST_VERIFY(eastl::midpoint(T(10), T(7)) == T(9)); - EATEST_VERIFY(eastl::midpoint(T(-1), T(2)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(2), T(-1)) == T(1)); - EATEST_VERIFY(eastl::midpoint(T(-5), T(4)) == T(-1)); - EATEST_VERIFY(eastl::midpoint(T(4), T(-5)) == T(0)); - - // Test absolute limits - constexpr T MIN = eastl::numeric_limits<T>::min(); - constexpr T MAX = eastl::numeric_limits<T>::max(); - - EATEST_VERIFY(eastl::midpoint(MIN, MIN) == MIN); - EATEST_VERIFY(eastl::midpoint(MAX, MAX) == MAX); - EATEST_VERIFY(eastl::midpoint(MIN, MAX) == T(-1)); - EATEST_VERIFY(eastl::midpoint(MAX, MIN) == T(0)); - EATEST_VERIFY(eastl::midpoint(MIN, T(0)) == MIN / 2); - EATEST_VERIFY(eastl::midpoint(T(0), MIN) == MIN / 2); - EATEST_VERIFY(eastl::midpoint(MAX, T(0)) == (MAX / 2) + 1); - EATEST_VERIFY(eastl::midpoint(T(0), MAX) == (MAX / 2)); - - EATEST_VERIFY(eastl::midpoint(MIN, T(10)) == (MIN / 2) + 5); - EATEST_VERIFY(eastl::midpoint(T(10), MIN) == (MIN / 2) + 5); - EATEST_VERIFY(eastl::midpoint(MAX, T(10)) == (MAX / 2) + 5 + 1); - EATEST_VERIFY(eastl::midpoint(T(10), MAX) == (MAX / 2) + 5); - EATEST_VERIFY(eastl::midpoint(MIN, T(-10)) == (MIN / 2) - 5); - EATEST_VERIFY(eastl::midpoint(T(-10), MIN) == (MIN / 2) - 5); - EATEST_VERIFY(eastl::midpoint(MAX, T(-10)) == (MAX / 2) - 5 + 1); - EATEST_VERIFY(eastl::midpoint(T(-10), MAX) == (MAX / 2) - 5); - - return nErrorCount; -} - -template <typename T> -static constexpr int UnsignedIntMidpoint() -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::midpoint(T(0), T(0)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(0), T(2)) == T(1)); - EATEST_VERIFY(eastl::midpoint(T(0), T(4)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(0), T(8)) == T(4)); - EATEST_VERIFY(eastl::midpoint(T(2), T(0)) == T(1)); - EATEST_VERIFY(eastl::midpoint(T(4), T(0)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(8), T(0)) == T(4)); - - EATEST_VERIFY(eastl::midpoint(T(1), T(1)) == T(1)); - EATEST_VERIFY(eastl::midpoint(T(1), T(3)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(3), T(1)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(2), T(6)) == T(4)); - EATEST_VERIFY(eastl::midpoint(T(6), T(2)) == T(4)); - - // If an odd sum, midpoint should round towards the LHS operand. - EATEST_VERIFY(eastl::midpoint(T(0), T(5)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(5), T(0)) == T(3)); - EATEST_VERIFY(eastl::midpoint(T(1), T(4)) == T(2)); - EATEST_VERIFY(eastl::midpoint(T(4), T(1)) == T(3)); - EATEST_VERIFY(eastl::midpoint(T(7), T(10)) == T(8)); - EATEST_VERIFY(eastl::midpoint(T(10), T(7)) == T(9)); - - // Test absolute limits - constexpr T MIN = eastl::numeric_limits<T>::min(); - constexpr T MAX = eastl::numeric_limits<T>::max(); - - EATEST_VERIFY(eastl::midpoint(MIN, MIN) == MIN); - EATEST_VERIFY(eastl::midpoint(MAX, MAX) == MAX); - EATEST_VERIFY(eastl::midpoint(MIN, MAX) == MAX / 2); - EATEST_VERIFY(eastl::midpoint(MAX, MIN) == (MAX / 2) + 1); - EATEST_VERIFY(eastl::midpoint(MIN, T(0)) == T(0)); - EATEST_VERIFY(eastl::midpoint(T(0), MIN) == T(0)); - - EATEST_VERIFY(eastl::midpoint(MIN, T(10)) == (MIN / 2) + 5); - EATEST_VERIFY(eastl::midpoint(T(10), MIN) == (MIN / 2) + 5); - EATEST_VERIFY(eastl::midpoint(MAX, T(10)) == (MAX / 2) + 5 + 1); - EATEST_VERIFY(eastl::midpoint(T(10), MAX) == (MAX / 2) + 5); - - return nErrorCount; -} - -template <typename T> -static constexpr int FloatMidpoint() -{ - // for use with floats, double, long doubles. - int nErrorCount = 0; - EATEST_VERIFY(eastl::midpoint(T(0.0), T(0.0)) == T(0.0)); - EATEST_VERIFY(eastl::midpoint(T(0.0), T(2.0)) == T(1.0)); - EATEST_VERIFY(eastl::midpoint(T(0.0), T(4.0)) == T(2.0)); - EATEST_VERIFY(eastl::midpoint(T(2.0), T(0.0)) == T(1.0)); - EATEST_VERIFY(eastl::midpoint(T(4.0), T(0.0)) == T(2.0)); - - EATEST_VERIFY(eastl::midpoint(T(0.5), T(0.5)) == T(0.5)); - EATEST_VERIFY(eastl::midpoint(T(0.0), T(0.5)) == T(0.25)); - EATEST_VERIFY(eastl::midpoint(T(0.5), T(0.0)) == T(0.25)); - EATEST_VERIFY(eastl::midpoint(T(0.5), T(1.0)) == T(0.75)); - EATEST_VERIFY(eastl::midpoint(T(1.0), T(0.5)) == T(0.75)); - - EATEST_VERIFY(eastl::midpoint(T(-0.0), T(0.0)) == T(0.0)); - EATEST_VERIFY(eastl::midpoint(T(0.0), T(-0.0)) == T(0.0)); - EATEST_VERIFY(eastl::midpoint(T(-0.0), T(-0.0)) == T(0.0)); - EATEST_VERIFY(eastl::midpoint(T(-1.0), T(2.0)) == T(0.5)); - EATEST_VERIFY(eastl::midpoint(T(-2.0), T(1)) == T(-0.5)); - EATEST_VERIFY(eastl::midpoint(T(-3.0), T(6.0)) == T(1.5)); - EATEST_VERIFY(eastl::midpoint(T(-6.0), T(3.0)) == T(-1.5)); - - // Test absolute limits - const T MIN = eastl::numeric_limits<T>::min(); - const T MAX = eastl::numeric_limits<T>::max(); - - EATEST_VERIFY(eastl::midpoint(MIN, MIN) == MIN); - EATEST_VERIFY(eastl::midpoint(MAX, MAX) == MAX); - EATEST_VERIFY(eastl::midpoint(MIN, MAX) == MAX / 2); - EATEST_VERIFY(eastl::midpoint(MAX, MIN) == MAX / 2); - EATEST_VERIFY(eastl::midpoint(-MAX, MIN) == -MAX / 2); - - EATEST_VERIFY(eastl::midpoint(MIN, T(9.0)) == T(4.5)); - EATEST_VERIFY(eastl::midpoint(MIN, T(-9.0)) == T(-4.5)); - EATEST_VERIFY(eastl::midpoint(T(9.0), MIN) == T(4.5)); - EATEST_VERIFY(eastl::midpoint(T(-9.0), MIN) == T(-4.5)); - EATEST_VERIFY(eastl::midpoint(MAX, T(9.0)) == MAX / 2 + T(4.5)); - EATEST_VERIFY(eastl::midpoint(MAX, T(-9.0)) == MAX / 2 - T(4.5)); - EATEST_VERIFY(eastl::midpoint(T(9.0), MAX) == MAX / 2 + T(4.5)); - EATEST_VERIFY(eastl::midpoint(T(-9.0), MAX) == MAX / 2 - T(4.5)); - - return nErrorCount; -} - -template <typename T> -static constexpr int PointerMidpoint() -{ - int nErrorCount = 0; - - const T ARR[100] = {}; - - EATEST_VERIFY(eastl::midpoint(ARR, ARR) == ARR); - EATEST_VERIFY(eastl::midpoint(ARR, ARR + 100) == ARR + 50); - EATEST_VERIFY(eastl::midpoint(ARR + 100, ARR) == ARR + 50); - EATEST_VERIFY(eastl::midpoint(ARR, ARR + 25) == ARR + 12); - EATEST_VERIFY(eastl::midpoint(ARR + 25, ARR) == ARR + 13); - EATEST_VERIFY(eastl::midpoint(ARR, ARR + 13) == ARR + 6); - EATEST_VERIFY(eastl::midpoint(ARR + 13, ARR) == ARR + 7); - EATEST_VERIFY(eastl::midpoint(ARR + 50, ARR + 100) == ARR + 75); - EATEST_VERIFY(eastl::midpoint(ARR + 100, ARR + 50) == ARR + 75); - - return nErrorCount; -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestMidpoint -// -static int TestMidpoint() -{ - int nErrorCount = 0; - - // template <typename T> - // constexpr eastl::enable_if_t<eastl::is_arithmetic_v<T> && !eastl::is_same_v<eastl::remove_cv_t<T>, bool>, T> - // midpoint(const T lhs, const T rhs) EA_NOEXCEPT - nErrorCount += SignedIntMidpoint<int>(); - nErrorCount += SignedIntMidpoint<char>(); - nErrorCount += SignedIntMidpoint<short>(); - nErrorCount += SignedIntMidpoint<long>(); - nErrorCount += SignedIntMidpoint<long long>(); - - nErrorCount += UnsignedIntMidpoint<unsigned int>(); - nErrorCount += UnsignedIntMidpoint<unsigned char>(); - nErrorCount += UnsignedIntMidpoint<unsigned short>(); - nErrorCount += UnsignedIntMidpoint<unsigned long>(); - nErrorCount += UnsignedIntMidpoint<unsigned long long>(); - - nErrorCount += FloatMidpoint<float>(); - nErrorCount += FloatMidpoint<double>(); - nErrorCount += FloatMidpoint<long double>(); - - // template <typename T> - // constexpr eastl::enable_if_t<eastl::is_object_v<T>, const T*> midpoint(const T* lhs, const T* rhs) - nErrorCount += PointerMidpoint<int>(); - nErrorCount += PointerMidpoint<char>(); - nErrorCount += PointerMidpoint<short>(); - nErrorCount += PointerMidpoint<float>(); - nErrorCount += PointerMidpoint<double>(); - nErrorCount += PointerMidpoint<long double>(); - - return nErrorCount; -} - - -template <typename T> -static constexpr int FloatLerp() -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::lerp(T(0.0), T(0.0), T(0.0)) == T(0.0)); - EATEST_VERIFY(eastl::lerp(T(1.0), T(0.0), T(0.0)) == T(1.0)); - EATEST_VERIFY(eastl::lerp(T(-1.0), T(0.0), T(0.0)) == T(-1.0)); - EATEST_VERIFY(eastl::lerp(T(0.0), T(1.0), T(0.0)) == T(0.0)); - EATEST_VERIFY(eastl::lerp(T(0.0), T(-1.0), T(0.0)) == T(0.0)); - EATEST_VERIFY(eastl::lerp(T(-1.0), T(1.0), T(1.0)) == T(1.0)); - EATEST_VERIFY(eastl::lerp(T(1.0), T(-1.0), T(1.0)) == T(-1.0)); - EATEST_VERIFY(eastl::lerp(T(-1.0), T(1.0), T(0.5)) == T(0.0)); - EATEST_VERIFY(eastl::lerp(T(1.0), T(-1.0), T(0.5)) == T(0.0)); - EATEST_VERIFY(eastl::lerp(T(5.0), T(5.0), T(0.5)) == T(5.0)); - EATEST_VERIFY(eastl::lerp(T(-5.0), T(-5.0), T(0.5)) == T(-5.0)); - EATEST_VERIFY(eastl::lerp(T(1.0), T(2.0), T(1.0)) == T(2.0)); - EATEST_VERIFY(eastl::lerp(T(2.0), T(1.0), T(1.0)) == T(1.0)); - EATEST_VERIFY(eastl::lerp(T(1.0), T(2.0), T(1.0)) == T(2.0)); - EATEST_VERIFY(eastl::lerp(T(1.0), T(2.0), T(2.0)) == T(3.0)); - EATEST_VERIFY(eastl::lerp(T(2.0), T(1.0), T(2.0)) == T(0.0)); - EATEST_VERIFY(eastl::lerp(T(1.0), T(-2.0), T(2.0)) == T(-5.0)); - EATEST_VERIFY(eastl::lerp(T(-1.0), T(2.0), T(2.0)) == T(5.0)); - EATEST_VERIFY(eastl::lerp(T(-1.5), T(1.5), T(0.75)) == T(0.75)); - EATEST_VERIFY(eastl::lerp(T(0.125), T(1.75), T(0.25)) == T(0.53125)); - EATEST_VERIFY(eastl::lerp(T(-0.125), T(-1.75), T(0.5)) == T(-0.9375)); - EATEST_VERIFY(eastl::lerp(T(-0.125), T(1.5), T(2.5)) == T(3.9375)); - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestLerp -// -static int TestLerp() -{ - int nErrorCount = 0; - - // template <class T> - // constexpr T lerp(const T a, const T b, const T t) EA_NOEXCEPT - nErrorCount += FloatLerp<float>(); - nErrorCount += FloatLerp<double>(); - nErrorCount += FloatLerp<long double>(); - - return nErrorCount; -} -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// TestAdaptors -// -static int TestAdaptors() -{ - int nErrorCount = 0; - - // reverse lvalue container - { - int int_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::vector<int> original(begin(int_data), end(int_data)); - - eastl::vector<int> reversed; - for(auto& e : eastl::reverse(original)) - reversed.push_back(e); - - eastl::reverse(begin(original), end(original)); - EATEST_VERIFY(reversed == original); - } - - // reverse const lvalue container - { - int int_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - const eastl::vector<int> original(begin(int_data), end(int_data)); - - eastl::vector<int> reversed; - for(auto& e : eastl::reverse(original)) - reversed.push_back(e); - - eastl::vector<int> reversed_original(original); - eastl::reverse(begin(reversed_original), end(reversed_original)); - EATEST_VERIFY(reversed == reversed_original); - } - - // reverse rvalue container - { - int int_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::vector<int> original(begin(int_data), end(int_data)); - - eastl::vector<int> reversed; - for (auto& e : eastl::reverse(eastl::vector<int>(original))) - reversed.push_back(e); - - eastl::reverse(begin(original), end(original)); - EATEST_VERIFY(reversed == original); - } - - return nErrorCount; -} - -#if defined(EA_COMPILER_CPP20_ENABLED) -template <typename T> -int TestHasSingleBit() -{ - int nErrorCount = 0; - - VERIFY(eastl::has_single_bit(T(0)) == false); - VERIFY(eastl::has_single_bit(T(1)) == true); - VERIFY(eastl::has_single_bit(T(2)) == true); - VERIFY(eastl::has_single_bit(T(3)) == false); - - VERIFY(eastl::has_single_bit(eastl::numeric_limits<T>::min()) == false); - VERIFY(eastl::has_single_bit(eastl::numeric_limits<T>::max()) == false); - - for (int i = 4; i < eastl::numeric_limits<T>::digits; i++) - { - T power_of_two = static_cast<T>(T(1U) << i); - VERIFY(eastl::has_single_bit(power_of_two)); - VERIFY(eastl::has_single_bit(static_cast<T>(power_of_two - 1)) == false); - } - - return nErrorCount; -} - -template <typename T> -static int TestBitCeil() -{ - int nErrorCount = 0; - - VERIFY(eastl::bit_ceil(T(0)) == T(1)); - VERIFY(eastl::bit_ceil(T(1)) == T(1)); - VERIFY(eastl::bit_ceil(T(2)) == T(2)); - VERIFY(eastl::bit_ceil(T(3)) == T(4)); - - EA_CONSTEXPR auto DIGITS = eastl::numeric_limits<T>::digits; - EA_CONSTEXPR auto MIN = eastl::numeric_limits<T>::min(); - EA_CONSTEXPR auto MAX = static_cast<T>(T(1) << (DIGITS - 1)); - - VERIFY(eastl::bit_ceil(MAX) == MAX); - VERIFY(eastl::bit_ceil(static_cast<T>(MAX - 1)) == MAX); - VERIFY(eastl::bit_ceil(MIN) == T(1)); - - for (int i = 4; i < eastl::numeric_limits<T>::digits; i++) - { - T power_of_two = static_cast<T>(T(1U) << i); - VERIFY(eastl::bit_ceil(power_of_two) == power_of_two); - VERIFY(eastl::bit_ceil(static_cast<T>(power_of_two - 1)) == power_of_two); - } - - return nErrorCount; -} - -template <typename T> -static int TestBitFloor() -{ - int nErrorCount = 0; - VERIFY(eastl::bit_floor(T(0)) == T(0)); - VERIFY(eastl::bit_floor(T(1)) == T(1)); - VERIFY(eastl::bit_floor(T(2)) == T(2)); - VERIFY(eastl::bit_floor(T(3)) == T(2)); - - EA_CONSTEXPR auto DIGITS = eastl::numeric_limits<T>::digits; - EA_CONSTEXPR auto MIN = eastl::numeric_limits<T>::min(); - EA_CONSTEXPR auto MAX = eastl::numeric_limits<T>::max(); - - VERIFY(eastl::bit_floor(MAX) == T(1) << (DIGITS - 1)); - VERIFY(eastl::bit_floor(MIN) == T(0)); - - for (int i = 4; i < eastl::numeric_limits<T>::digits; i++) - { - T power_of_two = static_cast<T>(T(1U) << i); - VERIFY(eastl::bit_floor(power_of_two) == power_of_two); - VERIFY(eastl::bit_floor(static_cast<T>(power_of_two + 1)) == power_of_two); - } - return nErrorCount; -} - -template <typename T> -static int TestBitWidth() -{ - int nErrorCount = 0; - - VERIFY(eastl::bit_width(T(0)) == T(0)); - VERIFY(eastl::bit_width(T(1)) == T(1)); - VERIFY(eastl::bit_width(T(2)) == T(2)); - VERIFY(eastl::bit_width(T(3)) == T(2)); - - EA_CONSTEXPR auto DIGITS = eastl::numeric_limits<T>::digits; - EA_CONSTEXPR auto MIN = eastl::numeric_limits<T>::min(); - EA_CONSTEXPR auto MAX = eastl::numeric_limits<T>::max(); - - VERIFY(eastl::bit_width(MIN) == 0); - VERIFY(eastl::bit_width(MAX) == DIGITS); - - for (int i = 4; i < eastl::numeric_limits<T>::digits; i++) - { - T power_of_two = static_cast<T>(T(1U) << i); - VERIFY(eastl::bit_width(power_of_two) == static_cast<T>(i + 1)); - } - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestPowerofTwo -// -static int TestPowerOfTwo() -{ - int nErrorCount = 0; - nErrorCount += TestHasSingleBit<unsigned int>(); - nErrorCount += TestHasSingleBit<unsigned char>(); - nErrorCount += TestHasSingleBit<unsigned short>(); - nErrorCount += TestHasSingleBit<unsigned long>(); - nErrorCount += TestHasSingleBit<unsigned long long>(); - - nErrorCount += TestBitCeil<unsigned int>(); - nErrorCount += TestBitCeil<unsigned char>(); - nErrorCount += TestBitCeil<unsigned short>(); - nErrorCount += TestBitCeil<unsigned long>(); - nErrorCount += TestBitCeil<unsigned long long>(); - - nErrorCount += TestBitFloor<unsigned int>(); - nErrorCount += TestBitFloor<unsigned char>(); - nErrorCount += TestBitFloor<unsigned short>(); - nErrorCount += TestBitFloor<unsigned long>(); - nErrorCount += TestBitFloor<unsigned long long>(); - - nErrorCount += TestBitWidth<unsigned int>(); - nErrorCount += TestBitWidth<unsigned char>(); - nErrorCount += TestBitWidth<unsigned short>(); - nErrorCount += TestBitWidth<unsigned long>(); - nErrorCount += TestBitWidth<unsigned long long>(); - - return nErrorCount; -} -#endif - -/////////////////////////////////////////////////////////////////////////////// -// TestExtra -// -int TestExtra() -{ - int nErrorCount = 0; - - nErrorCount += TestForwardDeclarations(); - nErrorCount += TestQueue(); - nErrorCount += TestPriorityQueue(); - nErrorCount += TestStack(); - nErrorCount += TestCompressedPair(); - nErrorCount += TestCallTraits(); - nErrorCount += TestNumeric(); - nErrorCount += TestAdaptors(); -#if defined(EA_COMPILER_CPP20_ENABLED) - nErrorCount += TestMidpoint(); - nErrorCount += TestLerp(); - nErrorCount += TestPowerOfTwo(); -#endif - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestFinally.cpp b/test/source/TestFinally.cpp deleted file mode 100644 index 6e6e595..0000000 --- a/test/source/TestFinally.cpp +++ /dev/null @@ -1,107 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/finally.h> - - -int TestFinally() -{ - using namespace eastl; - - int nErrorCount = 0; - - { - #if defined(EA_COMPILER_CPP17_ENABLED) - { - // requires CTAD (class template argument deduction) - int a = 0; - { - VERIFY(a == 0); - eastl::finally _([&] { a = 42; }); - VERIFY(a == 0); - } - VERIFY(a == 42); - } - #endif - - { - int a = 0; - { - VERIFY(a == 0); - auto _ = eastl::make_finally([&] { a = 42; }); - VERIFY(a == 0); - } - VERIFY(a == 42); - } - - { - int a = 0; - { - VERIFY(a == 0); - auto f = eastl::make_finally([&] { a = 42; }); - VERIFY(a == 0); - f.dismiss(); - VERIFY(a == 0); - } - VERIFY(a == 0); - } - - { - int a = 0; - { - VERIFY(a == 0); - auto f = eastl::make_finally([&] { a = 42; }); - VERIFY(a == 0); - f.execute(); - VERIFY(a == 42); - } - VERIFY(a == 42); - } - - { - int a = 0; - { - VERIFY(a == 0); - auto f = eastl::make_finally([&] { a = 42; }); - VERIFY(a == 0); - f.execute(); - VERIFY(a == 42); - - // verify the finally object doesn't re-run the callback on scope-exit. - a = -1; - } - VERIFY(a == -1); - } - - { - struct local_flag { bool b = false; }; - - local_flag lf; - VERIFY(lf.b == false); - - { auto _ = eastl::make_finally([&] { lf.b = true; }); } - - VERIFY(lf.b); - } - - // This currently does not compile by design. - // - // { - // int a = 0; - // auto lbda = [&a] { a = 1234; }; - // { - // VERIFY(a == 0); - // auto _ = eastl::make_finally(lbda); // compiler error - // VERIFY(a == 0); - // } - // VERIFY(a == 1234); - // } - } - - return nErrorCount; -} - - diff --git a/test/source/TestFixedFunction.cpp b/test/source/TestFixedFunction.cpp deleted file mode 100644 index 272b545..0000000 --- a/test/source/TestFixedFunction.cpp +++ /dev/null @@ -1,614 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include <EABase/eabase.h> -#include <EAAssert/eaassert.h> - -// Included prior to EASTLTest.h to guard against the following bug resurfacing: -// https://github.com/electronicarts/EASTL/issues/275 -#include <EASTL/fixed_function.h> - -#include "EASTLTest.h" -#include <EASTL/numeric.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#include <functional> -EA_RESTORE_ALL_VC_WARNINGS() - - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionDtor -// -int TestFixedFunctionDtor() -{ - using namespace eastl; - - int nErrorCount = 0; - - { - TestObject to; - TestObject::Reset(); - { - eastl::fixed_function<sizeof(TestObject), void(void)> ff = [to] {}; - ff(); - } - VERIFY(TestObject::IsClear()); - } - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionStdBind -// -int TestFixedFunctionStdBind() -{ - using namespace eastl; - - int nErrorCount = 0; - int val = 0; - - { - TestObject to; - auto lambda = [to, &val] { ++val; }; - TestObject::Reset(); - { - eastl::fixed_function<64, void(void)> ff = std::bind(lambda); - ff(); - } - VERIFY(TestObject::IsClear()); - VERIFY(val == 1); - } - { - TestObject to; - auto lambda = [to, &val] { ++val; }; - TestObject::Reset(); - { - eastl::fixed_function<64, void(void)> ff = nullptr; - ff = std::bind(lambda); - ff(); - } - VERIFY(TestObject::IsClear()); - VERIFY(val == 2); - } - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionReferenceWrapper -// -int TestFixedFunctionReferenceWrapper() -{ - using namespace eastl; - - int nErrorCount = 0; - int val = 0; - - { - TestObject to; - auto lambda = [to, &val] { ++val; }; - TestObject::Reset(); - { - eastl::fixed_function<sizeof(eastl::reference_wrapper<decltype(lambda)>), void(void)> ff = eastl::reference_wrapper<decltype(lambda)>(lambda); - ff(); - } - VERIFY(TestObject::IsClear()); - VERIFY(val == 1); - } - { - TestObject to; - auto lambda = [to, &val] { ++val; }; - TestObject::Reset(); - { - eastl::fixed_function<sizeof(eastl::reference_wrapper<decltype(lambda)>), void(void)> ff = nullptr; - ff = eastl::reference_wrapper<decltype(lambda)>(lambda); - ff(); - } - VERIFY(TestObject::IsClear()); - VERIFY(val == 2); - } - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionFunctionPointer -// - -static void TestVoidRet(int* p) -{ - *p += 1; -} - -static int TestIntRet(int* p) -{ - int ret = *p; - *p += 1; - return ret; -} - -int TestFixedFunctionFunctionPointer() -{ - using namespace eastl; - - typedef int (*FuncPtrInt)(int*); - typedef void (*FuncPtrVoid)(int*); - - int nErrorCount = 0; - int val = 0; - - { - eastl::fixed_function<sizeof(FuncPtrVoid), void(int*)> ff = &TestVoidRet; - ff(&val); - VERIFY(val == 1); - } - { - eastl::fixed_function<sizeof(FuncPtrVoid), void(int*)> ff; - ff = &TestVoidRet; - ff(&val); - VERIFY(val == 2); - } - { - eastl::fixed_function<sizeof(FuncPtrInt), int(int*)> ff = &TestIntRet; - int ret = ff(&val); - VERIFY(ret == 2); - VERIFY(val == 3); - } - { - eastl::fixed_function<sizeof(FuncPtrInt), int(int*)> ff; - ff = &TestIntRet; - int ret = ff(&val); - VERIFY(ret == 3); - VERIFY(val == 4); - } - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionPointerToMemberFunction -// - -int TestFixedFunctionPointerToMemberFunction() -{ - using namespace eastl; - - struct TestVoidRet - { - TestVoidRet() : x(0) {} - ~TestVoidRet() = default; - - void IncX() const - { - ++x; - } - - void IncX() - { - ++x; - } - - mutable int x = 0; - }; - - struct TestIntRet - { - TestIntRet() : x(0) {} - - int IncX() const - { - return x++; - } - - int IncX() - { - return x++; - } - - mutable int x = 0; - }; - - int nErrorCount = 0; - TestVoidRet voidRet; - TestIntRet intRet; - const TestVoidRet cvoidRet; - const TestIntRet cintRet; - - typedef void (TestVoidRet::*PTMFSize)(void); - - { - eastl::fixed_function<sizeof(PTMFSize), void(const TestVoidRet&)> ff = static_cast<void(TestVoidRet::*)() const>(&TestVoidRet::IncX); - ff(cvoidRet); - VERIFY(cvoidRet.x == 1); - } - { - eastl::fixed_function<sizeof(PTMFSize), void(const TestVoidRet&)> ff = static_cast<void(TestVoidRet::*)() const>(&TestVoidRet::IncX); - ff(voidRet); - VERIFY(voidRet.x == 1); - } - { - eastl::fixed_function<sizeof(PTMFSize), void(TestVoidRet&)> ff = static_cast<void(TestVoidRet::*)()>(&TestVoidRet::IncX); - ff(voidRet); - VERIFY(voidRet.x == 2); - } - - { - eastl::fixed_function<sizeof(PTMFSize), int(const TestIntRet&)> ff = static_cast<int(TestIntRet::*)() const>(&TestIntRet::IncX); - int ret = ff(cintRet); - VERIFY(ret == 0); - VERIFY(cintRet.x == 1); - } - { - eastl::fixed_function<sizeof(PTMFSize), int(const TestIntRet&)> ff = static_cast<int(TestIntRet::*)() const>(&TestIntRet::IncX); - int ret = ff(intRet); - VERIFY(ret == 0); - VERIFY(intRet.x == 1); - } - { - eastl::fixed_function<sizeof(PTMFSize), int(TestIntRet&)> ff = static_cast<int(TestIntRet::*)()>(&TestIntRet::IncX); - int ret = ff(intRet); - VERIFY(ret == 1); - VERIFY(intRet.x == 2); - } - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionPointerToMemberData -// - -int TestFixedFunctionPointerToMemberData() -{ - using namespace eastl; - - struct Test - { - Test() : x(1) {} - int x = 1; - }; - - int nErrorCount = 0; - - Test t; - const Test ct; - - { - eastl::fixed_function<sizeof(void*), int(const Test&)> ff = &Test::x; - int ret = ff(t); - VERIFY(ret == 1); - } - { - eastl::fixed_function<sizeof(void*), int(const Test&)> ff = &Test::x; - int ret = ff(ct); - VERIFY(ret == 1); - } - { - eastl::fixed_function<sizeof(void*), int(const Test&)> ff; - ff = &Test::x; - int ret = ff(t); - VERIFY(ret == 1); - } - { - eastl::fixed_function<sizeof(void*), int(const Test&)> ff; - ff = &Test::x; - int ret = ff(ct); - VERIFY(ret == 1); - } - - return nErrorCount; -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionExistingClosure -// -int TestFixedFunctionExistingClosure() -{ - using namespace eastl; - - int nErrorCount = 0; - - { - TestObject to; - { - using ff_t = eastl::fixed_function<sizeof(TestObject), void(void)>; - { - ff_t ff1 = [to] {}; - ff_t ff3 = [to] {}; - TestObject::Reset(); - { - ff_t ff2 = ff1; - ff2 = ff3; // copy over function that holds existing closure state - } - VERIFY(TestObject::IsClear()); - } - { - ff_t ff1 = [to] {}; - TestObject::Reset(); - ff_t ff3 = [to] {}; - { - ff_t ff2 = ff1; - ff2 = eastl::move(ff3); // copy over function that holds existing closure state - } - VERIFY(TestObject::IsClear()); - } - { - ff_t ff1 = [to] {}; - TestObject::Reset(); - { - ff_t ff2 = ff1; - ff2 = nullptr; - } - VERIFY(TestObject::IsClear()); - } - { - TestObject::Reset(); - ff_t ff1 = [to] {}; - { - ff_t ff2 = eastl::move(ff1); - ff2 = nullptr; - } - VERIFY(TestObject::IsClear()); - } - } - } - - return nErrorCount; -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionCaptureless -// -// Tests calling a captureless (eg. function pointer) callable with variable -// eastl::fixed_function size types. -// -template<class FixedFunctionT> -int TestFixedFunctionCaptureless() -{ - int nErrorCount = 0; - - FixedFunctionT fn; - - EATEST_VERIFY(!fn); - - fn = [](int in) { return in; }; - - EATEST_VERIFY(!!fn); - - EATEST_VERIFY(fn(42) == 42); - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestFixedFunctionBasic -// -int TestFixedFunctionBasic() -{ - using namespace eastl; - - int nErrorCount = 0; - - { - struct Functor { void operator()() { return; } }; - fixed_function<24, void(void)> fn; - fixed_function<24, void(void)> fn2 = nullptr; - EATEST_VERIFY(!fn); - EATEST_VERIFY(!fn2); - EATEST_VERIFY(fn == nullptr); - EATEST_VERIFY(fn2 == nullptr); - EATEST_VERIFY(nullptr == fn); - EATEST_VERIFY(nullptr == fn2); - fn = Functor(); - fn2 = Functor(); - EATEST_VERIFY(!!fn); - EATEST_VERIFY(!!fn2); - EATEST_VERIFY(fn != nullptr); - EATEST_VERIFY(fn2 != nullptr); - EATEST_VERIFY(nullptr != fn); - EATEST_VERIFY(nullptr != fn2); - fn = nullptr; - fn2 = fn; - EATEST_VERIFY(!fn); - EATEST_VERIFY(!fn2); - EATEST_VERIFY(fn == nullptr); - EATEST_VERIFY(fn2 == nullptr); - EATEST_VERIFY(nullptr == fn); - EATEST_VERIFY(nullptr == fn2); - } - - { - using eastl::swap; - struct Functor { int operator()() { return 5; } }; - fixed_function<24, int(void)> fn = Functor(); - fixed_function<24, int(void)> fn2; - EATEST_VERIFY(fn() == 5); - EATEST_VERIFY(!fn2); - fn.swap(fn2); - EATEST_VERIFY(!fn); - EATEST_VERIFY(fn2() == 5); - swap(fn, fn2); - EATEST_VERIFY(fn() == 5); - EATEST_VERIFY(!fn2); - } - - { - struct Functor { int operator()() { return 42; } }; - fixed_function<0, int(void)> fn = Functor(); - EATEST_VERIFY(fn() == 42); - } - - { - struct Functor { int operator()(int in) { return in; } }; - fixed_function<0, int(int)> fn = Functor(); - EATEST_VERIFY(fn(24) == 24); - } - - { - eastl::fixed_function<0, void(void)> fn; - - EATEST_VERIFY(!fn); - fn = [] {}; - EATEST_VERIFY(!!fn); - } - - { - eastl::fixed_function<0, int(int)> fn = [](int param) { return param; }; - EATEST_VERIFY(fn(42) == 42); - } - - { - eastl::fixed_function<0, int(int)> fn = ReturnVal; - EATEST_VERIFY(fn(42) == 42); - } - - { - eastl::fixed_function<0, int()> fn0 = ReturnZero; - eastl::fixed_function<0, int()> fn1 = ReturnOne; - - EATEST_VERIFY(fn0() == 0 && fn1() == 1); - swap(fn0, fn1); - EATEST_VERIFY(fn0() == 1 && fn1() == 0); - } - - { - eastl::fixed_function<0, int()> fn0 = ReturnZero; - eastl::fixed_function<0, int()> fn1 = ReturnOne; - - EATEST_VERIFY(fn0() == 0 && fn1() == 1); - fn0 = fn1; - EATEST_VERIFY(fn0() == 1 && fn1() == 1); - } - - { - eastl::fixed_function<0, int()> fn0 = ReturnZero; - eastl::fixed_function<0, int()> fn1 = ReturnOne; - - EATEST_VERIFY(fn0() == 0 && fn1() == 1); - fn0 = eastl::move(fn1); - EATEST_VERIFY(fn0() == 1 && fn1 == nullptr); - } - - { - eastl::fixed_function<0, int(int)> f1(nullptr); - EATEST_VERIFY(!f1); - - eastl::fixed_function<0, int(int)> f2 = nullptr; - EATEST_VERIFY(!f2); - } - - { - // test using a large lambda capture - uint64_t a = 1, b = 2, c = 3, d = 4, e = 5, f = 6; - auto large_add = [=] { return a + b + c + d + e + f; }; - - { - eastl::fixed_function<48, uint64_t(void)> fn = large_add; - auto result = fn(); - EATEST_VERIFY(result == 21); - } - - { - eastl::fixed_function<sizeof(large_add), uint64_t(void)> fn = large_add; - auto result = fn(); - EATEST_VERIFY(result == 21); - } - } - - { - using ff_0 = eastl::fixed_function<0, int(int)>; - using ff_1 = eastl::fixed_function<1, int(int)>; - using ff_4 = eastl::fixed_function<4, int(int)>; - using ff_8 = eastl::fixed_function<8, int(int)>; - using ff_64 = eastl::fixed_function<64, int(int)>; - using ff_128 = eastl::fixed_function<128, int(int)>; - using ff_4096 = eastl::fixed_function<4096, int(int)>; - - static_assert(sizeof(ff_0) >= sizeof(void*), "error"); - static_assert(sizeof(ff_1) >= sizeof(void*), "error"); - static_assert(sizeof(ff_4) >= sizeof(void*), "error"); - static_assert(sizeof(ff_8) >= 8, "error"); - static_assert(sizeof(ff_64) >= 64, "error"); - static_assert(sizeof(ff_128) >= 128, "error"); - static_assert(sizeof(ff_4096) >= 4096, "error"); - - nErrorCount += TestFixedFunctionCaptureless<ff_0>(); - nErrorCount += TestFixedFunctionCaptureless<ff_1>(); - nErrorCount += TestFixedFunctionCaptureless<ff_4>(); - nErrorCount += TestFixedFunctionCaptureless<ff_8>(); - nErrorCount += TestFixedFunctionCaptureless<ff_64>(); - nErrorCount += TestFixedFunctionCaptureless<ff_128>(); - nErrorCount += TestFixedFunctionCaptureless<ff_4096>(); - } - - // Verify conversions to fixed_function<N> for sizes greater or equal to the source size. - { - uint32_t v0 = 130480, v1 = 936780302; - const uint32_t result = v0 + v1; - - eastl::fixed_function<8, uint32_t(void)> ff8 = [v0, v1] - { return v0 + v1; }; - - { - eastl::fixed_function<16, uint32_t(void)> ff16(ff8); - VERIFY(result == ff16()); - } - - { - eastl::fixed_function<16, uint32_t(void)> ff16 = ff8; - VERIFY(result == ff16()); - } - - { - eastl::fixed_function<16, uint32_t(void)> ff16; - ff16 = ff8; - VERIFY(result == ff16()); - } - - { - auto ff8Copy = ff8; - eastl::fixed_function<16, uint32_t(void)> ff16(eastl::move(ff8Copy)); - VERIFY(result == ff16()); - } - - { - auto ff8Copy = ff8; - eastl::fixed_function<16, uint32_t(void)> ff16 = eastl::move(ff8Copy); - VERIFY(result == ff16()); - } - - { - auto ff8Copy = ff8; - eastl::fixed_function<16, uint32_t(void)> ff16; - ff16 = eastl::move(ff8Copy); - VERIFY(result == ff16()); - } - } - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestFunctional -// -int TestFixedFunction() -{ - using namespace eastl; - - int nErrorCount = 0; - - nErrorCount += TestFixedFunctionBasic(); - nErrorCount += TestFixedFunctionDtor(); - nErrorCount += TestFixedFunctionExistingClosure(); - nErrorCount += TestFixedFunctionReferenceWrapper(); - nErrorCount += TestFixedFunctionFunctionPointer(); - nErrorCount += TestFixedFunctionPointerToMemberFunction(); - nErrorCount += TestFixedFunctionPointerToMemberData(); - nErrorCount += TestFixedFunctionStdBind(); - - return nErrorCount; -} diff --git a/test/source/TestFixedHash.cpp b/test/source/TestFixedHash.cpp deleted file mode 100644 index d7e20d0..0000000 --- a/test/source/TestFixedHash.cpp +++ /dev/null @@ -1,744 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include <EABase/eabase.h> -#include "EASTLTest.h" -#include "TestMap.h" -#include "TestSet.h" -#include <EASTL/fixed_hash_set.h> -#include <EASTL/fixed_hash_map.h> -#include <EASTL/fixed_vector.h> - - - - -using namespace eastl; - - -struct A -{ - int mX; - A(int x = 999) : mX(x) {} -}; - -inline bool operator==(const A& a1, const A& a2) - { return a1.mX == a2.mX; } - - - -namespace eastl -{ - template <> - struct hash<A> - { - size_t operator()(const A& a) const - { return static_cast<size_t>(a.mX); } - }; -} - - -/////////////////////////////////////////////////////////////////////////////// -// For test of user-reported crash. -// -struct MemoryEntry -{ - size_t mSize; - void* mGroup; -}; -/////////////////////////////////////////////////////////////////////////////// - - - -/////////////////////////////////////////////////////////////////////////////// -// For test of bug reported by Dave Wall, May 14, 2008. -// -struct InstanceRenderData -{ - static const uint32_t kDataCount = 10; // Bug only occurs with this value. - - uint32_t mPad[kDataCount]; - - InstanceRenderData() - { - memset(mPad, 0, sizeof(mPad)); - } - - bool operator==(const InstanceRenderData &rhs) const - { - for(uint32_t index = 0; index < kDataCount; index++) - { - if(mPad[index] != rhs.mPad[index]) - { - return false; - } - } - - return true; - } -}; - -namespace eastl -{ - template <> - struct hash<const InstanceRenderData> - { - size_t operator()(InstanceRenderData val) const - { - return val.mPad[0]; - } - }; - - template <> - struct hash<InstanceRenderData> - { - size_t operator()(InstanceRenderData val) const - { - return val.mPad[0]; - } - }; -} -/////////////////////////////////////////////////////////////////////////////// - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::fixed_hash_set<int, 1, 2>; -template class eastl::fixed_hash_map<int, int, 1, 2>; -template class eastl::fixed_hash_multiset<int, 1, 2>; -template class eastl::fixed_hash_multimap<int, int, 1, 2>; - -template class eastl::fixed_hash_set<A, 1, 2>; -template class eastl::fixed_hash_map<A, A, 1, 2>; -template class eastl::fixed_hash_multiset<A, 1, 2>; -template class eastl::fixed_hash_multimap<A, A, 1, 2>; - -template class eastl::fixed_hash_set<int, 1, 2, true, eastl::hash<int>, eastl::equal_to<int>, true>; -template class eastl::fixed_hash_map<int, int, 1, 2, true, eastl::hash<int>, eastl::equal_to<int>, true>; -template class eastl::fixed_hash_multiset<int, 1, 2, true, eastl::hash<int>, eastl::equal_to<int>, true>; -template class eastl::fixed_hash_multimap<int, int, 1, 2, true, eastl::hash<int>, eastl::equal_to<int>, true>; - -template class eastl::fixed_hash_set<A, 1, 2, true, eastl::hash<A>, eastl::equal_to<A>, true>; -template class eastl::fixed_hash_map<A, A, 1, 2, true, eastl::hash<A>, eastl::equal_to<A>, true>; -template class eastl::fixed_hash_multiset<A, 1, 2, true, eastl::hash<A>, eastl::equal_to<A>, true>; -template class eastl::fixed_hash_multimap<A, A, 1, 2, true, eastl::hash<A>, eastl::equal_to<A>, true>; - -// Custom allocator -template class eastl::fixed_hash_set<int, 1, 2, true, eastl::hash<int>, eastl::equal_to<int>, false, MallocAllocator>; -template class eastl::fixed_hash_map<int, int, 1, 2, true, eastl::hash<int>, eastl::equal_to<int>, false, MallocAllocator>; -template class eastl::fixed_hash_multiset<int, 1, 2, true, eastl::hash<int>, eastl::equal_to<int>, false, MallocAllocator>; -template class eastl::fixed_hash_multimap<int, int, 1, 2, true, eastl::hash<int>, eastl::equal_to<int>, false, MallocAllocator>; - -template class eastl::fixed_hash_set<A, 1, 2, true, eastl::hash<A>, eastl::equal_to<A>, false, MallocAllocator>; -template class eastl::fixed_hash_map<A, A, 1, 2, true, eastl::hash<A>, eastl::equal_to<A>, false, MallocAllocator>; -template class eastl::fixed_hash_multiset<A, 1, 2, true, eastl::hash<A>, eastl::equal_to<A>, false, MallocAllocator>; -template class eastl::fixed_hash_multimap<A, A, 1, 2, true, eastl::hash<A>, eastl::equal_to<A>, false, MallocAllocator>; - - - -template<typename FixedHashMap, int ELEMENT_MAX, int ITERATION_MAX> -int TestFixedHashMapClearBuckets() -{ - int nErrorCount = 0; - - FixedHashMap fixedHashMap; - const auto nPreClearBucketCount = fixedHashMap.bucket_count(); - - for (int j = 0; j < ITERATION_MAX; j++) - { - // add elements and ensure container is valid - for (int i = 0; i < int(nPreClearBucketCount); i++) - fixedHashMap.emplace(i, i); - VERIFY(fixedHashMap.validate()); - - // ensure contents are expected values - for (int i = 0; i < int(nPreClearBucketCount); i++) - { - auto iter = fixedHashMap.find(i); - - VERIFY(iter != fixedHashMap.end()); - VERIFY(iter->second == i); - } - - // validate container after its cleared its nodes and buckets - fixedHashMap.clear(true); - VERIFY(fixedHashMap.validate()); - VERIFY(fixedHashMap.size() == 0); - VERIFY(fixedHashMap.bucket_count() == nPreClearBucketCount); - } - - return nErrorCount; -} - - -EA_DISABLE_VC_WARNING(6262) -int TestFixedHash() -{ - int nErrorCount = 0; - - { // fixed_hash_map - { - // Test version *without* pool overflow. - typedef eastl::fixed_hash_map<int, int, 100, 100, false> FixedHashMapFalse; - FixedHashMapFalse fixedHashMap; - - fixedHashMap[0] = 0; - fixedHashMap.insert(FixedHashMapFalse::value_type(0, 0)); - - VERIFY(fixedHashMap.max_size() == 100); - VERIFY(fixedHashMap.size() == 1); - - fixedHashMap.clear(); - VERIFY(fixedHashMap.size() == 0); - - for(int i = 0; i < 100; i++) - fixedHashMap.insert(FixedHashMapFalse::value_type(i, i)); - VERIFY(fixedHashMap.size() == 100); - - // Verify that we allocated enough space for exactly N items. - // It's possible that due to alignments, there might be room for N + 1. - FixedHashMapFalse::allocator_type& allocator = fixedHashMap.get_allocator(); - void* pResult = allocator.allocate(sizeof(FixedHashMapFalse::node_type)); - if(pResult) - { - pResult = allocator.allocate(sizeof(FixedHashMapFalse::node_type)); - VERIFY(pResult == NULL); - } - - fixedHashMap.clear(true); - VERIFY(fixedHashMap.validate()); - VERIFY(fixedHashMap.size() == 0); - VERIFY(fixedHashMap.bucket_count() == fixedHashMap.rehash_policy().GetPrevBucketCount(100)); - } - - { - // Test version *with* pool overflow. - typedef eastl::fixed_hash_map<int, int, 100, 100, true> FixedHashMapTrue; - FixedHashMapTrue fixedHashMap; - - fixedHashMap[0] = 0; - fixedHashMap.insert(FixedHashMapTrue::value_type(0, 0)); - - VERIFY(fixedHashMap.max_size() == 100); - VERIFY(fixedHashMap.size() == 1); - - fixedHashMap.clear(); - VERIFY(fixedHashMap.size() == 0); - - for(int i = 0; i < 100; i++) - fixedHashMap.insert(FixedHashMapTrue::value_type(i, i)); - VERIFY(fixedHashMap.size() == 100); - - FixedHashMapTrue::allocator_type& allocator = fixedHashMap.get_allocator(); - void* pResult = allocator.allocate(sizeof(FixedHashMapTrue::node_type)); - VERIFY(pResult != NULL); - allocator.deallocate(pResult, sizeof(FixedHashMapTrue::node_type)); - - fixedHashMap.clear(true); - VERIFY(fixedHashMap.validate()); - VERIFY(fixedHashMap.size() == 0); - VERIFY(fixedHashMap.bucket_count() == fixedHashMap.rehash_policy().GetPrevBucketCount(100)); - - // get_overflow_allocator / set_overflow_allocator - // This is a weak test which should be improved. - EASTLAllocatorType a = fixedHashMap.get_allocator().get_overflow_allocator(); - fixedHashMap.get_allocator().set_overflow_allocator(a); - } - - // Test that fixed_hash_map (with and without overflow enabled) is usable after the node and bucket array has - // been cleared. - { - constexpr const int ITERATION_MAX = 5; - constexpr const int ELEMENT_MAX = 100; - constexpr const int ELEMENT_OVERFLOW_MAX = ELEMENT_MAX * 2; - - TestFixedHashMapClearBuckets<eastl::fixed_hash_map<int, int, ELEMENT_MAX, ELEMENT_MAX, false>, ELEMENT_MAX, ITERATION_MAX>(); - TestFixedHashMapClearBuckets<eastl::fixed_hash_map<int, int, ELEMENT_MAX, ELEMENT_MAX, true>, ELEMENT_OVERFLOW_MAX, ITERATION_MAX>(); - TestFixedHashMapClearBuckets<eastl::fixed_hash_multimap<int, int, ELEMENT_MAX, ELEMENT_MAX, false>, ELEMENT_MAX, ITERATION_MAX>(); - TestFixedHashMapClearBuckets<eastl::fixed_hash_multimap<int, int, ELEMENT_MAX, ELEMENT_MAX, true>, ELEMENT_OVERFLOW_MAX, ITERATION_MAX>(); - } - - { - // Test fixed_hash_map *with* overflow and ensure the underlying hashtable rehashes. - typedef eastl::fixed_hash_map<unsigned int, unsigned int, 512, 513, true, eastl::hash<unsigned int>, eastl::equal_to<unsigned int>, false, MallocAllocator> FixedHashMap; - - FixedHashMap fixedHashMap; - auto old_bucket_count = fixedHashMap.bucket_count(); - auto old_load_factor = fixedHashMap.load_factor(); - - for (int i = 0; i < 1000; i++) - fixedHashMap.insert(i); - - auto new_bucket_count = fixedHashMap.bucket_count(); - auto new_load_factor = fixedHashMap.load_factor(); - - VERIFY(new_bucket_count != old_bucket_count); - VERIFY(new_bucket_count > old_bucket_count); - VERIFY(new_load_factor != old_load_factor); - VERIFY(fixedHashMap.get_overflow_allocator().mAllocCountAll != 0); - } - - { - // Test version with overflow and alignment requirements. - typedef fixed_hash_map<Align64, int, 1, 2, true> FixedHashMapWithAlignment; - typedef fixed_hash_multimap<Align64, int, 1, 2, true> FixedHashMultiMapWithAlignment; - typedef fixed_hash_set<Align64, 1, 2, true> FixedHashSetWithAlignment; - typedef fixed_hash_multiset<Align64, 1, 2, true> FixedHashMultiSetWithAlignment; - - FixedHashMapWithAlignment fhm; - FixedHashMultiMapWithAlignment fhmm; - FixedHashSetWithAlignment fhs; - FixedHashMultiSetWithAlignment fhms; - - Align64 a; a.mX = 1; - Align64 b; b.mX = 2; - Align64 c; c.mX = 3; - Align64 d; d.mX = 4; - Align64 e; e.mX = 5; - - fhm.insert(a); - fhm.insert(b); - fhm.insert(c); - fhm.insert(d); - fhm.insert(e); - for (FixedHashMapWithAlignment::const_iterator it = fhm.begin(); it != fhm.end(); ++it) - { - const Align64* ptr = &((*it).first); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - fhmm.insert(a); - fhmm.insert(b); - fhmm.insert(c); - fhmm.insert(d); - fhmm.insert(e); - for (FixedHashMultiMapWithAlignment::const_iterator it = fhmm.begin(); it != fhmm.end(); ++it) - { - const Align64* ptr = &((*it).first); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - fhs.insert(a); - fhs.insert(b); - fhs.insert(c); - fhs.insert(d); - fhs.insert(e); - for (FixedHashSetWithAlignment::const_iterator it = fhs.begin(); it != fhs.end(); ++it) - { - const Align64* ptr = &(*it); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - fhms.insert(a); - fhms.insert(b); - fhms.insert(c); - fhms.insert(d); - fhms.insert(e); - for (FixedHashMultiSetWithAlignment::const_iterator it = fhms.begin(); it != fhms.end(); ++it) - { - const Align64* ptr = &(*it); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - } - - { - typedef eastl::fixed_hash_map<int, A, 100, 100> FixedHashMap; - FixedHashMap fixedHashMap; - - fixedHashMap[0] = A(); - fixedHashMap.insert(FixedHashMap::value_type(0, A())); - - VERIFY(fixedHashMap.size() == 1); - } - - { - typedef eastl::fixed_hash_map<A, int, 100, 100> FixedHashMap; - FixedHashMap fixedHashMap; - - fixedHashMap[A()] = 0; - fixedHashMap.insert(FixedHashMap::value_type(A(), 0)); - - VERIFY(fixedHashMap.size() == 1); - } - - // explicitly instantiate some templated member functions - { - typedef eastl::fixed_hash_map<int, int, 100, 100, true> FixedHashMapTrue; - FixedHashMapTrue::value_type testValues[] = { eastl::make_pair(0, 0), eastl::make_pair(1,1) }; - FixedHashMapTrue fixedHashMap(testValues, testValues + EAArrayCount(testValues)); - VERIFY(fixedHashMap.size() == 2); - } - } - - - { // fixed_hash_multimap - { - typedef eastl::fixed_hash_multimap<int, int, 100, 100> FixedHashMultiMap; - FixedHashMultiMap fixedHashMultiMap; - - fixedHashMultiMap.insert(FixedHashMultiMap::value_type(0, 0)); - fixedHashMultiMap.insert(FixedHashMultiMap::value_type(0, 0)); - - VERIFY(fixedHashMultiMap.max_size() == 100); - VERIFY(fixedHashMultiMap.size() == 2); - } - - // explicitly instantiate some templated member functions - { - typedef eastl::fixed_hash_multimap<int, int, 100, 100, true> FixedHashMultiMap; - FixedHashMultiMap::value_type testValues[] = { eastl::make_pair(0, 0), eastl::make_pair(1,1) }; - FixedHashMultiMap fixedHashMultiMap(testValues, testValues + EAArrayCount(testValues)); - VERIFY(fixedHashMultiMap.size() == 2); - } - } - - - { // fixed_hash_set - { - typedef eastl::fixed_hash_set<int, 100, 100> FixedHashSet; - FixedHashSet fixedHashSet; - - fixedHashSet.insert(0); - fixedHashSet.insert(0); - VERIFY(fixedHashSet.size() == 1); - - fixedHashSet.clear(); - VERIFY(fixedHashSet.size() == 0); - - for(int i = 0; i < 100; i++) - fixedHashSet.insert(i); - - VERIFY(fixedHashSet.max_size() == 100); - VERIFY(fixedHashSet.size() == 100); - - fixedHashSet.clear(true); - VERIFY(fixedHashSet.validate()); - VERIFY(fixedHashSet.size() == 0); - VERIFY(fixedHashSet.bucket_count() == 1); - } - - { - typedef eastl::fixed_hash_set<A, 100, 100> FixedHashSet; - FixedHashSet fixedHashSet; - - fixedHashSet.insert(A()); - fixedHashSet.insert(A()); - - VERIFY(fixedHashSet.max_size() == 100); - VERIFY(fixedHashSet.size() == 1); - } - - // explicitly instantiate some templated member functions - { - typedef eastl::fixed_hash_set<A, 100, 100> FixedHashSet; - FixedHashSet::value_type testValues[] = { 0, 1 }; - FixedHashSet fixedHashSet(testValues, testValues + EAArrayCount(testValues)); - VERIFY(fixedHashSet.size() == 2); - } - } - - - { // fixed_hash_multiset - { - typedef eastl::fixed_hash_multiset<int, 100, 100> FixedHashMultiSet; - FixedHashMultiSet fixedHashMultiSet; - - fixedHashMultiSet.insert(0); - fixedHashMultiSet.insert(0); - - VERIFY(fixedHashMultiSet.size() == 2); - } - - - // explicitly instantiate some templated member functions - { - typedef eastl::fixed_hash_multiset<A, 100, 100> FixedHashMultiSet; - FixedHashMultiSet::value_type testValues[] = { 0, 1 }; - FixedHashMultiSet fixedHashMultiSet(testValues, testValues + EAArrayCount(testValues)); - VERIFY(fixedHashMultiSet.size() == 2); - } - } - - - { // Tests of various bucketCount values. - { - typedef eastl::fixed_hash_set<int, 1, 2> FixedHashSet; - FixedHashSet fixedHashSet; - - fixedHashSet.insert(0); - - VERIFY(fixedHashSet.size() == 1); - } - - { - typedef eastl::fixed_hash_set<int, 2, 2> FixedHashSet; - FixedHashSet fixedHashSet; - - fixedHashSet.insert(0); - fixedHashSet.insert(1); - - VERIFY(fixedHashSet.size() == 2); - } - - { - typedef eastl::fixed_hash_set<int, 11, 11> FixedHashSet; // 11 is one of the hashtable prime numbers. - FixedHashSet fixedHashSet; - - for(int i = 0; i < 11; i++) - fixedHashSet.insert(i); - - VERIFY(fixedHashSet.size() == 11); - } - - - { - typedef eastl::fixed_hash_set<int, 11, 11> FixedHashSet; // 11 is one of the hashtable prime numbers. - FixedHashSet fixedHashSet; - - VERIFY(fixedHashSet.validate()); - VERIFY(fixedHashSet.size() == 0); - - // Clear a newly constructed, already empty container. - fixedHashSet.clear(true); - VERIFY(fixedHashSet.validate()); - VERIFY(fixedHashSet.size() == 0); - VERIFY(fixedHashSet.bucket_count() == 1); - - for(int i = 0; i < 11; i++) - fixedHashSet.insert(i); - VERIFY(fixedHashSet.size() == 11); - VERIFY(fixedHashSet.bucket_count() > 1); - - fixedHashSet.clear(true); - VERIFY(fixedHashSet.validate()); - VERIFY(fixedHashSet.size() == 0); - VERIFY(fixedHashSet.bucket_count() == 1); - - for(int i = 0; i < 11; i++) - fixedHashSet.insert(i); - VERIFY(fixedHashSet.size() == 11); - } - } - - { // Test of user-reported crash. - - // MemoryAddressToGroupMap is a container used by one team to associate debug - // information with memory allocations. A crash due to corruption of the - // fixed size node pool was reported on consoles (no crash on PC platform). - const eastl_size_t kMemoryAddressMapNodeCount = 500000; - - typedef eastl::fixed_hash_map< - const void*, // Key - MemoryEntry, // Value - kMemoryAddressMapNodeCount, // Node Count - kMemoryAddressMapNodeCount + 1, // Bucket Count - true, // Enable Overflow - eastl::hash<const void*>, // Hash - eastl::equal_to<const void*>, // Predicate - false, // Cache Hash Code - eastl::allocator // Allocator - > MemoryAddressToGroupMap; - - MemoryAddressToGroupMap* pMap = new MemoryAddressToGroupMap; - EA::UnitTest::Rand rng(EA::UnitTest::GetRandSeed()); - - // We simulate the usage of MemoryAddressToGroupMap via simulated alloc/free actions. - for(eastl_size_t i = 0; i < kMemoryAddressMapNodeCount * 2; i++) - { - void* const p = (void*)(uintptr_t)rng.RandLimit(kMemoryAddressMapNodeCount); - - if(pMap->find(p) == pMap->end()) - (*pMap)[p] = MemoryEntry(); - else - pMap->erase(p); - } - - delete pMap; - } - - - { // Test of bug reported by Dave Wall, May 14, 2008. - const size_t kNumBuckets = 10; // Bug only occurred with kNumBuckets == 10 or 11. - - typedef eastl::fixed_hash_map<const InstanceRenderData, uint32_t, kNumBuckets, kNumBuckets + 1, false> Map; - - Map map; - InstanceRenderData renderData; - - uint32_t count = (uint32_t)kNumBuckets; - - while(count--) - { - renderData.mPad[0] = count; - map.insert(Map::value_type(renderData, count)); - } - - } - - { - // Test construction of a container with an overflow allocator constructor argument. - MallocAllocator overflowAllocator; - void* p = overflowAllocator.allocate(1); - - typedef eastl::fixed_hash_map<int, int, 64, 100, true, eastl::hash<int>, eastl::equal_to<int>, false, MallocAllocator> Container; - Container c(overflowAllocator); - - for(int i = 0; i < 65; i++) - c.insert(Container::value_type(i, i)); - - VERIFY(c.get_overflow_allocator().mAllocCount == 2); // 1 for above, and 1 for overflowing from 64 to 65. - overflowAllocator.deallocate(p, 1); - } - - - { - // C++11 emplace and related functionality - nErrorCount += TestMapCpp11<eastl::fixed_hash_map<int, TestObject, 2, 7, true> >(); // Exercize a low-capacity fixed-size container. - nErrorCount += TestMapCpp11<eastl::fixed_hash_map<int, TestObject, 32, 7, true> >(); - - nErrorCount += TestMapCpp11NonCopyable<eastl::fixed_hash_map<int, NonCopyable, 2, 7, true>>(); - - nErrorCount += TestSetCpp11<eastl::fixed_hash_set<TestObject, 2, 7, true> >(); - nErrorCount += TestSetCpp11<eastl::fixed_hash_set<TestObject, 32, 7, true> >(); - - nErrorCount += TestMultimapCpp11<eastl::fixed_hash_multimap<int, TestObject, 2, 7, true> >(); - nErrorCount += TestMultimapCpp11<eastl::fixed_hash_multimap<int, TestObject, 32, 7, true> >(); - - nErrorCount += TestMultisetCpp11<eastl::fixed_hash_multiset<TestObject, 2, 7, true> >(); - nErrorCount += TestMultisetCpp11<eastl::fixed_hash_multiset<TestObject, 32, 7, true> >(); - } - - { - // C++17 try_emplace and related functionality - nErrorCount += TestMapCpp17<eastl::fixed_hash_map<int, TestObject, 2, 7, true>>(); - nErrorCount += TestMapCpp17<eastl::fixed_hash_map<int, TestObject, 32, 7, true> >(); - } - - { - // void reserve(size_type nElementCount); - - // test with overflow enabled. - nErrorCount += HashContainerReserveTest<fixed_hash_set<int, 16>>()(); - nErrorCount += HashContainerReserveTest<fixed_hash_multiset<int, 16>>()(); - nErrorCount += HashContainerReserveTest<fixed_hash_map<int, int, 16>>()(); - nErrorCount += HashContainerReserveTest<fixed_hash_multimap<int, int, 16>>()(); - - // API prevents testing fixed size hash container reservation without overflow enabled. - // - // nErrorCount += HashContainerReserveTest<fixed_hash_set<int, 400, 401, false>>()(); - // nErrorCount += HashContainerReserveTest<fixed_hash_multiset<int, 400, 401, false>>()(); - // nErrorCount += HashContainerReserveTest<fixed_hash_map<int, int, 400, 401, false>>()(); - // nErrorCount += HashContainerReserveTest<fixed_hash_multimap<int, int, 9000, 9001, false>>()(); - } - - { - // initializer_list support. - // fixed_hash_set(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_HASH_SET_DEFAULT_ALLOCATOR) - // this_type& operator=(std::initializer_list<value_type> ilist); - // void insert(std::initializer_list<value_type> ilist); - fixed_hash_set<int, 11> intHashSet = { 12, 13, 14 }; - EATEST_VERIFY(intHashSet.size() == 3); - EATEST_VERIFY(intHashSet.find(12) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(13) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(14) != intHashSet.end()); - - intHashSet = { 22, 23, 24 }; - EATEST_VERIFY(intHashSet.size() == 3); - EATEST_VERIFY(intHashSet.find(22) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(23) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(24) != intHashSet.end()); - - intHashSet.insert({ 42, 43, 44 }); - EATEST_VERIFY(intHashSet.size() == 6); - EATEST_VERIFY(intHashSet.find(42) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(43) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(44) != intHashSet.end()); - - // hash_map(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_HASH_SET_DEFAULT_ALLOCATOR) - // this_type& operator=(std::initializer_list<value_type> ilist); - // void insert(std::initializer_list<value_type> ilist); - fixed_hash_map<int, double, 11> intHashMap = { {12,12.0}, {13,13.0}, {14,14.0} }; - EATEST_VERIFY(intHashMap.size() == 3); - EATEST_VERIFY(intHashMap.find(12) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(13) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(14) != intHashMap.end()); - - intHashMap = { {22,22.0}, {23,23.0}, {24,24.0} }; - EATEST_VERIFY(intHashMap.size() == 3); - EATEST_VERIFY(intHashMap.find(22) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(23) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(24) != intHashMap.end()); - - intHashMap.insert({ {42,42.0}, {43,43.0}, {44,44.0} }); - EATEST_VERIFY(intHashMap.size() == 6); - EATEST_VERIFY(intHashMap.find(42) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(43) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(44) != intHashMap.end()); - } - - { - constexpr int ELEM_MAX = 10; - typedef eastl::fixed_hash_map<int, int, ELEM_MAX, ELEM_MAX, false> FixedHashMapFalse; - FixedHashMapFalse fixedHashMap; - VERIFY(fixedHashMap.size() == 0); - - for (int i = 0; i < ELEM_MAX; i++) - fixedHashMap.insert(FixedHashMapFalse::value_type(i, i)); - - VERIFY(fixedHashMap.validate()); - VERIFY(fixedHashMap.size() == ELEM_MAX); - - // Verify insert requests of nodes already in the container don't attempt to allocate memory. - // Because the fixed_hash_map is full any attempt to allocate memory will generate an OOM error. - { - auto result = fixedHashMap.insert(FixedHashMapFalse::value_type(0, 0)); - VERIFY(result.second == false); - } - - { - auto result = fixedHashMap.insert(fixedHashMap.begin(), FixedHashMapFalse::value_type(0, 0)); - VERIFY(result->first == 0); - VERIFY(result->second == 0); - } - - { - FixedHashMapFalse::value_type value(0, 0); - auto result = fixedHashMap.insert(eastl::move(value)); - VERIFY(result.second == false); - } - { - FixedHashMapFalse::value_type value(0, 0); - auto result = fixedHashMap.insert(fixedHashMap.begin(), eastl::move(value)); - VERIFY(result->first == 0); - VERIFY(result->second == 0); - } - - { - FixedHashMapFalse::value_type value(0, 0); - auto result = fixedHashMap.insert(value); - VERIFY(result.second == false); - } - - { - auto result = fixedHashMap.insert(eastl::make_pair(0, 0)); - VERIFY(result.second == false); - } - - { - // OOM, fixed allocator memory is exhausted so it can't create a node for insertation testing - // auto result = fixedHashMap.emplace(0, 0); - // VERIFY(result.second == false); - } - } - - return nErrorCount; -} -EA_RESTORE_VC_WARNING() - - - - - - - - - diff --git a/test/source/TestFixedList.cpp b/test/source/TestFixedList.cpp deleted file mode 100644 index 9212559..0000000 --- a/test/source/TestFixedList.cpp +++ /dev/null @@ -1,563 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/fixed_list.h> - - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::fixed_list<int, 1, true, EASTLAllocatorType>; -template class eastl::fixed_list<int, 1, false, EASTLAllocatorType>; - - -/* -// This does not compile, since the fixed_list allocator is templated on sizeof(T), -// not just T. Thus, the full type is required at the time of instantiation, but it -// is not available. -// See EATech Core JIRA issue ETCR-1608 for more information. -struct StructWithContainerOfStructs -{ - eastl::fixed_list<StructWithContainerOfStructs,4> children; -}; -*/ - - -namespace FixedListTest -{ - struct Item - { - char mName[5]; - }; -} - - -EA_DISABLE_VC_WARNING(6262) -int TestFixedList() -{ - int nErrorCount = 0; - - { - // Test version *without* pool overflow. - typedef fixed_list<int, 64, false> FixedListInt64False; - - FixedListInt64False listInt64; - VERIFY(listInt64.empty()); - VERIFY(listInt64.size() == 0); - VERIFY(listInt64.max_size() == 64); - - listInt64.push_back(1); - VERIFY(!listInt64.empty()); - VERIFY(listInt64.size() == 1); - - listInt64.resize(3, 2); - VERIFY(!listInt64.empty()); - VERIFY(listInt64.size() == 3); - - FixedListInt64False::iterator i = listInt64.begin(); - VERIFY(*i == 1); ++i; - VERIFY(*i == 2); ++i; - VERIFY(*i == 2); ++i; - VERIFY(i == listInt64.end()); - - listInt64.resize(0); - VERIFY(listInt64.empty()); - VERIFY(listInt64.size() == 0); - - while(listInt64.size() < 64) - listInt64.push_back(0); - - // Verify that we allocated enough space for exactly N items. - // It's possible that due to alignments, there might be room for N + 1. - FixedListInt64False::allocator_type& allocator = listInt64.get_allocator(); - void* pResult = allocator.allocate(sizeof(FixedListInt64False::node_type)); - if(pResult) - { - pResult = allocator.allocate(sizeof(FixedListInt64False::node_type)); - VERIFY(pResult == NULL); - } - } - - - { - // Test version *with* pool overflow. - typedef fixed_list<int, 64, true> FixedListInt64True; - - FixedListInt64True listInt64; - VERIFY(listInt64.empty()); - VERIFY(listInt64.size() == 0); - - listInt64.push_back(1); - VERIFY(!listInt64.empty()); - VERIFY(listInt64.size() == 1); - - listInt64.resize(3, 2); - VERIFY(!listInt64.empty()); - VERIFY(listInt64.size() == 3); - - FixedListInt64True::iterator i = listInt64.begin(); - VERIFY(*i == 1); ++i; - VERIFY(*i == 2); ++i; - VERIFY(*i == 2); ++i; - VERIFY(i == listInt64.end()); - - listInt64.resize(0); - VERIFY(listInt64.empty()); - VERIFY(listInt64.size() == 0); - - while(listInt64.size() < 64 + 16) - listInt64.push_back(0); - - FixedListInt64True::allocator_type& allocator = listInt64.get_allocator(); - void* pResult = allocator.allocate(sizeof(FixedListInt64True::node_type)); - VERIFY(pResult != NULL); - allocator.deallocate(pResult, sizeof(FixedListInt64True::node_type)); - - // get_overflow_allocator / set_overflow_allocator - // This is a weak test which should be improved. - EASTLAllocatorType a = listInt64.get_allocator().get_overflow_allocator(); - listInt64.get_allocator().set_overflow_allocator(a); - } - - - { - // Test version *with* pool overflow with a custom overlow allocator specification. - typedef fixed_list<int, 64, true, MallocAllocator> FixedListInt64TrueMalloc; - - FixedListInt64TrueMalloc listInt64; - VERIFY(listInt64.empty()); - VERIFY(listInt64.size() == 0); - - listInt64.push_back(1); - VERIFY(!listInt64.empty()); - VERIFY(listInt64.size() == 1); - - listInt64.resize(3, 2); - VERIFY(!listInt64.empty()); - VERIFY(listInt64.size() == 3); - - FixedListInt64TrueMalloc::iterator i = listInt64.begin(); - VERIFY(*i == 1); ++i; - VERIFY(*i == 2); ++i; - VERIFY(*i == 2); ++i; - VERIFY(i == listInt64.end()); - - listInt64.resize(0); - VERIFY(listInt64.empty()); - VERIFY(listInt64.size() == 0); - - while(listInt64.size() < 64 + 16) - listInt64.push_back(0); - - FixedListInt64TrueMalloc::allocator_type& allocator = listInt64.get_allocator(); - void* pResult = allocator.allocate(sizeof(FixedListInt64TrueMalloc::node_type)); - VERIFY(pResult != NULL); - allocator.deallocate(pResult, sizeof(FixedListInt64TrueMalloc::node_type)); - } - - { - // Test fixed list with overflow and alignment requirements. - typedef fixed_list<Align64, 1, true, CustomAllocator> FixedListWithAlignment; - - FixedListWithAlignment fl; - - Align64 a; - - fl.push_back(a); - fl.push_back(a); - fl.push_back(a); - fl.push_back(a); - fl.push_back(a); - for (FixedListWithAlignment::const_iterator it = fl.begin(); it != fl.end(); ++it) - { - const Align64* ptr = &(*it); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - } - - { - // swap - - fixed_list<int, 64>* pListInt64A = new fixed_list<int, 64>; - fixed_list<int, 64>* pListInt64B = new fixed_list<int, 64>; - - pListInt64A->push_back(0); - pListInt64B->push_back(0); - - swap(*pListInt64A, *pListInt64B); - - delete pListInt64A; - delete pListInt64B; - } - - - { - // operator= - - fixed_list<int, 64>* pListInt64A = new fixed_list<int, 64>; - fixed_list<int, 64>* pListInt64B = new fixed_list<int, 64>; - - pListInt64A->push_back(0); - pListInt64B->push_back(0); - - *pListInt64A = *pListInt64B; - - delete pListInt64A; - delete pListInt64B; - } - - - { - // bool empty() const - // bool has_overflowed() const - // size_type size() const; - // size_type max_size() const - - // Test a list that has overflow disabled. - fixed_list<int, 5, false> listInt5; - - VERIFY(listInt5.max_size() == 5); - VERIFY(listInt5.size() == 0); - VERIFY(listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_back(37); - listInt5.push_back(37); - listInt5.push_back(37); - - VERIFY(listInt5.size() == 3); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_back(37); - listInt5.push_back(37); - - VERIFY(listInt5.size() == 5); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.pop_back(); - - VERIFY(listInt5.size() == 4); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - } - - - { - // bool empty() const - // bool has_overflowed() const - // size_type size() const; - // size_type max_size() const - - // Test a list that has overflow enabled. - fixed_list<int, 5, true> listInt5; - - VERIFY(listInt5.max_size() == 5); - VERIFY(listInt5.size() == 0); - VERIFY(listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_back(37); - listInt5.push_back(37); - listInt5.push_back(37); - - VERIFY(listInt5.size() == 3); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_back(37); - listInt5.push_back(37); - - VERIFY(listInt5.size() == 5); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_back(37); - - VERIFY(listInt5.size() == 6); - VERIFY(!listInt5.empty()); - VERIFY(listInt5.has_overflowed()); - - listInt5.pop_back(); - - VERIFY(listInt5.size() == 5); - VERIFY(!listInt5.empty()); - //VERIFY(listInt5.has_overflowed()); Disabled because currently has_overflowed can't detect this situation in non-debug builds. - } - - { - //template <typename Compare> - //void merge(this_type& x, Compare compare); - //void unique(); - //template <typename BinaryPredicate> - //void unique(BinaryPredicate); - //void sort(); - //template<typename Compare> - //void sort(Compare compare); - - const int A[] = {1, 2, 3, 4, 5, 6}; - const int B[] = {12, 15, 13, 14, 11}; - const int C[] = {11, 12, 13, 14, 15}; - const int D[] = {1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6}; - const int N = sizeof(A) / sizeof(A[0]); - const int M = sizeof(B) / sizeof(B[0]); - const int Q = sizeof(D) / sizeof(D[0]); - - fixed_list<int, 32, true> list0401(A, A + N); - fixed_list<int, 32, true> list0402(B, B + M); - fixed_list<int, 32, true> list0403(C, C + M); - fixed_list<int, 32, true> list0404(D, D + Q); - fixed_list<int, 32, true> list0405(A, A + N); - - list0402.sort(eastl::less<int>()); - VERIFY(list0402 == list0403); - - list0401.merge(list0402, eastl::less<int>()); - list0404.sort(); - - //merge and isn't yet working for fixed_list. - //VERIFY(list0401 == list0404); - - VERIFY(list0401.validate()); - VERIFY(list0402.validate()); - VERIFY(list0403.validate()); - VERIFY(list0404.validate()); - VERIFY(list0405.validate()); - } - - - { - // void sort() - // void sort(Compare compare) - - const int kSize = 10; - const int A[kSize] = { 1, 9, 2, 3, 5, 7, 4, 6, 8, 0 }; - - fixed_list<int, 32, true> listEmpty; - VERIFY(VerifySequence(listEmpty.begin(), listEmpty.end(), int(), "fixed_list::sort", -1)); - listEmpty.sort(); - VERIFY(VerifySequence(listEmpty.begin(), listEmpty.end(), int(), "fixed_list::sort", -1)); - - fixed_list<int, 32, true> list1(A, A + 1); - VERIFY(VerifySequence(list1.begin(), list1.end(), int(), "fixed_list::sort", 1, -1)); - list1.sort(); - VERIFY(VerifySequence(list1.begin(), list1.end(), int(), "fixed_list::sort", 1, -1)); - - fixed_list<int, 32, true> list4(A, A + 4); - VERIFY(VerifySequence(list4.begin(), list4.end(), int(), "fixed_list::sort", 1, 9, 2, 3, -1)); - list4.sort(); - VERIFY(VerifySequence(list4.begin(), list4.end(), int(), "fixed_list::sort", 1, 2, 3, 9, -1)); - - fixed_list<int, 32, true> listA(A, A + kSize); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::sort", 1, 9, 2, 3, 5, 7, 4, 6, 8, 0, -1)); - listA.sort(); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::sort", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1)); - - listA.assign(A, A + kSize); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::sort", 1, 9, 2, 3, 5, 7, 4, 6, 8, 0, -1)); - listA.sort(eastl::less<int>()); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::sort", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1)); - } - - - { - // void merge(this_type& x); - // void merge(this_type& x, Compare compare); - - const int kSize = 8; - const int A[kSize] = { 1, 2, 3, 4, 4, 5, 9, 9 }; - const int B[kSize] = { 1, 2, 3, 4, 4, 5, 9, 9 }; - - fixed_list<int, 32, true> listA(A, A + kSize); - fixed_list<int, 32, true> listB(B, B + kSize); - - listA.merge(listB); - - //merge and isn't yet working for fixed_list. - //VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::merge", 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 9, 9, 9, 9, -1)); - //VERIFY(VerifySequence(listB.begin(), listB.end(), int(), "fixed_list::merge", -1)); - } - - - { - // void splice(iterator position, this_type& x); - // void splice(iterator position, this_type& x, iterator i); - // void splice(iterator position, this_type& x, iterator first, iterator last); - - const int kSize = 8; - const int A[kSize] = { 1, 2, 3, 4, 4, 5, 9, 9 }; - const int B[kSize] = { 1, 2, 3, 4, 4, 5, 9, 9 }; - - fixed_list<int, 32, true> listA(A, A + kSize); - fixed_list<int, 32, true> listB(B, B + kSize); - fixed_list<int, 32, true>::iterator it; - - // void splice(iterator position, this_type& x); - it = listA.begin(); eastl::advance(it, 2); - listA.splice(it, listB); // move listB into listA at position it. - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::splice", 1, 2, 1, 2, 3, 4, 4, 5, 9, 9, 3, 4, 4, 5, 9, 9, -1)); - VERIFY(VerifySequence(listB.begin(), listB.end(), int(), "fixed_list::splice", -1)); - - // void splice(iterator position, this_type& x, iterator i); - it = listA.begin(); eastl::advance(it, 6); - listB.splice(listB.begin(), listA, it); // move listA's it (6th element) into the front of listB. - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::splice", 1, 2, 1, 2, 3, 4, 5, 9, 9, 3, 4, 4, 5, 9, 9, -1)); - VERIFY(VerifySequence(listB.begin(), listB.end(), int(), "fixed_list::splice", 4, -1)); - - // void splice(iterator position, this_type& x, iterator first, iterator last); - listA.splice(listA.end(), listB, listB.begin(), listB.end()); // move listB into listA at the end of listA. - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::splice", 1, 2, 1, 2, 3, 4, 5, 9, 9, 3, 4, 4, 5, 9, 9, 4, -1)); - VERIFY(VerifySequence(listB.begin(), listB.end(), int(), "fixed_list::splice", -1)); - } - - - { - // void unique(); - // void unique(BinaryPredicate); - - const int kSize = 8; - const int A[kSize] = { 1, 2, 3, 4, 4, 5, 9, 9 }; - const int B[kSize] = { 1, 2, 3, 4, 4, 5, 9, 9 }; - - fixed_list<int, 32, true> listA(A, A + kSize); - listA.unique(); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::unique", 1, 2, 3, 4, 5, 9, -1)); - - fixed_list<int, 32, true> listB(B, B + kSize); - listB.unique(eastl::equal_to<int>()); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "fixed_list::unique", 1, 2, 3, 4, 5, 9, -1)); - } - - - { - // fixed_list(this_type&& x); - // fixed_list(this_type&&, const allocator_type&); - // this_type& operator=(this_type&& x); - fixed_list<TestObject, 16> list3TO33(3, TestObject(33)); - fixed_list<TestObject, 16> toListA(eastl::move(list3TO33)); - EATEST_VERIFY((toListA.size() == 3) && (toListA.front().mX == 33) /* && (list3TO33.size() == 0) fixed_list usually can't honor the move request. */); - - // The following is not as strong a test of this ctor as it could be. A stronger test would be to use IntanceAllocator with different instances. - fixed_list<TestObject, 16, true, MallocAllocator> list4TO44(4, TestObject(44)); - fixed_list<TestObject, 16, true, MallocAllocator> toListB(eastl::move(list4TO44), MallocAllocator()); - EATEST_VERIFY((toListB.size() == 4) && (toListB.front().mX == 44) /* && (list4TO44.size() == 0) fixed_list usually can't honor the move request. */); - - fixed_list<TestObject, 16, true, MallocAllocator> list5TO55(5, TestObject(55)); - toListB = eastl::move(list5TO55); - EATEST_VERIFY((toListB.size() == 5) && (toListB.front().mX == 55) /* && (list5TO55.size() == 0) fixed_list usually can't honor the move request. */); - } - - - { - // template <class... Args> - // void emplace_front(Args&&... args); - - // template <class... Args> - // void emplace_back(Args&&... args); - - // template <class... Args> - // iterator emplace(const_iterator position, Args&&... args); - - TestObject::Reset(); - - fixed_list<TestObject, 16> toListA; - - toListA.emplace_front(1, 2, 3); // This uses the TestObject(int x0, int x1, int x2, bool bThrowOnCopy) constructor. - EATEST_VERIFY((toListA.size() == 1) && (toListA.front().mX == (1+2+3)) && (TestObject::sTOCtorCount == 1)); - - toListA.emplace_back(2, 3, 4); - EATEST_VERIFY((toListA.size() == 2) && (toListA.back().mX == (2+3+4)) && (TestObject::sTOCtorCount == 2)); - - toListA.emplace(toListA.begin(), 3, 4, 5); - EATEST_VERIFY((toListA.size() == 3) && (toListA.front().mX == (3+4+5)) && (TestObject::sTOCtorCount == 3)); - - - // This test is similar to the emplace pathway above. - TestObject::Reset(); - - // void push_front(T&& x); - // void push_back(T&& x); - // iterator insert(const_iterator position, T&& x); - - fixed_list<TestObject, 16> toListC; - - toListC.push_front(TestObject(1, 2, 3)); - EATEST_VERIFY((toListC.size() == 1) && (toListC.front().mX == (1+2+3)) && (TestObject::sTOMoveCtorCount == 1)); - - toListC.push_back(TestObject(2, 3, 4)); - EATEST_VERIFY((toListC.size() == 2) && (toListC.back().mX == (2+3+4)) && (TestObject::sTOMoveCtorCount == 2)); - - toListC.insert(toListC.begin(), TestObject(3, 4, 5)); - EATEST_VERIFY((toListC.size() == 3) && (toListC.front().mX == (3+4+5)) && (TestObject::sTOMoveCtorCount == 3)); - } - - - { - // list(std::initializer_list<value_type> ilist, const allocator_type& allocator = EASTL_LIST_DEFAULT_ALLOCATOR); - // this_type& operator=(std::initializer_list<value_type> ilist); - // void assign(std::initializer_list<value_type> ilist); - // iterator insert(iterator position, std::initializer_list<value_type> ilist); - list<int> intList = { 0, 1, 2 }; - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "list std::initializer_list", 0, 1, 2, -1)); - - intList = { 13, 14, 15 }; - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "list std::initializer_list", 13, 14, 15, -1)); - - intList.assign({ 16, 17, 18 }); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "list std::initializer_list", 16, 17, 18, -1)); - - intList.insert(intList.begin(), { 14, 15 }); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "list std::initializer_list", 14, 15, 16, 17, 18, -1)); - } - - - { // Regression of user test - struct Dummy - { - typedef eastl::fixed_list<FixedListTest::Item, 10, false> TCollection; - - TCollection mCollection1; - TCollection mCollection2; - }; - - Dummy d; - VERIFY(d.mCollection1.size() == d.mCollection2.size()); - } - - - { - // Test construction of a container with an overflow allocator constructor argument. - MallocAllocator overflowAllocator; - void* p = overflowAllocator.allocate(1); - fixed_list<int, 64, true, MallocAllocator> c(overflowAllocator); - c.resize(65); - VERIFY(c.get_overflow_allocator().mAllocCount == 2); // 1 for above, and 1 for overflowing from 64 to 65. - overflowAllocator.deallocate(p, 1); - } - - - // We can't do this, due to how Reset is used above: - // EATEST_VERIFY(TestObject::IsClear()); - EATEST_VERIFY(TestObject::sMagicErrorCount == 0); - TestObject::Reset(); - - - return nErrorCount; -} -EA_RESTORE_VC_WARNING() - - - - - - - - - - diff --git a/test/source/TestFixedMap.cpp b/test/source/TestFixedMap.cpp deleted file mode 100644 index 6df97f0..0000000 --- a/test/source/TestFixedMap.cpp +++ /dev/null @@ -1,185 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include "TestMap.h" -#include <EASTL/fixed_map.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <map> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::fixed_map <int, float, 1>; -template class eastl::fixed_multimap<float, int, 1>; -template class eastl::fixed_map <int, TestObject, 1>; -template class eastl::fixed_multimap<TestObject, int, 1>; - -template class eastl::fixed_map <int, float, 1, true, eastl::less<int>, MallocAllocator>; -template class eastl::fixed_multimap<float, int, 1, true, eastl::less<float>, MallocAllocator>; -template class eastl::fixed_map <int, TestObject, 1, true, eastl::less<int>, MallocAllocator>; -template class eastl::fixed_multimap<TestObject, int, 1, true, eastl::less<TestObject>, MallocAllocator>; - - -/////////////////////////////////////////////////////////////////////////////// -// typedefs -// - const eastl_size_t kContainerSize = 1000; - -typedef eastl::fixed_map<int, int, kContainerSize> VM1; -typedef eastl::fixed_map<TestObject, TestObject, kContainerSize> VM4; -typedef eastl::fixed_multimap<int, int, kContainerSize> VMM1; -typedef eastl::fixed_multimap<TestObject, TestObject, kContainerSize> VMM4; - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - typedef std::map<int, int> VM3; - typedef std::map<TestObject, TestObject> VM6; - typedef std::multimap<int, int> VMM3; - typedef std::multimap<TestObject, TestObject> VMM6; -#endif - -/////////////////////////////////////////////////////////////////////////////// - - -EA_DISABLE_VC_WARNING(6262) -int TestFixedMap() -{ - int nErrorCount = 0; - - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - { // Test construction - nErrorCount += TestMapConstruction<VM1, VM3, false>(); - nErrorCount += TestMapConstruction<VM4, VM6, false>(); - - nErrorCount += TestMapConstruction<VMM1, VMM3, true>(); - nErrorCount += TestMapConstruction<VMM4, VMM6, true>(); - } - - - { // Test mutating functionality. - nErrorCount += TestMapMutation<VM1, VM3, false>(); - nErrorCount += TestMapMutation<VM4, VM6, false>(); - - nErrorCount += TestMapMutation<VMM1, VMM3, true>(); - nErrorCount += TestMapMutation<VMM4, VMM6, true>(); - } - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - - { // Test searching functionality. - nErrorCount += TestMapSearch<VM1, false>(); - nErrorCount += TestMapSearch<VM4, false>(); - - nErrorCount += TestMapSearch<VMM1, true>(); - nErrorCount += TestMapSearch<VMM4, true>(); - } - - - { - // C++11 emplace and related functionality - nErrorCount += TestMapCpp11<eastl::fixed_map<int, TestObject, 32> >(); - - nErrorCount += TestMultimapCpp11<eastl::fixed_multimap<int, TestObject, 32> >(); - - nErrorCount += TestMapCpp11NonCopyable<eastl::fixed_map<int, NonCopyable, 32>>(); - } - - { - // C++17 try_emplace and related functionality - nErrorCount += TestMapCpp17<eastl::fixed_map<int, TestObject, 32>>(); - } - - - { // Test functionality specific to fixed size containers. - - VM1 vm1; - VMM1 vmm1; - - VERIFY(vm1.max_size() == kContainerSize); - VERIFY(vmm1.max_size() == kContainerSize); - } - - - { // Regression of bug report by Eric Turmel, May 20, 2008 - typedef eastl::fixed_map<int, TestObject, 37, false> FixedMap; - VERIFY(FixedMap::kMaxSize == 37); - - FixedMap fixedMap; - FixedMap::fixed_allocator_type& a = fixedMap.get_allocator(); - - for(int i = 0; i < FixedMap::kMaxSize; i++) - { - VERIFY(a.can_allocate()); - - fixedMap.insert(FixedMap::value_type(i, TestObject(i))); - - #if EASTL_FIXED_SIZE_TRACKING_ENABLED - // Disabled because mPool is (mistakenly) inaccessible. - // VERIFY((a.mPool.mnCurrentSize == a.mPool.mnPeakSize) && (a.mPool.mnCurrentSize == i)); - #endif - } - - VERIFY(!a.can_allocate()); - } - - { - // Test fixed set with overflow and alignment requirements. - typedef fixed_map<Align64, int, 1, true> FixedMapWithAlignment; - typedef fixed_multimap<Align64, int, 1, true> FixedMultiMapWithAlignment; - - FixedMapWithAlignment fm; - FixedMultiMapWithAlignment fmm; - - Align64 a; a.mX = 1; - Align64 b; b.mX = 2; - Align64 c; c.mX = 3; - Align64 d; d.mX = 4; - Align64 e; e.mX = 5; - - fm.insert(a); - fm.insert(b); - fm.insert(c); - fm.insert(d); - fm.insert(e); - for (FixedMapWithAlignment::const_iterator it = fm.begin(); it != fm.end(); ++it) - { - const Align64* ptr = &((*it).first); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - - fmm.insert(a); - fmm.insert(b); - fmm.insert(c); - fmm.insert(d); - fmm.insert(e); - for (FixedMultiMapWithAlignment::const_iterator it = fmm.begin(); it != fmm.end(); ++it) - { - const Align64* ptr = &((*it).first); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - } - - - return nErrorCount; -} -EA_RESTORE_VC_WARNING() - - - - - - - - - - - - diff --git a/test/source/TestFixedSList.cpp b/test/source/TestFixedSList.cpp deleted file mode 100644 index 6620c79..0000000 --- a/test/source/TestFixedSList.cpp +++ /dev/null @@ -1,313 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/fixed_slist.h> -#include <EABase/eabase.h> - -#ifdef _MSC_VER - #pragma warning(push, 0) -#endif - -#include <stdio.h> - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::fixed_slist<int, 1, true, EASTLAllocatorType>; -template class eastl::fixed_slist<int, 1, false, EASTLAllocatorType>; - - -/* -// This does not compile, since the fixed_slist allocator is templated on sizeof(T), -// not just T. Thus, the full type is required at the time of instantiation, but it -// is not available. -// See EATech Core JIRA issue ETCR-1608 for more information. -struct StructWithContainerOfStructs -{ - eastl::fixed_slist<StructWithContainerOfStructs,4> children; -}; -*/ - - -int TestFixedSList() -{ - int nErrorCount = 0; - - { - fixed_slist<int, 64> list0101; - VERIFY(list0101.empty()); - VERIFY(list0101.size() == 0); - VERIFY(list0101.max_size() == 64); - - list0101.push_front(1); - VERIFY(!list0101.empty()); - VERIFY(list0101.size() == 1); - - list0101.resize(3, 2); - VERIFY(!list0101.empty()); - VERIFY(list0101.size() == 3); - - fixed_slist<int, 64>::iterator i = list0101.begin(); - VERIFY(*i == 1); ++i; - VERIFY(*i == 2); ++i; - VERIFY(*i == 2); ++i; - VERIFY(i == list0101.end()); - - list0101.resize(0); - VERIFY(list0101.empty()); - VERIFY(list0101.size() == 0); - } - - { - fixed_slist<int, 64, true, MallocAllocator> list0101; - VERIFY(list0101.empty()); - VERIFY(list0101.size() == 0); - VERIFY(list0101.max_size() == 64); - - list0101.push_front(1); - VERIFY(!list0101.empty()); - VERIFY(list0101.size() == 1); - - list0101.resize(3, 2); - VERIFY(!list0101.empty()); - VERIFY(list0101.size() == 3); - - fixed_slist<int, 64>::iterator i = list0101.begin(); - VERIFY(*i == 1); ++i; - VERIFY(*i == 2); ++i; - VERIFY(*i == 2); ++i; - VERIFY(i == list0101.end()); - - while(list0101.size() < 64 + 16) - list0101.push_front(0); - - list0101.resize(0); - VERIFY(list0101.empty()); - VERIFY(list0101.size() == 0); - } - - { - // Test fixed slist with overflow and alignment requirements. - typedef fixed_slist<Align64, 1, true, CustomAllocator> FixedSListWithAlignment; - - FixedSListWithAlignment fsl; - - Align64 a; - - fsl.push_front(a); - fsl.push_front(a); - fsl.push_front(a); - fsl.push_front(a); - fsl.push_front(a); - for (FixedSListWithAlignment::const_iterator it = fsl.begin(); it != fsl.end(); ++it) - { - const Align64* ptr = &(*it); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - } - - { - // bool empty() const - // bool has_overflowed() const - // size_type size() const; - // size_type max_size() const - - // Test a list that has overflow disabled. - fixed_slist<int, 5, false> listInt5; - - VERIFY(listInt5.max_size() == 5); - VERIFY(listInt5.size() == 0); - VERIFY(listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_front(37); - listInt5.push_front(37); - listInt5.push_front(37); - - VERIFY(listInt5.size() == 3); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_front(37); - listInt5.push_front(37); - - VERIFY(listInt5.size() == 5); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.pop_front(); - - VERIFY(listInt5.size() == 4); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - } - - - { - // bool empty() const - // bool has_overflowed() const - // size_type size() const; - // size_type max_size() const - - // Test a list that has overflow enabled. - fixed_slist<int, 5, true> listInt5; - - VERIFY(listInt5.max_size() == 5); - VERIFY(listInt5.size() == 0); - VERIFY(listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_front(37); - listInt5.push_front(37); - listInt5.push_front(37); - - VERIFY(listInt5.size() == 3); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_front(37); - listInt5.push_front(37); - - VERIFY(listInt5.size() == 5); - VERIFY(!listInt5.empty()); - VERIFY(!listInt5.has_overflowed()); - - listInt5.push_front(37); - - VERIFY(listInt5.size() == 6); - VERIFY(!listInt5.empty()); - VERIFY(listInt5.has_overflowed()); - - listInt5.pop_front(); - - VERIFY(listInt5.size() == 5); - VERIFY(!listInt5.empty()); - //VERIFY(listInt5.has_overflowed()); Disabled because currently has_overflowed can't detect this situation in non-debug builds. - } - - - { - // fixed_slist(this_type&& x); - // fixed_slist(this_type&&, const allocator_type&); - // this_type& operator=(this_type&& x); - - fixed_slist<TestObject, 16> slist3TO33(3, TestObject(33)); - fixed_slist<TestObject, 16> toListA(eastl::move(slist3TO33)); - EATEST_VERIFY((toListA.size() == 3) && (toListA.front().mX == 33) /* && (slist3TO33.size() == 0) fixed_list usually can't honor the move request. */); - - // The following is not as strong a test of this ctor as it could be. A stronger test would be to use IntanceAllocator with different instances. - fixed_slist<TestObject, 16, true, MallocAllocator> slist4TO44(4, TestObject(44)); - fixed_slist<TestObject, 16, true, MallocAllocator> toListB(eastl::move(slist4TO44), MallocAllocator()); - EATEST_VERIFY((toListB.size() == 4) && (toListB.front().mX == 44) /* && (slist4TO44.size() == 0) fixed_list usually can't honor the move request. */); - - fixed_slist<TestObject, 16, true, MallocAllocator> slist5TO55(5, TestObject(55)); - toListB = eastl::move(slist5TO55); - EATEST_VERIFY((toListB.size() == 5) && (toListB.front().mX == 55) /* && (slist5TO55.size() == 0) fixed_list usually can't honor the move request. */); - } - - - { - // template <class... Args> - // void emplace_front(Args&&... args); - - // template <class... Args> - // iterator emplace_after(const_iterator position, Args&&... args); - - TestObject::Reset(); - - fixed_slist<TestObject, 16> toListA; - - toListA.emplace_front(1, 2, 3); // This uses the TestObject(int x0, int x1, int x2, bool bThrowOnCopy) constructor. - EATEST_VERIFY((toListA.size() == 1) && (toListA.front().mX == (1+2+3)) && (TestObject::sTOCtorCount == 1)); - - toListA.emplace_after(toListA.before_begin(), 3, 4, 5); - EATEST_VERIFY((toListA.size() == 2) && (toListA.front().mX == (3+4+5)) && (TestObject::sTOCtorCount == 2)); - - - // This test is similar to the emplace pathway above. - TestObject::Reset(); - - // void push_front(T&& x); - // iterator insert(const_iterator position, T&& x); - - fixed_slist<TestObject, 16> toListC; - - toListC.push_front(TestObject(1, 2, 3)); - EATEST_VERIFY((toListC.size() == 1) && (toListC.front().mX == (1+2+3)) && (TestObject::sTOMoveCtorCount == 1)); - - toListC.insert_after(toListC.before_begin(), TestObject(3, 4, 5)); - EATEST_VERIFY((toListC.size() == 2) && (toListC.front().mX == (3+4+5)) && (TestObject::sTOMoveCtorCount == 2)); - } - - - { - // slist(std::initializer_list<value_type> ilist, const allocator_type& allocator = EASTL_SLIST_DEFAULT_ALLOCATOR); - // this_type& operator=(std::initializer_list<value_type>); - // void assign(std::initializer_list<value_type> ilist); - // iterator insert_after(iterator position, std::initializer_list<value_type> ilist); - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - fixed_slist<int, 8> intList = { 0, 1, 2 }; - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "fixed_slist std::initializer_list", 0, 1, 2, -1)); - - intList = { 13, 14, 15 }; - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "fixed_slist std::initializer_list", 13, 14, 15, -1)); - - intList.assign({ 16, 17, 18 }); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "fixed_slist std::initializer_list", 16, 17, 18, -1)); - - fixed_slist<int, 8>::iterator it = intList.insert_after(intList.before_begin(), { 14, 15 }); - EATEST_VERIFY(VerifySequence(intList.begin(), intList.end(), int(), "fixed_slist std::initializer_list", 14, 15, 16, 17, 18, -1)); - EATEST_VERIFY(*it == 15); // Note that slist::insert_after returns the last inserted element, not the first as with list::insert. - #endif - } - - - { - // Test construction of a container with an overflow allocator constructor argument. - // - // GCC 4.4 has a hard time compiling this code correctly in optimized builds as it - // omits the increment of the mAllocCount field when calling overflowAllocator.allocate. - #if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION == 4004) - MallocAllocator overflowAllocator; - fixed_slist<int, 64, true, MallocAllocator> c(overflowAllocator); - c.resize(65); - VERIFY(c.get_overflow_allocator().mAllocCount == 1); // 1 for overflowing from 64 to 65. - #else - MallocAllocator overflowAllocator; - void* p = overflowAllocator.allocate(1); - fixed_slist<int, 64, true, MallocAllocator> c(overflowAllocator); - c.resize(65); - VERIFY(c.get_overflow_allocator().mAllocCount == 2); // 1 for above, and 1 for overflowing from 64 to 65. - overflowAllocator.deallocate(p, 1); - #endif - } - - - // We can't do this, due to how Reset is used above: - // EATEST_VERIFY(TestObject::IsClear()); - EATEST_VERIFY(TestObject::sMagicErrorCount == 0); - TestObject::Reset(); - - - return nErrorCount; -} - - - - - - - - - - diff --git a/test/source/TestFixedSet.cpp b/test/source/TestFixedSet.cpp deleted file mode 100644 index 8bfbe90..0000000 --- a/test/source/TestFixedSet.cpp +++ /dev/null @@ -1,207 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include "TestSet.h" -#include <EASTL/fixed_set.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <set> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::fixed_set <int, 1>; -template class eastl::fixed_multiset<float, 1>; -template class eastl::fixed_set <Align64, 1>; -template class eastl::fixed_multiset<TestObject, 1>; - - -template class eastl::fixed_set <int, 1, true, eastl::less<int>, MallocAllocator>; -template class eastl::fixed_multiset<float, 1, true, eastl::less<float>, MallocAllocator>; -template class eastl::fixed_set <Align64, 1, true, eastl::less<Align64>, MallocAllocator>; -template class eastl::fixed_multiset<TestObject, 1, true, eastl::less<TestObject>, MallocAllocator>; - - -/////////////////////////////////////////////////////////////////////////////// -// typedefs -// -const eastl_size_t kContainerSize = 1000; - -typedef eastl::fixed_set<int, kContainerSize> VS1; -typedef eastl::fixed_set<TestObject, kContainerSize> VS4; -typedef eastl::fixed_multiset<int, kContainerSize> VMS1; -typedef eastl::fixed_multiset<TestObject, kContainerSize> VMS4; - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - typedef std::set<int> VS3; - typedef std::set<TestObject> VS6; - typedef std::multiset<int> VMS3; - typedef std::multiset<TestObject> VMS6; -#endif - -/////////////////////////////////////////////////////////////////////////////// - - -EA_DISABLE_VC_WARNING(6262) -int TestFixedSet() -{ - int nErrorCount = 0; - - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - { // Test construction - nErrorCount += TestSetConstruction<VS1, VS3, false>(); - nErrorCount += TestSetConstruction<VS4, VS6, false>(); - - nErrorCount += TestSetConstruction<VMS1, VMS3, true>(); - nErrorCount += TestSetConstruction<VMS4, VMS6, true>(); - } - - - { // Test mutating functionality. - nErrorCount += TestSetMutation<VS1, VS3, false>(); - nErrorCount += TestSetMutation<VS4, VS6, false>(); - - nErrorCount += TestSetMutation<VMS1, VMS3, true>(); - nErrorCount += TestSetMutation<VMS4, VMS6, true>(); - } - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - - { // Test searching functionality. - nErrorCount += TestSetSearch<VS1, false>(); - nErrorCount += TestSetSearch<VS4, false>(); - - nErrorCount += TestSetSearch<VMS1, true>(); - nErrorCount += TestSetSearch<VMS4, true>(); - } - - - { - // C++11 emplace and related functionality - nErrorCount += TestSetCpp11<eastl::fixed_set<TestObject, 32> >(); - - nErrorCount += TestMultisetCpp11<eastl::fixed_multiset<TestObject, 32> >(); - } - - - { // Test functionality specific to fixed size containers. - - VS1 vs1; - VMS1 vms1; - - VERIFY(vs1.max_size() == kContainerSize); - VERIFY(vms1.max_size() == kContainerSize); - } - - - { - // Test version *without* pool overflow. - typedef eastl::fixed_set<int, 100, false> FixedSetFalse; - FixedSetFalse fixedSet; - - fixedSet.insert(FixedSetFalse::value_type(0)); - VERIFY(fixedSet.size() == 1); - - fixedSet.clear(); - VERIFY(fixedSet.size() == 0); - - for(int i = 0; fixedSet.size() < 100; i++) - fixedSet.insert(FixedSetFalse::value_type(i)); - VERIFY(fixedSet.size() == 100); - - // Verify that we allocated enough space for exactly N items. - // It's possible that due to alignments, there might be room for N + 1. - FixedSetFalse::allocator_type& allocator = fixedSet.get_allocator(); - void* pResult = allocator.allocate(sizeof(FixedSetFalse::node_type)); - if(pResult) - { - pResult = allocator.allocate(sizeof(FixedSetFalse::node_type)); - VERIFY(pResult == NULL); - } - } - - - { - // Test version *with* pool overflow. - typedef eastl::fixed_set<int, 100, true> FixedSetTrue; - FixedSetTrue fixedSet; - - fixedSet.insert(FixedSetTrue::value_type(0)); - VERIFY(fixedSet.size() == 1); - - fixedSet.clear(); - VERIFY(fixedSet.size() == 0); - - for(int i = 0; fixedSet.size() < 100; i++) - fixedSet.insert(FixedSetTrue::value_type(i)); - VERIFY(fixedSet.size() == 100); - - FixedSetTrue::allocator_type& allocator = fixedSet.get_allocator(); - void* pResult = allocator.allocate(sizeof(FixedSetTrue::node_type)); - VERIFY(pResult != NULL); - allocator.deallocate(pResult, sizeof(FixedSetTrue::node_type)); - - // get_overflow_allocator / set_overflow_allocator - // This is a weak test which should be improved. - EASTLAllocatorType a = fixedSet.get_allocator().get_overflow_allocator(); - fixedSet.get_allocator().set_overflow_allocator(a); - } - - { - // Test fixed set with overflow and alignment requirements. - typedef fixed_set<Align64, 1, true> FixedSetWithAlignment; - typedef fixed_multiset<Align64, 1, true> FixedMultiSetWithAlignment; - - FixedSetWithAlignment fs; - FixedMultiSetWithAlignment fms; - - Align64 a; a.mX = 1; - Align64 b; b.mX = 2; - Align64 c; c.mX = 3; - Align64 d; d.mX = 4; - Align64 e; e.mX = 5; - - fs.insert(a); - fs.insert(b); - fs.insert(c); - fs.insert(d); - fs.insert(e); - for (FixedSetWithAlignment::const_iterator it = fs.begin(); it != fs.end(); ++it) - { - const Align64* ptr = &(*it); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - fms.insert(a); - fms.insert(b); - fms.insert(c); - fms.insert(d); - fms.insert(e); - for (FixedMultiSetWithAlignment::const_iterator it = fms.begin(); it != fms.end(); ++it) - { - const Align64* ptr = &(*it); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - } - return nErrorCount; -} -EA_RESTORE_VC_WARNING() - - - - - - - - - - - - diff --git a/test/source/TestFixedString.cpp b/test/source/TestFixedString.cpp deleted file mode 100644 index 8528dc7..0000000 --- a/test/source/TestFixedString.cpp +++ /dev/null @@ -1,500 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include <EABase/eabase.h> -EA_DISABLE_GCC_WARNING(-Warray-bounds) - -#include "EASTLTest.h" -#include <EASTL/fixed_string.h> -#include <EASTL/fixed_substring.h> - -#ifdef _MSC_VER - #pragma warning(push, 0) -#endif - -#include <string.h> - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - -using namespace eastl; - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::fixed_string<char8_t, 1, true>; -template class eastl::fixed_string<char16_t, 1, true>; -template class eastl::fixed_string<char32_t, 1, true>; - -template class eastl::fixed_string<char8_t, 128, false>; -template class eastl::fixed_string<char16_t, 128, false>; -template class eastl::fixed_string<char32_t, 128, false>; - -template class eastl::fixed_string<char8_t, 128, true, MallocAllocator>; -template class eastl::fixed_string<char16_t, 128, true, MallocAllocator>; -template class eastl::fixed_string<char32_t, 128, true, MallocAllocator>; - -template class eastl::fixed_string<char8_t, 128, false, MallocAllocator>; -template class eastl::fixed_string<char16_t, 128, false, MallocAllocator>; -template class eastl::fixed_string<char32_t, 128, false, MallocAllocator>; - -template class eastl::fixed_substring<char8_t>; -template class eastl::fixed_substring<char16_t>; - - - - -/* -// This does not compile, since the fixed_string allocator (among other things) is -// templated on sizeof(T), not just T. Thus, the full type is required at the time -// of instantiation, but it is not available. -// See EATech Core JIRA issue ETCR-1608 for more information. -struct StructWithContainerOfStructs -{ - eastl::fixed_string<StructWithContainerOfStructs,4> children; -}; -*/ - - -int TestFixedSubstring() -{ - int nErrorCount = 0; - - { - const char* pSource1 = "hello world"; - const char* pSource2 = "hola mundo"; - - basic_string<char> str(pSource1); - fixed_substring<char> sub(str, 2, 5); - - EATEST_VERIFY(sub.size() == 5); - EATEST_VERIFY(sub[0] == 'l'); - EATEST_VERIFY(sub == "llo w"); - - sub.assign(pSource2); - EATEST_VERIFY(sub.size() == 10); - EATEST_VERIFY(sub[0] == pSource2[0]); - EATEST_VERIFY(sub == pSource2); - - fixed_substring<char> sub2(sub); - EATEST_VERIFY(sub2.size() == 10); - EATEST_VERIFY(sub2[0] == pSource2[0]); - EATEST_VERIFY(sub2 == pSource2); - - sub.assign(sub2, 1, 3); - EATEST_VERIFY(sub.size() == 3); - EATEST_VERIFY(sub == "ola"); - - sub.assign(pSource2, 3); - EATEST_VERIFY(sub.size() == 3); - EATEST_VERIFY(sub == "hol"); - - sub.assign(pSource2, pSource2 + 4); - EATEST_VERIFY(sub.size() == 4); - EATEST_VERIFY(sub == "hola"); - - sub = pSource1; - EATEST_VERIFY(sub.size() == strlen(pSource1)); - EATEST_VERIFY(sub == pSource1); - } - - - { // Test fixed_substring with a C character array - char pArray[256]; - fixed_substring<char> str(pArray, 255); - - str.resize(5); - EATEST_VERIFY(str.size() == 5); - - str[0] = 'a'; - EATEST_VERIFY(str[0] == 'a'); - - str.sprintf("Hello %s", "world"); - EATEST_VERIFY(str == "Hello world"); - - str += " Hola mundo"; - EATEST_VERIFY(str == "Hello world Hola mundo"); - - str.pop_back(); - EATEST_VERIFY(str == "Hello world Hola mund"); - - str.replace(6, 5, "abcdefghijlk"); - EATEST_VERIFY(str == "Hello abcdefghijlk Hola mund"); - - str.clear(); - EATEST_VERIFY(str.empty()); - EATEST_VERIFY(str == ""); - } - - - { - // Check that copies/moves don't become independent strings. - // They should all point to the same sub-string. - string str = "hello world"; - fixed_substring<char> sub(str, 2, 5); - - EATEST_VERIFY(sub.size() == 5); - EATEST_VERIFY(sub[0] == 'l'); - EATEST_VERIFY(sub == "llo w"); - - vector<fixed_substring<char>> v; - for (eastl_size_t i = 0; i < 1000; ++i) { - v.push_back(sub); - } - - sub[0] = 'g'; - EATEST_VERIFY(str == "heglo world"); - EATEST_VERIFY(sub == "glo w"); - - for (const auto& s : v){ - EATEST_VERIFY(s == "glo w"); - } - - // copy construct - fixed_substring<char> sub2 = sub; - - // copy assign - fixed_substring<char> sub3; - sub3 = sub; - - // move construct - fixed_substring<char> sub4 = eastl::move(sub); - - // move assign - fixed_substring<char> sub_again(str, 2, 5); - fixed_substring<char> sub5; - sub5 = eastl::move(sub_again); - - EATEST_VERIFY(sub2 == "glo w"); - EATEST_VERIFY(sub3 == "glo w"); - EATEST_VERIFY(sub4 == "glo w"); - EATEST_VERIFY(sub5 == "glo w"); - - str[5] = 'g'; - EATEST_VERIFY(sub2 == "glogw"); - EATEST_VERIFY(sub3 == "glogw"); - EATEST_VERIFY(sub4 == "glogw"); - EATEST_VERIFY(sub5 == "glogw"); - - } - - return nErrorCount; -} - - -int TestFixedString() -{ - int nErrorCount = 0; - - { - fixed_string<char, 64>::CtorSprintf cs; - - fixed_string<char, 64> s8(cs, "hello world %d.", 1); - EATEST_VERIFY(s8 == "hello world 1."); - EATEST_VERIFY(s8.capacity() == 63); // 63 because the 64 includes the terminating 0, but capacity() subtracts the terminating 0 usage. - EATEST_VERIFY(s8.max_size() == 63); - - s8.append_sprintf(" More hello %d.", 2); - EATEST_VERIFY(s8 == "hello world 1. More hello 2."); - EATEST_VERIFY(s8.capacity() == 63); - } - - - { - fixed_string<wchar_t, 64>::CtorSprintf cs; - - fixed_string<wchar_t, 64> sW(cs, L"hello world %d.", 1); - EATEST_VERIFY(sW == L"hello world 1."); - EATEST_VERIFY(sW.capacity() == 63); // 63 because the 64 includes the terminating 0, but capacity() subtracts the terminating 0 usage. - - sW.append_sprintf(L" More hello %d.", 2); - EATEST_VERIFY(sW == L"hello world 1. More hello 2."); - EATEST_VERIFY(sW.capacity() == 63); // 63 because the 64 includes the terminating 0, but capacity() subtracts the terminating 0 usage. - } - - - { - typedef fixed_string<char8_t, 64, true> FixedString64; - typedef fixed_string<char8_t, 64, false> FixedString64NoOverflow; - FixedString64::CtorSprintf cs; - FixedString64::CtorDoNotInitialize cdni; - - // fixed_string(); - FixedString64 fs1; - EATEST_VERIFY(fs1.size() == 0); - EATEST_VERIFY(fs1.capacity() == 63); - - FixedString64NoOverflow fsNo; - EATEST_VERIFY(fs1.can_overflow() == true); - EATEST_VERIFY(fsNo.can_overflow() == false); - EATEST_VERIFY(fs1.full() == false); - EATEST_VERIFY(fs1.has_overflowed() == false); - - const char8_t* pCStr = fs1.c_str(); - EATEST_VERIFY(*pCStr == 0); - - // fixed_string(const this_type& x); - FixedString64 fs2(fs1); - EATEST_VERIFY(fs2.size() == 0); - EATEST_VERIFY(fs2.capacity() == 63); - - fs1 = EA_CHAR8("abc"); - FixedString64 fs3(fs1); - EATEST_VERIFY(fs3.size() == 3); - EATEST_VERIFY(fs3.capacity() == 63); - EATEST_VERIFY(fs3 == EA_CHAR8("abc")); - - // fixed_string(const this_type& x, size_type position, size_type n = npos); - FixedString64 fs4(fs1, 1, 2); - EATEST_VERIFY(fs4.size() == 2); - EATEST_VERIFY(fs4.capacity() == 63); - EATEST_VERIFY(fs4 == EA_CHAR8("bc")); - - // fixed_string(const value_type* p, size_type n); - FixedString64 fs5(EA_CHAR8("abcdef"), 6); - EATEST_VERIFY(fs5.size() == 6); - EATEST_VERIFY(fs5.capacity() == 63); - EATEST_VERIFY(fs5 == EA_CHAR8("abcdef")); - - // fixed_string(const value_type* p); - FixedString64 fs6(EA_CHAR8("abcdef")); - EATEST_VERIFY(fs6.size() == 6); - EATEST_VERIFY(fs6.capacity() == 63); - EATEST_VERIFY(fs6 == EA_CHAR8("abcdef")); - - // fixed_string(size_type n, const value_type& value); - FixedString64 fs7(8, 'a'); - EATEST_VERIFY(fs7.size() == 8); - EATEST_VERIFY(fs7.capacity() == 63); - EATEST_VERIFY(fs7 == EA_CHAR8("aaaaaaaa")); - - // fixed_string(const value_type* pBegin, const value_type* pEnd); - FixedString64 fs8(&fs6[0], &fs6[5]); - EATEST_VERIFY(fs8.size() == 5); - EATEST_VERIFY(fs8.capacity() == 63); - EATEST_VERIFY(fs8 == EA_CHAR8("abcde")); - - // fixed_string(CtorDoNotInitialize, size_type n); - FixedString64 fs9(cdni, 7); - EATEST_VERIFY(fs9.size() == 7); - EATEST_VERIFY(fs9.capacity() == 63); - - // fixed_string(CtorSprintf, const value_type* pFormat, ...); - FixedString64 fs10(cs, EA_CHAR8("%d"), 37); - EATEST_VERIFY(fs10.size() == 2); - EATEST_VERIFY(fs10.capacity() == 63); - EATEST_VERIFY(fs10 == EA_CHAR8("37")); - - // this_type& operator=(const const value_type* p); - // this_type& operator=(const this_type& x); - fs9 = EA_CHAR8("hello"); - EATEST_VERIFY(fs9 == EA_CHAR8("hello")); - - fs9 = fs10; - EATEST_VERIFY(fs9 == fs10); - EATEST_VERIFY(fs9 == EA_CHAR8("37")); - - // void swap(this_type& x); - swap(fs7, fs9); - EATEST_VERIFY(fs7 == EA_CHAR8("37")); - EATEST_VERIFY(fs9 == EA_CHAR8("aaaaaaaa")); - - // void set_capacity(size_type n); - fs9.set_capacity(100); - EATEST_VERIFY(fs9.size() == 8); - EATEST_VERIFY(fs9.capacity() == 100); - EATEST_VERIFY(fs9.full() == true); - EATEST_VERIFY(fs9.has_overflowed() == true); - - fs9.set_capacity(100); // EATEST_VERIFY that this has no effect. - EATEST_VERIFY(fs9.size() == 8); - EATEST_VERIFY(fs9.capacity() == 100); - EATEST_VERIFY(fs9.full() == true); - EATEST_VERIFY(fs9.has_overflowed() == true); - - fs9.resize(100); - fs9.set_capacity(100); - EATEST_VERIFY(fs9.size() == 100); - EATEST_VERIFY(fs9.capacity() == 100); - EATEST_VERIFY(fs9.full() == true); - EATEST_VERIFY(fs9.has_overflowed() == true); - - fs9.set_capacity(1); - EATEST_VERIFY(fs9.size() == 1); - EATEST_VERIFY(fs9.capacity() < fs9.max_size()); // We don't test for capacity == 1, because with fixed_strings, the fixed-size capacity is the lowest it ever gets. - EATEST_VERIFY(fs9.full() == false); - EATEST_VERIFY(fs9.has_overflowed() == false); - - fs9.set_capacity(0); - EATEST_VERIFY(fs9.size() == 0); - EATEST_VERIFY(fs9.capacity() < fs9.max_size()); // We don't test for capacity == 1, because with fixed_strings, the fixed-size capacity is the lowest it ever gets. - EATEST_VERIFY(fs9.full() == false); - EATEST_VERIFY(fs9.has_overflowed() == false); - - // Exercise the freeing of memory in set_capacity. - fixed_string<char8_t, 64, true> fs88; - eastl_size_t capacity = fs88.capacity(); - fs88.resize(capacity); - fs88.set_capacity(capacity * 2); - EATEST_VERIFY(fs88.capacity() >= (capacity * 2)); - - // void reset_lose_memory(); - fs6.reset_lose_memory(); - EATEST_VERIFY(fs6.size() == 0); - EATEST_VERIFY(fs5.capacity() == 63); - - // size_type max_size() const; - EATEST_VERIFY(fs7.max_size() == 63); - - - // global operator + - { - // fixed_string operator+(const fixed_string& a, const fixed_string& b); - // fixed_string operator+(value_type* p, const fixed_string& b); - // fixed_string operator+(value_type c, const fixed_string& b); - // fixed_string operator+(const fixed_string& a, const value_type* p); - // fixed_string operator+(const fixed_string& a, value_type c); - - typedef fixed_string<char, 8, true> FSTest; // Make it a small size so it's easily overflowed when we want. - - FSTest a("abc"); - FSTest b("def"); - FSTest c(a + b); - EATEST_VERIFY(c == "abcdef"); - c = a + "ghi"; - EATEST_VERIFY(c == "abcghi"); - c = "ghi" + a; - EATEST_VERIFY(c == "ghiabc"); - c = a + 'g'; - EATEST_VERIFY(c == "abcg"); - c = 'g' + a; - EATEST_VERIFY(c == "gabc"); - - // fixed_string operator+(fixed_string&& a, fixed_string&& b); - // fixed_string operator+(fixed_string&& a, const fixed_string& b); - // fixed_string operator+(const value_type* p, fixed_string&& b); - // fixed_string operator+(fixed_string&& a, const value_type* p); - // fixed_string operator+(fixed_string&& a, value_type b); - - c = eastl::move(a) + eastl::move(b); - EATEST_VERIFY(c == "abcdef"); - c.clear(); - - FSTest a1("abc"); - FSTest b1("def"); - c = eastl::move(a1) + b1; - EATEST_VERIFY(c == "abcdef"); - c.clear(); - - FSTest b2("def"); - c = "abc" + eastl::move(b2); - EATEST_VERIFY(c == "abcdef"); - c.clear(); - - FSTest a3("abc"); - c = eastl::move(a3) + "def"; - EATEST_VERIFY(c == "abcdef"); - c.clear(); - - FSTest a4("abc"); - c = eastl::move(a4) + 'd'; - EATEST_VERIFY(c == "abcd"); - c.clear(); - } - - - // bool operator==(const fixed_string<& a, const fixed_string& b) - // bool operator!=(const fixed_string<& a, const fixed_string& b) - EATEST_VERIFY( fs7 != fs8); - EATEST_VERIFY(!(fs7 == fs8)); - fs7 = fs8; - EATEST_VERIFY( fs7 == fs8); - EATEST_VERIFY(!(fs7 != fs8)); - } - - - { // Test overflow allocator specification - - typedef fixed_string<char8_t, 64, true, MallocAllocator> FixedString64Malloc; - - FixedString64Malloc fs; - - fs.push_back('a'); - EATEST_VERIFY(fs.size() == 1); - EATEST_VERIFY(fs[0] == 'a'); - - fs.resize(95); - fs[94] = 'b'; - EATEST_VERIFY(fs[0] == 'a'); - EATEST_VERIFY(fs[94] == 'b'); - EATEST_VERIFY(fs.size() == 95); - - fs.clear(); - EATEST_VERIFY(fs.empty()); - - fs.push_back('a'); - EATEST_VERIFY(fs.size() == 1); - EATEST_VERIFY(fs[0] == 'a'); - - fs.resize(195); - fs[194] = 'b'; - EATEST_VERIFY(fs[0] == 'a'); - EATEST_VERIFY(fs[194] == 'b'); - EATEST_VERIFY(fs.size() == 195); - } - - { - // Test construction of a container with an overflow allocator constructor argument. - MallocAllocator overflowAllocator; - void* p = overflowAllocator.allocate(1); - fixed_string<char8_t, 64, true, MallocAllocator> c(overflowAllocator); - c.resize(65); - EATEST_VERIFY(c.get_overflow_allocator().mAllocCount == 2); // 1 for above, and 1 for overflowing from 64 to 65. - overflowAllocator.deallocate(p, 1); - } - - { - // Regression for compile failure when EASTL_NO_RVALUE_REFERENCES is 0. - typedef eastl::fixed_string<char, 32, true, MallocAllocator> TestString; - - TestString ts1; - TestString ts2(ts1 + "Test"); - - EATEST_VERIFY(ts1.empty() && ts2.size() == 4); - } - - { - // Test equality tests of differently-sized fixed_strings. - - /* Disabled because this isn't currently supported by fixed_string. - typedef fixed_string<char8_t, 64, true, MallocAllocator> FixedString64Malloc; - typedef fixed_string<char8_t, 32> FixedString32; - - FixedString64Malloc s64M; - FixedString32 s32; - - EATEST_VERIFY(s64M == s32); - */ - } - - nErrorCount += TestFixedSubstring(); - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestFixedTupleVector.cpp b/test/source/TestFixedTupleVector.cpp deleted file mode 100644 index dbeb3fc..0000000 --- a/test/source/TestFixedTupleVector.cpp +++ /dev/null @@ -1,1594 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// TestFixedTupleVector.cpp -// -// Copyright (c) 2018, Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" - -#include <EASTL/bonus/fixed_tuple_vector.h> - -#include <EASTL/sort.h> - -using namespace eastl; - -template <size_t nodeCount, bool bEnableOverflow> -int TestFixedTupleVectorVariant() -{ - int nErrorCount = 0; - - // Test uninit'ed push-backs - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int> singleElementVec; - EATEST_VERIFY(singleElementVec.size() == 0); - EATEST_VERIFY(singleElementVec.capacity() == nodeCount); - EATEST_VERIFY(singleElementVec.empty() == true); - EATEST_VERIFY(singleElementVec.validate()); - singleElementVec.push_back_uninitialized(); - singleElementVec.push_back(5); - EATEST_VERIFY(singleElementVec.size() == 2); - EATEST_VERIFY(singleElementVec.template get<0>()[1] == 5); - EATEST_VERIFY(singleElementVec.template get<int>()[1] == 5); - EATEST_VERIFY(singleElementVec.empty() == false); - EATEST_VERIFY(singleElementVec.validate()); - - fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, bool> complexVec; - complexVec.reserve(5); - { - // need to call an overload of push_back that specifically grabs lvalue candidates - providing constants tend to prefer rvalue path - int intArg = 3; - float floatArg = 2.0f; - bool boolArg = true; - complexVec.push_back(intArg, floatArg, boolArg); - } - complexVec.push_back(1, 4.0f, false); - complexVec.push_back(2, 1.0f, true); - { - tuple<int, float, bool> complexTup(4, 3.0f, false); - complexVec.push_back(complexTup); - } - complexVec.push_back(); - EATEST_VERIFY((!complexVec.has_overflowed() && complexVec.capacity() == nodeCount) || complexVec.capacity() == 5); - EATEST_VERIFY(*(complexVec.template get<0>()) == 3); - EATEST_VERIFY(complexVec.template get<float>()[1] == 4.0f); - EATEST_VERIFY(complexVec.template get<2>()[2] == complexVec.template get<bool>()[2]); - EATEST_VERIFY(complexVec.validate()); - - tuple<int, float, bool> defaultComplexTup; - EATEST_VERIFY(complexVec.at(4) == defaultComplexTup); - - tuple<int*, float*, bool*> complexPtrTuple = complexVec.data(); - EATEST_VERIFY(get<0>(complexPtrTuple) != nullptr); - EATEST_VERIFY(get<2>(complexPtrTuple)[2] == complexVec.template get<2>()[2]); - - tuple<int&, float&, bool&> complexRefTuple = complexVec.at(2); - tuple<int&, float&, bool&> complexRefTupleBracket = complexVec[2]; - tuple<int&, float&, bool&> complexRefTupleFront = complexVec.front(); - tuple<int&, float&, bool&> complexRefTupleBack = complexVec.back(); - EATEST_VERIFY(get<2>(complexRefTuple) == complexVec.template get<2>()[2]); - EATEST_VERIFY(get<1>(complexRefTupleBracket) == 1.0f); - EATEST_VERIFY(get<1>(complexRefTupleFront) == 2.0f); - EATEST_VERIFY(get<1>(complexRefTupleBack) == 0.0f); - - // verify the equivalent accessors for the const container exist/compile - { - const fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, bool>& constVec = complexVec; - - EATEST_VERIFY(constVec.size() == 5); - EATEST_VERIFY(constVec.capacity() >= constVec.size()); - EATEST_VERIFY(constVec.empty() == false); - EATEST_VERIFY(constVec.template get<1>() == constVec.template get<float>()); - - tuple<const int*, const float*, const bool*> constPtrTuple = constVec.data(); - EATEST_VERIFY(get<0>(constPtrTuple) != nullptr); - EATEST_VERIFY(get<2>(constPtrTuple)[2] == constVec.template get<2>()[2]); - - tuple<const int&, const float&, const bool&> constRefTuple = constVec.at(2); - tuple<const int&, const float&, const bool&> constRefTupleBracket = constVec[2]; - tuple<const int&, const float&, const bool&> constRefTupleFront = constVec.front(); - tuple<const int&, const float&, const bool&> constRefTupleBack = constVec.back(); - EATEST_VERIFY(get<2>(constRefTuple) == constVec.template get<2>()[2]); - EATEST_VERIFY(get<1>(constRefTupleBracket) == 1.0f); - EATEST_VERIFY(get<1>(constRefTupleFront) == 2.0f); - EATEST_VERIFY(get<1>(constRefTupleBack) == 0.0f); - - // check that return types of const-version of begin and cbegin (etc) match - static_assert(eastl::is_same<decltype(constVec.begin()), decltype(constVec.cbegin())>::value, "error"); - static_assert(eastl::is_same<decltype(constVec.end()), decltype(constVec.cend())>::value, "error"); - static_assert(eastl::is_same<decltype(constVec.rbegin()), decltype(constVec.crbegin())>::value, "error"); - static_assert(eastl::is_same<decltype(constVec.rend()), decltype(constVec.crend())>::value, "error"); - - // check that return type of non-const version of begin and cbegin (etc) do _not_ match - static_assert(!eastl::is_same<decltype(complexVec.begin()), decltype(complexVec.cbegin())>::value, "error"); - static_assert(!eastl::is_same<decltype(complexVec.end()), decltype(complexVec.cend())>::value, "error"); - static_assert(!eastl::is_same<decltype(complexVec.rbegin()), decltype(complexVec.crbegin())>::value, "error"); - static_assert(!eastl::is_same<decltype(complexVec.rend()), decltype(complexVec.crend())>::value, "error"); - } - } - - // test the memory layouts work for aligned structures - { - struct EA_ALIGN(16) AlignTestVec4 - { - float a[4]; - AlignTestVec4() :a{ 1.0f, 2.0f, 3.0f, 4.0f } {} - }; - - struct AlignTestByte3 - { - char a[3]; - AlignTestByte3() : a{1, 2, 3} {} - }; - - struct EA_ALIGN(8) AlignTestFourByte - { - int a[5]; - AlignTestFourByte() : a{-1, -2, -3, -4, -5} {} - }; - - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, AlignTestVec4, AlignTestByte3, AlignTestFourByte> alignElementVec; - alignElementVec.push_back(); - alignElementVec.push_back(); - alignElementVec.push_back(); - alignElementVec.push_back(); - alignElementVec.push_back(); - - EATEST_VERIFY((uintptr_t)alignElementVec.template get<AlignTestVec4>() % 16 == 0); - EATEST_VERIFY((uintptr_t)alignElementVec.template get<AlignTestFourByte>() % 8 == 0); - } - - // Test various modifications - { - TestObject::Reset(); - - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - testVec.reserve(10); - for (int i = 0; i < 10; ++i) - { - testVec.push_back(i % 3 == 0, TestObject(i), (float)i); - } - testVec.pop_back(); - EATEST_VERIFY(testVec.size() == 9); - - // test resize that does destruction of objects - testVec.resize(5); - EATEST_VERIFY(testVec.size() == 5); - EATEST_VERIFY(TestObject::sTOCount == 5); - EATEST_VERIFY((!testVec.has_overflowed() && testVec.capacity() == nodeCount) || testVec.capacity() == 10); - - // test resize that does default construction of objects - testVec.resize(10); - EATEST_VERIFY(testVec.size() == 10); - EATEST_VERIFY(TestObject::sTOCount == 10); - - // test resize with args that does destruction of objects - testVec.resize(5, true, TestObject(5), 5.0f); - EATEST_VERIFY(testVec.size() == 5); - EATEST_VERIFY(TestObject::sTOCount == 5); - - // test resize with args that does construction of objects - testVec.resize(10, true, TestObject(5), 5.0f); - EATEST_VERIFY(testVec.size() == 10); - EATEST_VERIFY(TestObject::sTOCount == 10); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 5; i < 10; ++i) - { - EATEST_VERIFY(testVec.template get<0>()[i] == true); - EATEST_VERIFY(testVec.template get<1>()[i] == TestObject(5)); - EATEST_VERIFY(testVec.template get<2>()[i] == 5.0f); - } - - { - tuple<bool, TestObject, float> resizeTup(true, TestObject(10), 10.0f); - // test resize with tuple that does destruction of objects - testVec.resize(10, resizeTup); - EATEST_VERIFY(testVec.size() == 10); - EATEST_VERIFY(TestObject::sTOCount == 10 + 1); - - // test resize with tuple that does construction of objects - testVec.resize(15, resizeTup); - EATEST_VERIFY(testVec.size() == 15); - EATEST_VERIFY(TestObject::sTOCount == 15 + 1); - - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 5; i < 10; ++i) - { - EATEST_VERIFY(testVec.template get<0>()[i] == true); - EATEST_VERIFY(testVec.template get<1>()[i] == TestObject(5)); - EATEST_VERIFY(testVec.template get<2>()[i] == 5.0f); - } - for (unsigned int i = 10; i < 15; ++i) - { - EATEST_VERIFY(testVec.template get<0>()[i] == get<0>(resizeTup)); - EATEST_VERIFY(testVec.template get<1>()[i] == get<1>(resizeTup)); - EATEST_VERIFY(testVec.template get<2>()[i] == get<2>(resizeTup)); - } - } - - // test other modifiers - testVec.pop_back(); - EATEST_VERIFY(testVec.size() == 14); - EATEST_VERIFY(TestObject::sTOCount == 14); // down 2 from last sTOCount check - resizeTup dtor and pop_back - - if (testVec.can_overflow()) - { - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == testVec.size()); - } - EATEST_VERIFY(testVec.validate()); - - testVec.clear(); - EATEST_VERIFY(testVec.empty()); - EATEST_VERIFY(testVec.validate()); - EATEST_VERIFY(TestObject::IsClear()); - - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 0); - } - EATEST_VERIFY(testVec.validate()); - TestObject::Reset(); - } - - // Test insert - { - TestObject::Reset(); - - // test insert with n values and lvalue args - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - bool boolArg = true; - TestObject toArg = TestObject(0); - float floatArg = 0.0f; - testVec.reserve(10); - - // test insert on empty vector that doesn't cause growth - toArg = TestObject(3); - floatArg = 3.0f; - auto insertIter = testVec.insert(testVec.begin(), 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(insertIter == testVec.begin()); - - // test insert to end of vector that doesn't cause growth - toArg = TestObject(5); - floatArg = 5.0f; - insertIter = testVec.insert(testVec.end(), 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 6); - EATEST_VERIFY(insertIter == testVec.begin() + 3); - - // test insert to middle of vector that doesn't cause growth - toArg = TestObject(4); - floatArg = 4.0f; - testVec.insert(testVec.begin() + 3, 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 9); - EATEST_VERIFY(testVec.capacity() == 10 || testVec.capacity() == nodeCount); - - // test insert to end of vector that causes growth - toArg = TestObject(6); - floatArg = 6.0f; - testVec.insert(testVec.end(), 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 12); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 12 || testVec.capacity() == nodeCount); - - // test insert to beginning of vector that causes growth - toArg = TestObject(1); - floatArg = 1.0f; - testVec.insert(testVec.begin(), 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 15); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 15 || testVec.capacity() == nodeCount); - - // test insert to middle of vector that causes growth - toArg = TestObject(2); - floatArg = 2.0f; - testVec.insert(testVec.begin() + 3, 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 18); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 18 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.template get<1>()[i] == TestObject(i / 3 + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with lvalue args - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - bool boolArg = true; - TestObject toArg = TestObject(0); - float floatArg = 0.0f; - testVec.reserve(3); - - // test insert on empty vector that doesn't cause growth - toArg = TestObject(3); - floatArg = 3.0f; - testVec.insert(testVec.begin(), boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 1); - - // test insert to end of vector that doesn't cause growth - toArg = TestObject(5); - floatArg = 5.0f; - testVec.insert(testVec.end(), boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 2); - - // test insert to middle of vector that doesn't cause growth - toArg = TestObject(4); - floatArg = 4.0f; - testVec.insert(testVec.begin() + 1, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3 || testVec.capacity() == nodeCount); - - // test insert to end of vector that causes growth - toArg = TestObject(6); - floatArg = 6.0f; - testVec.insert(testVec.end(), boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 4); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 4 || testVec.capacity() == nodeCount); - - // test insert to beginning of vector that causes growth - toArg = TestObject(1); - floatArg = 1.0f; - testVec.insert(testVec.begin(), boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 5); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 5 || testVec.capacity() == nodeCount); - - // test insert to middle of vector that causes growth - toArg = TestObject(2); - floatArg = 2.0f; - testVec.insert(testVec.begin() + 1, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 6); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 6 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.template get<1>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with n and tuple - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - tuple<bool, TestObject, float> testTup; - testVec.reserve(10); - - // test insert on empty vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(3), 3.0f); - testVec.insert(testVec.begin(), 3, testTup); - EATEST_VERIFY(testVec.size() == 3); - - // test insert to end of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(5), 5.0f); - testVec.insert(testVec.end(), 3, testTup); - EATEST_VERIFY(testVec.size() == 6); - - // test insert to middle of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(4), 4.0f); - testVec.insert(testVec.begin() + 3, 3, testTup); - EATEST_VERIFY(testVec.size() == 9); - EATEST_VERIFY(testVec.capacity() == 10 || testVec.capacity() == nodeCount); - - // test insert to end of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(6), 6.0f); - testVec.insert(testVec.end(), 3, testTup); - EATEST_VERIFY(testVec.size() == 12); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 12 || testVec.capacity() == nodeCount); - - // test insert to beginning of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(1), 1.0f); - testVec.insert(testVec.begin(), 3, testTup); - EATEST_VERIFY(testVec.size() == 15); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - - EATEST_VERIFY(testVec.capacity() == 15 || testVec.capacity() == nodeCount); - // test insert to middle of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(2), 2.0f); - testVec.insert(testVec.begin() + 3, 3, testTup); - EATEST_VERIFY(testVec.size() == 18); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 18 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.template get<1>()[i] == TestObject(i / 3 + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with tuple - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - tuple<bool, TestObject, float> testTup; - testVec.reserve(3); - - // test insert on empty vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(3), 3.0f); - testVec.insert(testVec.begin(), testTup); - EATEST_VERIFY(testVec.size() == 1); - - // test insert to end of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(5), 5.0f); - testVec.insert(testVec.end(), testTup); - EATEST_VERIFY(testVec.size() == 2); - - // test insert to middle of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(4), 4.0f); - testVec.insert(testVec.begin() + 1, testTup); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3 || testVec.capacity() == nodeCount); - - // test insert to end of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(6), 6.0f); - testVec.insert(testVec.end(), 1, testTup); - EATEST_VERIFY(testVec.size() == 4); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 4 || testVec.capacity() == nodeCount); - - // test insert to beginning of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(1), 1.0f); - testVec.insert(testVec.begin(), 1, testTup); - EATEST_VERIFY(testVec.size() == 5); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 5 || testVec.capacity() == nodeCount); - - // test insert to middle of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(2), 2.0f); - testVec.insert(testVec.begin() + 1, 1, testTup); - EATEST_VERIFY(testVec.size() == 6); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 6 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.template get<1>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with initList - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - tuple<bool, TestObject, float> testTup; - testVec.reserve(10); - - // test insert on empty vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(3), 3.0f); - testVec.insert(testVec.begin(), { - {true, TestObject(3), 3.0f}, - testTup, - {true, TestObject(3), 3.0f} - }); - EATEST_VERIFY(testVec.size() == 3); - - // test insert to end of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(5), 5.0f); - testVec.insert(testVec.end(), { - {true, TestObject(5), 5.0f}, - testTup, - {true, TestObject(5), 5.0f} - }); - EATEST_VERIFY(testVec.size() == 6); - - // test insert to middle of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(4), 4.0f); - testVec.insert(testVec.begin() + 3, { - {true, TestObject(4), 4.0f}, - testTup, - {true, TestObject(4), 4.0f} - }); - EATEST_VERIFY(testVec.size() == 9); - EATEST_VERIFY(testVec.capacity() == 10 || testVec.capacity() == nodeCount); - - // test insert to end of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(6), 6.0f); - testVec.insert(testVec.end(), { - {true, TestObject(6), 6.0f}, - testTup, - {true, TestObject(6), 6.0f} - }); - EATEST_VERIFY(testVec.size() == 12); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 12 || testVec.capacity() == nodeCount); - - // test insert to beginning of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(1), 1.0f); - testVec.insert(testVec.begin(), { - {true, TestObject(1), 1.0f}, - testTup, - {true, TestObject(1), 1.0f} - }); - EATEST_VERIFY(testVec.size() == 15); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 15 || testVec.capacity() == nodeCount); - - // test insert to middle of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(2), 2.0f); - testVec.insert(testVec.begin() + 3, { - {true, TestObject(2), 2.0f}, - testTup, - {true, TestObject(2), 2.0f - } }); - EATEST_VERIFY(testVec.size() == 18); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 18 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.template get<1>()[i] == TestObject(i / 3 + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with rvalue args - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> testVec; - testVec.reserve(3); - - // test insert on empty vector that doesn't cause growth - testVec.insert(testVec.begin(), 3, MoveOnlyType(3), TestObject(3)); - EATEST_VERIFY(testVec.size() == 1); - - // test insert to end of vector that doesn't cause growth - testVec.insert(testVec.end(), 5, MoveOnlyType(5), TestObject(5)); - EATEST_VERIFY(testVec.size() == 2); - - // test insert to middle of vector that doesn't cause growth - testVec.insert(testVec.begin() + 1, 4, MoveOnlyType(4), TestObject(4)); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3 || testVec.capacity() == nodeCount); - - // test insert to end of vector that causes growth - testVec.insert(testVec.end(), 6, MoveOnlyType(6), TestObject(6)); - EATEST_VERIFY(testVec.size() == 4); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 4 || testVec.capacity() == nodeCount); - - // test insert to beginning of vector that causes growth - testVec.insert(testVec.begin(), 1, MoveOnlyType(1), TestObject(1)); - EATEST_VERIFY(testVec.size() == 5); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 5 || testVec.capacity() == nodeCount); - - // test insert to middle of vector that causes growth - testVec.insert(testVec.begin() + 1, 2, MoveOnlyType(2), TestObject(2)); - EATEST_VERIFY(testVec.size() == 6); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 6 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.template get<2>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with rvalue tuple - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> testVec; - testVec.reserve(3); - - // test insert on empty vector that doesn't cause growth - testVec.insert(testVec.begin(), forward_as_tuple(3, MoveOnlyType(3), TestObject(3))); - EATEST_VERIFY(testVec.size() == 1); - - // test insert to end of vector that doesn't cause growth - testVec.insert(testVec.end(), forward_as_tuple(5, MoveOnlyType(5), TestObject(5))); - EATEST_VERIFY(testVec.size() == 2); - - // test insert to middle of vector that doesn't cause growth - testVec.insert(testVec.begin() + 1, forward_as_tuple(4, MoveOnlyType(4), TestObject(4))); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3 || testVec.capacity() == nodeCount); - - // test insert to end of vector that causes growth - testVec.insert(testVec.end(), forward_as_tuple(6, MoveOnlyType(6), TestObject(6))); - EATEST_VERIFY(testVec.size() == 4); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 4 || testVec.capacity() == nodeCount); - - // test insert to beginning of vector that causes growth - testVec.insert(testVec.begin(), forward_as_tuple(1, MoveOnlyType(1), TestObject(1))); - EATEST_VERIFY(testVec.size() == 5); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 5 || testVec.capacity() == nodeCount); - - // test insert to middle of vector that causes growth - testVec.insert(testVec.begin() + 1, forward_as_tuple(2, MoveOnlyType(2), TestObject(2))); - EATEST_VERIFY(testVec.size() == 6); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 6 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.template get<2>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with iterator range - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> srcVec; - for (unsigned int i = 0; i < 20; ++i) - { - srcVec.push_back(true, TestObject(i), (float)i); - } - - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - testVec.reserve(10); - - // test insert on empty vector that doesn't cause growth - testVec.insert(testVec.begin(), srcVec.begin() + 6, srcVec.begin() + 9); - EATEST_VERIFY(testVec.size() == 3); - - // test insert to end of vector that doesn't cause growth - testVec.insert(testVec.end(), srcVec.begin() + 12, srcVec.begin() + 15); - EATEST_VERIFY(testVec.size() == 6); - - // test insert to middle of vector that doesn't cause growth - testVec.insert(testVec.begin() + 3, srcVec.begin() + 9, srcVec.begin() + 12); - EATEST_VERIFY(testVec.size() == 9); - EATEST_VERIFY(testVec.capacity() == 10 || testVec.capacity() == nodeCount); - - // test insert to end of vector that causes growth - testVec.insert(testVec.end(), srcVec.begin() + 15, srcVec.begin() + 18); - EATEST_VERIFY(testVec.size() == 12); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 12 || testVec.capacity() == nodeCount); - - // test insert to beginning of vector that causes growth - testVec.insert(testVec.begin(), srcVec.begin(), srcVec.begin() + 3); - EATEST_VERIFY(testVec.size() == 15); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 15 || testVec.capacity() == nodeCount); - - // test insert to middle of vector that causes growth - testVec.insert(testVec.begin() + 3, srcVec.begin() + 3, srcVec.begin() + 6); - EATEST_VERIFY(testVec.size() == 18); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 18 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - } - EATEST_VERIFY(testVec.validate()); - } - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test assign - { - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - - // test assign that grows the capacity - testVec.assign(20, true, TestObject(1), 1.0f); - EATEST_VERIFY(testVec.size() == 20); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(1), 1.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 20); - - // test assign that shrinks the vector - testVec.assign(10, true, TestObject(2), 2.0f); - EATEST_VERIFY(testVec.size() == 10); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(2), 2.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 10); - - // test assign for when there's enough capacity - testVec.assign(15, true, TestObject(3), 3.0f); - EATEST_VERIFY(testVec.size() == 15); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(3), 3.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 15); - } - - { - tuple<bool, TestObject, float> srcTup; - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - - // test assign from tuple that grows the capacity - srcTup = make_tuple(true, TestObject(1), 1.0f); - testVec.assign(20, srcTup); - EATEST_VERIFY(testVec.size() == 20); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcTup); - } - EATEST_VERIFY(TestObject::sTOCount == 20 + 1); - - // test assign from tuple that shrinks the vector - srcTup = make_tuple(true, TestObject(2), 2.0f); - testVec.assign(10, srcTup); - EATEST_VERIFY(testVec.size() == 10); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcTup); - } - EATEST_VERIFY(TestObject::sTOCount == 10 + 1); - - // test assign from tuple for when there's enough capacity - srcTup = make_tuple(true, TestObject(3), 3.0f); - testVec.assign(15, srcTup); - EATEST_VERIFY(testVec.size() == 15); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcTup); - } - EATEST_VERIFY(TestObject::sTOCount == 15 + 1); - } - - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> srcVec; - for (unsigned int i = 0; i < 20; ++i) - { - srcVec.push_back(true, TestObject(i), (float)i); - } - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - - // test assign from iter range that grows the capacity - testVec.assign(srcVec.begin() + 5, srcVec.begin() + 15); - EATEST_VERIFY(testVec.size() == 10); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcVec[i+5]); - } - EATEST_VERIFY(TestObject::sTOCount == 10 + 20); - - // test assign from iter range that shrinks the vector - testVec.assign(srcVec.begin() + 2, srcVec.begin() + 7); - EATEST_VERIFY(testVec.size() == 5); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcVec[i + 2]); - } - EATEST_VERIFY(TestObject::sTOCount == 5 + 20); - - // test assign from iter range for when there's enough capacity - testVec.assign(srcVec.begin() + 5, srcVec.begin() + 15); - EATEST_VERIFY(testVec.size() == 10); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcVec[i + 5]); - } - EATEST_VERIFY(TestObject::sTOCount == 10 + 20); - } - - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - - // test assign from initList that grows the capacity - testVec.assign({ - { true, TestObject(1), 1.0f }, - { true, TestObject(1), 1.0f }, - { true, TestObject(1), 1.0f } - }); - EATEST_VERIFY(testVec.size() == 3); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(1), 1.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 3); - - // test assign from initList that shrinks the vector - testVec.assign({ - { true, TestObject(2), 2.0f } - }); - EATEST_VERIFY(testVec.size() == 1); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(2), 2.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 1); - - // test assign from initList for when there's enough capacity - testVec.assign({ - { true, TestObject(3), 3.0f }, - { true, TestObject(3), 3.0f } - }); - EATEST_VERIFY(testVec.size() == 2); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(3), 3.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 2); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test erase functions - { - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> srcVec; - for (unsigned int i = 0; i < 20; ++i) - { - srcVec.push_back(true, TestObject(i), (float)i); - } - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - - // test erase on an iter range - testVec.assign(srcVec.begin(), srcVec.end()); - auto eraseIter = testVec.erase(testVec.begin() + 5, testVec.begin() + 10); - EATEST_VERIFY(eraseIter == testVec.begin() + 5); - EATEST_VERIFY(testVec.size() == 15); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i < 5) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 5), (float)(i + 5))); - } - EATEST_VERIFY(TestObject::sTOCount == 15 + 20); - - // test erase on one position - testVec.assign(srcVec.begin(), srcVec.end()); - eraseIter = testVec.erase(testVec.begin() + 5); - EATEST_VERIFY(eraseIter == testVec.begin() + 5); - EATEST_VERIFY(testVec.size() == 19); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i < 5) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 1), (float)(i + 1))); - } - EATEST_VERIFY(TestObject::sTOCount == 19 + 20); - - // test erase_unsorted - testVec.assign(srcVec.begin(), srcVec.end()); - eraseIter = testVec.erase_unsorted(testVec.begin() + 5); - EATEST_VERIFY(eraseIter == testVec.begin() + 5); - EATEST_VERIFY(testVec.size() == 19); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i != 5) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(19), (float)(19))); - } - EATEST_VERIFY(TestObject::sTOCount == 19 + 20); - } - - // test erase again but with reverse iterators everywhere - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> srcVec; - for (unsigned int i = 0; i < 20; ++i) - { - srcVec.push_back(true, TestObject(i), (float)i); - } - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> testVec; - - // test erase on an iter range - testVec.assign(srcVec.begin(), srcVec.end()); - auto eraseIter = testVec.erase(testVec.rbegin() + 5, testVec.rbegin() + 10); - EATEST_VERIFY(eraseIter == testVec.rbegin() + 5); - EATEST_VERIFY(testVec.size() == 15); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i < 10) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 5), (float)(i + 5))); - } - EATEST_VERIFY(TestObject::sTOCount == 15 + 20); - - // test erase on one position - testVec.assign(srcVec.begin(), srcVec.end()); - eraseIter = testVec.erase(testVec.rbegin() + 5); - EATEST_VERIFY(eraseIter == testVec.rbegin() + 5); - EATEST_VERIFY(testVec.size() == 19); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i < 14) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 1), (float)(i + 1))); - } - EATEST_VERIFY(TestObject::sTOCount == 19 + 20); - - // test erase_unsorted - testVec.assign(srcVec.begin(), srcVec.end()); - eraseIter = testVec.erase_unsorted(testVec.rbegin() + 5); - EATEST_VERIFY(eraseIter == testVec.rbegin() + 5); - EATEST_VERIFY(testVec.size() == 19); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i != 14) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(19), (float)(19))); - } - EATEST_VERIFY(TestObject::sTOCount == 19 + 20); - } - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test multitude of constructors - { - EASTLAllocatorType ma; - EASTLAllocatorType otherMa; - TestObject::Reset(); - - // test ctor via initlist to prime srcVec. Equivalent to ... - // for (int i = 0; i < 10; ++i) - // srcVec.push_back(i % 3 == 0, TestObject(i), (float)i); - - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> srcVec({ - { true, TestObject(0), 0.0f}, - { false, TestObject(1), 1.0f}, - { false, TestObject(2), 2.0f}, - { true, TestObject(3), 3.0f}, - { false, TestObject(4), 4.0f}, - { false, TestObject(5), 5.0f}, - { true, TestObject(6), 6.0f}, - { false, TestObject(7), 7.0f}, - { false, TestObject(8), 8.0f}, - { true, TestObject(9), 9.0f} - }); - - // copy entire tuple_vector in ctor - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorFromConstRef(srcVec); - EATEST_VERIFY(ctorFromConstRef.size() == 10); - EATEST_VERIFY(ctorFromConstRef.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromConstRef.template get<0>()[i] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromConstRef.template get<1>()[i] == TestObject(i)); - EATEST_VERIFY(ctorFromConstRef.template get<2>()[i] == (float)i); - } - } - - // copy entire tuple_vector via assignment - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorFromAssignment; - ctorFromAssignment = srcVec; - EATEST_VERIFY(ctorFromAssignment.size() == 10); - EATEST_VERIFY(ctorFromAssignment.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromAssignment.template get<0>()[i] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromAssignment.template get<1>()[i] == TestObject(i)); - EATEST_VERIFY(ctorFromAssignment.template get<2>()[i] == (float)i); - } - } - - // copy entire tuple_vector via assignment of init-list - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorFromAssignment; - ctorFromAssignment = { - { true, TestObject(0), 0.0f}, - { false, TestObject(1), 1.0f}, - { false, TestObject(2), 2.0f}, - { true, TestObject(3), 3.0f}, - { false, TestObject(4), 4.0f}, - { false, TestObject(5), 5.0f}, - { true, TestObject(6), 6.0f}, - { false, TestObject(7), 7.0f}, - { false, TestObject(8), 8.0f}, - { true, TestObject(9), 9.0f} - }; - EATEST_VERIFY(ctorFromAssignment.size() == 10); - EATEST_VERIFY(ctorFromAssignment.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromAssignment.template get<0>()[i] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromAssignment.template get<1>()[i] == TestObject(i)); - EATEST_VERIFY(ctorFromAssignment.template get<2>()[i] == (float)i); - } - } - - // ctor tuple_vector with iterator range - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorFromIters(srcVec.begin() + 2, srcVec.begin() + 7); - EATEST_VERIFY(ctorFromIters.size() == 5); - EATEST_VERIFY(ctorFromIters.validate()); - for (int i = 2; i < 7; ++i) - { - EATEST_VERIFY(ctorFromIters.template get<0>()[i - 2] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromIters.template get<1>()[i - 2] == TestObject(i)); - EATEST_VERIFY(ctorFromIters.template get<2>()[i - 2] == (float)i); - } - } - - // ctor tuple_vector with initial size - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorFromFill(10); - EATEST_VERIFY(ctorFromFill.size() == 10); - EATEST_VERIFY(ctorFromFill.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromFill.template get<0>()[i] == false); - EATEST_VERIFY(ctorFromFill.template get<1>()[i] == TestObject()); - EATEST_VERIFY(ctorFromFill.template get<2>()[i] == 0.0f); - } - } - - // ctor tuple_vector with initial size and args - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorFromFillArgs(10, true, TestObject(5), 5.0f); - EATEST_VERIFY(ctorFromFillArgs.size() == 10); - EATEST_VERIFY(ctorFromFillArgs.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromFillArgs.template get<0>()[i] == true); - EATEST_VERIFY(ctorFromFillArgs.template get<1>()[i] == TestObject(5)); - EATEST_VERIFY(ctorFromFillArgs.template get<2>()[i] == 5.0f); - } - } - - // ctor tuple_vector with initial size and tuple - { - tuple<bool, TestObject, float> tup(true, TestObject(5), 5.0f); - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorFromFillTup(10, tup); - EATEST_VERIFY(ctorFromFillTup.size() == 10); - EATEST_VERIFY(ctorFromFillTup.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromFillTup.template get<0>()[i] == true); - EATEST_VERIFY(ctorFromFillTup.template get<1>()[i] == TestObject(5)); - EATEST_VERIFY(ctorFromFillTup.template get<2>()[i] == 5.0f); - } - } - - // ctor tuple_Vector with custom mallocator - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorWithAlloc(ma); - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> ctorDefault; - - ctorWithAlloc.push_back(); - ctorDefault.push_back(); - - EATEST_VERIFY(ctorWithAlloc == ctorDefault); - EATEST_VERIFY(ctorWithAlloc.validate()); - } - - // ctor fixed_tuple_vector_alloc with copy (from diff. allocator) - { - fixed_tuple_vector<nodeCount, bEnableOverflow,bool, TestObject, float> ctorFromConstRef(srcVec, ma); - EATEST_VERIFY(ctorFromConstRef.size() == 10); - EATEST_VERIFY(ctorFromConstRef.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromConstRef.template get<0>()[i] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromConstRef.template get<1>()[i] == TestObject(i)); - EATEST_VERIFY(ctorFromConstRef.template get<2>()[i] == (float)i); - } - EATEST_VERIFY(ctorFromConstRef.validate()); - } - - // ctor tuple_vector with initial size and args - { - fixed_tuple_vector<nodeCount, bEnableOverflow,bool, TestObject, float> ctorFromFillArgs(10, true, TestObject(5), 5.0f, ma); - EATEST_VERIFY(ctorFromFillArgs.size() == 10); - EATEST_VERIFY(ctorFromFillArgs.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromFillArgs.template get<0>()[i] == true); - EATEST_VERIFY(ctorFromFillArgs.template get<1>()[i] == TestObject(5)); - EATEST_VERIFY(ctorFromFillArgs.template get<2>()[i] == 5.0f); - } - } - - // ctor tuple_vector via move - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> srcMoveVec; - for (int i = 0; i < 10; ++i) - { - srcMoveVec.emplace_back(move(i), MoveOnlyType(i), TestObject(i)); - } - - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> ctorFromMove(move(srcMoveVec)); - - EATEST_VERIFY(ctorFromMove.size() == 10); - EATEST_VERIFY(ctorFromMove.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromMove.template get<0>()[i] == i); - EATEST_VERIFY(ctorFromMove.template get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(ctorFromMove.template get<2>()[i] == TestObject(i)); - } - EATEST_VERIFY(srcMoveVec.size() == 0); - EATEST_VERIFY(srcMoveVec.validate()); - } - - // ctor tuple_vector via move (from diff. allocator) - { - fixed_tuple_vector<nodeCount, bEnableOverflow,int, MoveOnlyType, TestObject> srcMoveVec; - for (int i = 0; i < 10; ++i) - { - srcMoveVec.emplace_back(move(i), MoveOnlyType(i), TestObject(i)); - } - - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> ctorFromMove(move(srcMoveVec), otherMa); - - EATEST_VERIFY(ctorFromMove.size() == 10); - EATEST_VERIFY(ctorFromMove.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromMove.template get<0>()[i] == i); - EATEST_VERIFY(ctorFromMove.template get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(ctorFromMove.template get<2>()[i] == TestObject(i)); - } - EATEST_VERIFY(srcMoveVec.size() == 0); - EATEST_VERIFY(srcMoveVec.validate()); - - // bonus test for specifying a custom allocator, but using the same one as above - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> ctorFromMoveSameAlloc(move(ctorFromMove), otherMa); - EATEST_VERIFY(ctorFromMoveSameAlloc.size() == 10); - EATEST_VERIFY(ctorFromMoveSameAlloc.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromMoveSameAlloc.template get<0>()[i] == i); - EATEST_VERIFY(ctorFromMoveSameAlloc.template get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(ctorFromMoveSameAlloc.template get<2>()[i] == TestObject(i)); - } - EATEST_VERIFY(ctorFromMove.size() == 0); - EATEST_VERIFY(ctorFromMove.validate()); - } - - // ctor tuple_vector via move-iters - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> srcMoveVec; - for (int i = 0; i < 10; ++i) - { - srcMoveVec.emplace_back(move(i), MoveOnlyType(i), TestObject(i)); - } - - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> ctorFromMove(make_move_iterator(srcMoveVec.begin() + 2), make_move_iterator(srcMoveVec.begin() + 7)); - - EATEST_VERIFY(ctorFromMove.size() == 5); - EATEST_VERIFY(ctorFromMove.validate()); - for (int i = 2; i < 7; ++i) - { - EATEST_VERIFY(ctorFromMove.template get<0>()[i-2] == i); - EATEST_VERIFY(ctorFromMove.template get<1>()[i-2] == MoveOnlyType(i)); - EATEST_VERIFY(ctorFromMove.template get<2>()[i-2] == TestObject(i)); - } - EATEST_VERIFY(srcMoveVec.size() == 10); - EATEST_VERIFY(srcMoveVec.validate()); - for (int i = 0; i < 2; ++i) - { - EATEST_VERIFY(srcMoveVec.template get<0>()[i] == i); - EATEST_VERIFY(srcMoveVec.template get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(srcMoveVec.template get<2>()[i] == TestObject(i)); - } - for (int i = 2; i < 7; ++i) - { - EATEST_VERIFY(srcMoveVec.template get<0>()[i] == i); // int's just get copied because they're POD - EATEST_VERIFY(srcMoveVec.template get<1>()[i] == MoveOnlyType(0)); - EATEST_VERIFY(srcMoveVec.template get<2>()[i] == TestObject(0)); - } - for (int i = 7; i < 10; ++i) - { - EATEST_VERIFY(srcMoveVec.template get<0>()[i] == i); - EATEST_VERIFY(srcMoveVec.template get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(srcMoveVec.template get<2>()[i] == TestObject(i)); - } - } - - srcVec.clear(); - EATEST_VERIFY(TestObject::IsClear()); - - TestObject::Reset(); - } - - // Test swap - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, bool> complexVec; - complexVec.push_back(3, 2.0f, true); - complexVec.push_back(1, 4.0f, false); - complexVec.push_back(2, 1.0f, true); - complexVec.push_back(4, 3.0f, false); - - fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, bool> otherComplexVec; - complexVec.swap(otherComplexVec); - - EATEST_VERIFY(complexVec.size() == 0); - EATEST_VERIFY(complexVec.validate()); - EATEST_VERIFY(otherComplexVec.validate()); - EATEST_VERIFY(otherComplexVec.template get<0>()[0] == 3); - EATEST_VERIFY(otherComplexVec.template get<float>()[1] == 4.0f); - - complexVec.push_back(10, 10.0f, true); - swap(complexVec, otherComplexVec); - - EATEST_VERIFY(complexVec.validate()); - EATEST_VERIFY(*(complexVec.template get<0>()) == 3); - EATEST_VERIFY(complexVec.template get<float>()[1] == 4.0f); - - EATEST_VERIFY(otherComplexVec.validate()); - EATEST_VERIFY(otherComplexVec.template get<float>()[0] == 10.0f); - EATEST_VERIFY(otherComplexVec.size() == 1); - - } - - - // Test tuple_Vector in a ranged for, and other large-scale iterator testing - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, int> tripleElementVec; - tripleElementVec.push_back(1, 2.0f, 6); - tripleElementVec.push_back(2, 3.0f, 7); - tripleElementVec.push_back(3, 4.0f, 8); - tripleElementVec.push_back(4, 5.0f, 9); - tripleElementVec.push_back(5, 6.0f, 10); - - - // test copyConstructible, copyAssignable, swappable, prefix inc, !=, reference convertible to value_type (InputIterator!) - { - typename fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, int>::iterator iter = tripleElementVec.begin(); - ++iter; - auto copiedIter(iter); - EATEST_VERIFY(get<2>(*copiedIter) == 7); - EATEST_VERIFY(copiedIter == iter); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(copiedIter) != isf_none); - - ++iter; - copiedIter = iter; - EATEST_VERIFY(get<2>(*copiedIter) == 8); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(copiedIter) != isf_none); - - ++iter; - swap(iter, copiedIter); - EATEST_VERIFY(get<2>(*iter) == 8); - EATEST_VERIFY(get<2>(*copiedIter) == 9); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(copiedIter) != isf_none); - - EATEST_VERIFY(copiedIter != iter); - - tuple<const int&, const float&, const int&> ref(*iter); - tuple<int, float, int> value(*iter); - EATEST_VERIFY(get<2>(ref) == get<2>(value)); - } - - // test postfix increment, default constructible (ForwardIterator) - { - typename fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, int>::iterator iter = tripleElementVec.begin(); - auto prefixIter = ++iter; - - typename fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, int>::iterator postfixIter; - postfixIter = iter++; - EATEST_VERIFY(prefixIter == postfixIter); - EATEST_VERIFY(get<2>(*prefixIter) == 7); - EATEST_VERIFY(get<2>(*iter) == 8); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(prefixIter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(postfixIter) != isf_none); - } - - // test prefix decrement and postfix decrement (BidirectionalIterator) - { - typename fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, int>::iterator iter = tripleElementVec.end(); - auto prefixIter = --iter; - - typename fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, int>::iterator postfixIter; - postfixIter = iter--; - EATEST_VERIFY(prefixIter == postfixIter); - EATEST_VERIFY(get<2>(*prefixIter) == 10); - EATEST_VERIFY(get<2>(*iter) == 9); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(prefixIter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(postfixIter) != isf_none); - } - - // test many arithmetic operations (RandomAccessIterator) - { - typename fixed_tuple_vector<nodeCount, bEnableOverflow, int, float, int>::iterator iter = tripleElementVec.begin(); - auto symmetryOne = iter + 2; - auto symmetryTwo = 2 + iter; - iter += 2; - EATEST_VERIFY(symmetryOne == symmetryTwo); - EATEST_VERIFY(symmetryOne == iter); - - symmetryOne = iter - 2; - symmetryTwo = 2 - iter; - iter -= 2; - EATEST_VERIFY(symmetryOne == symmetryTwo); - EATEST_VERIFY(symmetryOne == iter); - - iter += 2; - EATEST_VERIFY(iter - symmetryOne == 2); - - tuple<int&, float&, int&> symmetryRef = symmetryOne[2]; - EATEST_VERIFY(get<2>(symmetryRef) == get<2>(*iter)); - - EATEST_VERIFY(symmetryOne < iter); - EATEST_VERIFY(iter > symmetryOne); - EATEST_VERIFY(symmetryOne >= symmetryTwo && iter >= symmetryOne); - EATEST_VERIFY(symmetryOne <= symmetryTwo && symmetryOne <= iter); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(symmetryOne) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(symmetryTwo) != isf_none); - } - - // test simple iteration, and reverse iteration - { - float i = 0; - int j = 0; - EATEST_VERIFY(&get<0>(*tripleElementVec.begin()) == tripleElementVec.template get<0>()); - EATEST_VERIFY(&get<1>(*tripleElementVec.begin()) == tripleElementVec.template get<1>()); - for (auto iter : tripleElementVec) - { - i += get<1>(iter); - j += get<2>(iter); - } - EATEST_VERIFY(i == 20.0f); - EATEST_VERIFY(j == 40); - - float reverse_i = 0; - int reverse_j = 0; - - eastl::for_each(tripleElementVec.rbegin(), tripleElementVec.rend(), - [&](const tuple<int, float, int> tup) - { - reverse_i += get<1>(tup); - reverse_j += get<2>(tup); - }); - EATEST_VERIFY(i == reverse_i); - EATEST_VERIFY(j == reverse_j); - EATEST_VERIFY(get<0>(*tripleElementVec.rbegin()) == 5); - } - } - - // Test move operations - { - TestObject::Reset(); - - // test emplace - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> testVec; - testVec.reserve(3); - - // test emplace on empty vector that doesn't cause growth - testVec.emplace(testVec.begin(), 3, MoveOnlyType(3), TestObject(3)); - EATEST_VERIFY(testVec.size() == 1); - - // test emplace to end of vector that doesn't cause growth - testVec.emplace(testVec.end(), 5, MoveOnlyType(5), TestObject(5)); - EATEST_VERIFY(testVec.size() == 2); - - // test emplace to middle of vector that doesn't cause growth - testVec.emplace(testVec.begin() + 1, 4, MoveOnlyType(4), TestObject(4)); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3 || testVec.capacity() == nodeCount); - - // test emplace to end of vector that causes growth - testVec.emplace(testVec.end(), 6, MoveOnlyType(6), TestObject(6)); - EATEST_VERIFY(testVec.size() == 4); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 4 || testVec.capacity() == nodeCount); - - // test emplace to beginning of vector that causes growth - testVec.emplace(testVec.begin(), 1, MoveOnlyType(1), TestObject(1)); - EATEST_VERIFY(testVec.size() == 5); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 5 || testVec.capacity() == nodeCount); - - // test emplace to middle of vector that causes growth - testVec.emplace(testVec.begin() + 1, 2, MoveOnlyType(2), TestObject(2)); - EATEST_VERIFY(testVec.size() == 6); - if (testVec.has_overflowed()) - { - testVec.shrink_to_fit(); - } - EATEST_VERIFY(testVec.capacity() == 6 || testVec.capacity() == nodeCount); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.template get<2>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test some other miscellania around rvalues, including... - // push_back with rvalue args, push_back with rvalue tuple, - // emplace_back with args, and emplace_back with tup - { - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> v1; - fixed_tuple_vector<nodeCount, bEnableOverflow, int, MoveOnlyType, TestObject> v2; - // add some data in the vector so we can move it to the other vector. - v1.reserve(5); - auto emplacedTup = v1.emplace_back(1, MoveOnlyType(1), TestObject(1)); - EATEST_VERIFY(emplacedTup == v1.back()); - v1.push_back(3, MoveOnlyType(3), TestObject(3)); - v1.emplace_back(forward_as_tuple(5, MoveOnlyType(5), TestObject(5))); - v1.push_back(forward_as_tuple(6, MoveOnlyType(6), TestObject(6))); - v1.emplace(v1.begin() + 1, 2, MoveOnlyType(2), TestObject(2)); - v1.emplace(v1.begin() + 3, make_tuple(4, MoveOnlyType(4), TestObject(4))); - - tuple<int&, MoveOnlyType&, TestObject&> movedTup = v1.at(0); - EATEST_VERIFY(v1.validate()); - EATEST_VERIFY(get<0>(movedTup) == 1); - EATEST_VERIFY(get<0>(*v1.begin()) == 1); - - for (int i = 0; i < static_cast<int>(v1.size()); ++i) - { - EATEST_VERIFY(v1.template get<0>()[i] == i + 1); - } - EATEST_VERIFY(!v1.empty() && v2.empty()); - v2 = eastl::move(v1); - EATEST_VERIFY(v2.validate()); - EATEST_VERIFY(v1.empty() && !v2.empty()); - v1.swap(v2); - EATEST_VERIFY(v1.validate()); - EATEST_VERIFY(v2.validate()); - EATEST_VERIFY(!v1.empty() && v2.empty()); - } - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test comparisons - { - - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float> equalsVec1, equalsVec2; - for (int i = 0; i < 10; ++i) - { - equalsVec1.push_back(i % 3 == 0, TestObject(i), (float)i); - equalsVec2.push_back(i % 3 == 0, TestObject(i), (float)i); - } - EATEST_VERIFY(equalsVec1 == equalsVec2); - - using ftv = fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float>; - typename ftv::overflow_allocator_type otherAlloc; - ftv smallSizeVec(5); - ftv lessThanVec(10); - ftv greaterThanVec(10, otherAlloc); - for (int i = 0; i < 10; ++i) - { - lessThanVec.push_back(i % 3 == 0, TestObject(i), (float)i); - greaterThanVec.push_back(i % 3 == 0, TestObject(i * 2), (float)i * 2); - } - EATEST_VERIFY(equalsVec1 != smallSizeVec); - EATEST_VERIFY(equalsVec1 != lessThanVec); - EATEST_VERIFY(equalsVec1 != greaterThanVec); - EATEST_VERIFY(lessThanVec < greaterThanVec); - EATEST_VERIFY(greaterThanVec > lessThanVec); - EATEST_VERIFY(lessThanVec <= greaterThanVec); - EATEST_VERIFY(equalsVec1 <= equalsVec2); - EATEST_VERIFY(equalsVec1 >= equalsVec2); - } - - // Test partition - { - { - fixed_tuple_vector<nodeCount, bEnableOverflow, bool, TestObject, float, MoveOnlyType> vec; - for (int i = 0; i < 10; ++i) - { - vec.push_back(i % 3 == 0, TestObject(i), (float)i, MoveOnlyType(i)); - } - - eastl::partition(vec.begin(), vec.end(), [](tuple<bool&, TestObject&, float&, MoveOnlyType&> a) - { return get<0>(a) == true; }); - - // partition will split the array into 4 elements where the bool property is true, and 6 where it's false - for (int i = 0; i < 4; ++i) - EATEST_VERIFY(vec.template get<0>()[i] == true); - for (int i = 4; i < 10; ++i) - EATEST_VERIFY(vec.template get<0>()[i] == false); - - EATEST_VERIFY(vec.validate()); - EATEST_VERIFY(TestObject::sTOCount == 10); - } - EATEST_VERIFY(TestObject::IsClear()); - } - return nErrorCount; -} - -int TestFixedTupleVector() -{ - int nErrorCount = 0; - - nErrorCount += TestFixedTupleVectorVariant<2, true>(); - nErrorCount += TestFixedTupleVectorVariant<16, true>(); - nErrorCount += TestFixedTupleVectorVariant<64, false>(); - - return nErrorCount; -} - - diff --git a/test/source/TestFixedVector.cpp b/test/source/TestFixedVector.cpp deleted file mode 100644 index aeb3ba2..0000000 --- a/test/source/TestFixedVector.cpp +++ /dev/null @@ -1,581 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/fixed_vector.h> -#include <EASTL/unique_ptr.h> -#include <EAStdC/EAMemory.h> -#include <new> - -#if defined(EA_COMPILER_CPP17_ENABLED) && __has_include(<variant>) -#include <variant> //Variant not present in older standards -#endif - - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::fixed_vector<int, 1, true>; -template class eastl::fixed_vector<Align64, 1, true>; -template class eastl::fixed_vector<TestObject, 1, true>; - -template class eastl::fixed_vector<int, 1, false>; -template class eastl::fixed_vector<Align64, 1, false>; -template class eastl::fixed_vector<TestObject, 1, false>; - -/* -// This does not compile, since the fixed_vector allocator is templated on sizeof(T), -// not just T. Thus, the full type is required at the time of instantiation, but it -// is not available. -// See EATech Core JIRA issue ETCR-1608 for more information. -struct StructWithContainerOfStructs -{ - eastl::fixed_vector<StructWithContainerOfStructs,4> children; -}; -*/ - - -namespace -{ - // Aligned objects should be CustomAllocator instead of the default, because the - // EASTL default might be unable to do aligned allocations, but CustomAllocator always can. - typedef fixed_vector<Align64, 3, true, CustomAllocator> VA64; - - VA64 vA64; - Align64 a64(5); - Align64* pA64 = &a64; -} - - -int TestFixedVector() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { // Test the aligned_buffer template - { - eastl::aligned_buffer<sizeof(TestObject), EASTL_ALIGN_OF(TestObject)> toAlignedBuffer; - TestObject* const pTO = new(toAlignedBuffer.buffer) TestObject; - #if !defined(__GNUC__) // GCC complains about strict aliasing here. - EATEST_VERIFY(pTO->mX == ((TestObject*)&toAlignedBuffer.buffer[0])->mX); - #endif - pTO->~TestObject(); - } - - { - eastl::aligned_buffer<sizeof(Align64), EASTL_ALIGN_OF(Align64)> a64AlignedBuffer; - Align64* const pAlign64 = new(a64AlignedBuffer.buffer) Align64; - #if !defined(__GNUC__) // GCC complains about strict aliasing here. - EATEST_VERIFY(pAlign64->mX == ((Align64*)&a64AlignedBuffer.buffer[0])->mX); - #endif - pAlign64->~Align64(); - } - } - - { - // fixed_vector(); - // size_type max_size() const; - fixed_vector<int, 1, true> v; - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "fixed_vector", -1)); - EATEST_VERIFY(v.max_size() == 1); - - // fixed_vector(); - typedef fixed_vector<int, 8, false> FixedVectorInt8; - FixedVectorInt8 fv1; - EATEST_VERIFY(fv1.size() == 0); - EATEST_VERIFY(fv1.capacity() == 8); - - // this_type& operator=(const base_type& x); - FixedVectorInt8 fv2 = fv1; - EATEST_VERIFY(fv2.size() == 0); - EATEST_VERIFY(fv2.capacity() == 8); - - // fixed_vector(const base_type& x); - FixedVectorInt8 fv3(fv1); - EATEST_VERIFY(fv3.size() == 0); - EATEST_VERIFY(fv3.capacity() == 8); - - // explicit fixed_vector(size_type n); - FixedVectorInt8 fv4(5); - EATEST_VERIFY(fv4.size() == 5); - EATEST_VERIFY(fv4.capacity() == 8); - EATEST_VERIFY((fv4[0] == 0) && (fv4[4] == 0)); - - // fixed_vector(size_type n, const value_type& value); - FixedVectorInt8 fv5((eastl_size_t)5, (int)3); - EATEST_VERIFY(fv5.size() == 5); - EATEST_VERIFY(fv5.capacity() == 8); - EATEST_VERIFY((fv5[0] == 3) && (fv5[4] == 3)); - - // fixed_vector(InputIterator first, InputIterator last); - const int intArray[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - FixedVectorInt8 fv6(intArray, intArray + 8); - EATEST_VERIFY(fv6.size() == 8); - EATEST_VERIFY(fv5.capacity() == 8); - EATEST_VERIFY((fv6[0] == 0) && (fv6[7] == 7)); - - // void reset_lose_memory(); - fv6.reset_lose_memory(); - EATEST_VERIFY(fv6.size() == 0); - EATEST_VERIFY(fv6.capacity() == 8); - - // void set_capacity(size_type); - fv6.set_capacity(100); // overflow is disabled, so this should have no effect. - EATEST_VERIFY(fv6.size() == 0); - EATEST_VERIFY(fv6.capacity() == 8); // EATEST_VERIFY that the capacity is unchanged. - - fv6.resize(8); - EATEST_VERIFY(fv6.size() == 8); - fv6.set_capacity(1); - EATEST_VERIFY(fv6.size() == 1); - EATEST_VERIFY(fv6.capacity() == 8); - - // Exercise the freeing of memory in set_capacity. - fixed_vector<int, 8, true> fv88; - eastl_size_t capacity = fv88.capacity(); - fv88.resize(capacity); - fv88.set_capacity(capacity * 2); - EATEST_VERIFY(fv88.capacity() >= (capacity * 2)); - - // void swap(this_type& x); - // FixedVectorInt8 fv7(5, 3); // MSVC-ARM64 generated an internal compiler error on this line. - FixedVectorInt8 fv7 = {3, 3, 3, 3, 3}; - FixedVectorInt8 fv8(intArray, intArray + 8); - - swap(fv7, fv8); - EATEST_VERIFY(fv7.size() == 8); - EATEST_VERIFY((fv7[0] == 0) && (fv7[7] == 7)); - EATEST_VERIFY(fv8.size() == 5); - EATEST_VERIFY((fv8[0] == 3) && (fv8[4] == 3)); - - fv7.swap(fv8); - EATEST_VERIFY(fv8.size() == 8); - EATEST_VERIFY((fv8[0] == 0) && (fv8[7] == 7)); - EATEST_VERIFY(fv7.size() == 5); - EATEST_VERIFY((fv7[0] == 3) && (fv7[4] == 3)); - - // Test a recent optimization we added, which was to do a pointer swap of the fixed_vector pointers - // for the case that both fixed_vectors were overflowed and using the heap instead of their fixed buffers. - fixed_vector<int8_t, 4, true> fvo5; - fixed_vector<int8_t, 4, true> fvo6; - fvo5.resize(5, 5); - EATEST_VERIFY(fvo5.has_overflowed()); - fvo6.resize(6, 6); - EATEST_VERIFY(fvo6.has_overflowed()); - fvo5.swap(fvo6); - EATEST_VERIFY(fvo5.size() == 6); // Verify that sizes are swapped. - EATEST_VERIFY(fvo6.size() == 5); - EATEST_VERIFY(EA::StdC::Memcheck8(fvo5.data(), 6, fvo5.size()) == NULL); // Verify that contents are swapped. - EATEST_VERIFY(EA::StdC::Memcheck8(fvo6.data(), 5, fvo6.size()) == NULL); - - // global operators - EATEST_VERIFY( fv7 != fv8); - EATEST_VERIFY(!(fv7 == fv8)); - fv7 = fv8; - EATEST_VERIFY( fv7 == fv8); - EATEST_VERIFY(!(fv7 != fv8)); - EATEST_VERIFY(fv7.validate()); - EATEST_VERIFY(fv8.validate()); - } - - - { - // POD types - typedef fixed_vector<int, 1, true> vInt; - - vInt v; - int n = 5; - int* pN = &n; - - v.insert(v.begin(), pN, pN + 1); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "fixed_vector", 5, -1)); - EATEST_VERIFY(v.validate()); - } - - - { - // non POD types - typedef fixed_vector<TestObject, 1, true> VTO; - - VTO v; - TestObject to(5); - TestObject* pTO = &to; - - v.insert(v.begin(), pTO, pTO + 1); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "fixed_vector", 5, -1)); - EATEST_VERIFY(v.validate()); - } - - - { - // non POD types - - // The variables used here are declared above in the global space. - vA64.insert(vA64.begin(), pA64, pA64 + 1); - EATEST_VERIFY(VerifySequence(vA64.begin(), vA64.end(), int(), "fixed_vector", 5, -1)); - EATEST_VERIFY(((uintptr_t)&a64 % kEASTLTestAlign64) == 0); - EATEST_VERIFY(((uintptr_t)vA64.data() % kEASTLTestAlign64) == 0); - EATEST_VERIFY(((uintptr_t)&vA64[0] % kEASTLTestAlign64) == 0); - EATEST_VERIFY(vA64.max_size() == 3); - EATEST_VERIFY(vA64.validate()); - } - - - { - // Test for potential bug reported Sep. 19, 2006. - typedef eastl::fixed_vector<void*, 160, false> FixedVector; - FixedVector v; - int* p = (int*)(uintptr_t)0; - - for(int i = 0; i < 100; i++, p++) - v.push_back(p); - - EATEST_VERIFY(v.size() == 100); - EATEST_VERIFY(eastl::unique(v.begin(), v.end()) == v.end()); - - FixedVector::iterator it = eastl::lower_bound(v.begin(), v.end(), p - 30); - EATEST_VERIFY(v.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - EATEST_VERIFY((*it) == (p - 30)); - - v.erase(it); - - EATEST_VERIFY(v.size() == 99); - EATEST_VERIFY(eastl::unique(v.begin(), v.end()) == v.end()); - } - - { - typedef fixed_vector<Align64, 4, true, CustomAllocator> FixedVectorWithAlignment; - - FixedVectorWithAlignment fv; - - Align64 a; - - fv.push_back(a); - fv.push_back(a); - fv.push_back(a); - fv.push_back(a); - fv.push_back(a); - for (FixedVectorWithAlignment::const_iterator it = fv.begin(); it != fv.end(); ++it) - { - const Align64* ptr = &(*it); - EATEST_VERIFY((uint64_t)ptr % EASTL_ALIGN_OF(Align64) == 0); - } - } - - { // Test overflow allocator specification - typedef fixed_vector<char8_t, 64, true, MallocAllocator> FixedString64Malloc; - - FixedString64Malloc fs; - - fs.push_back('a'); - EATEST_VERIFY(fs.size() == 1); - EATEST_VERIFY(fs[0] == 'a'); - - fs.resize(95); - fs[94] = 'b'; - EATEST_VERIFY(fs[0] == 'a'); - EATEST_VERIFY(fs[94] == 'b'); - EATEST_VERIFY(fs.size() == 95); - EATEST_VERIFY(fs.validate()); - - fs.clear(); - EATEST_VERIFY(fs.empty()); - - fs.push_back('a'); - EATEST_VERIFY(fs.size() == 1); - EATEST_VERIFY(fs[0] == 'a'); - EATEST_VERIFY(fs.validate()); - - fs.resize(195); - fs[194] = 'b'; - EATEST_VERIFY(fs[0] == 'a'); - EATEST_VERIFY(fs[194] == 'b'); - EATEST_VERIFY(fs.size() == 195); - EATEST_VERIFY(fs.validate()); - - // get_overflow_allocator / set_overflow_allocator - fs.set_capacity(0); // This should free all memory allocated by the existing (overflow) allocator. - EATEST_VERIFY(fs.validate()); - MallocAllocator a; - fs.get_allocator().set_overflow_allocator(a); - EATEST_VERIFY(fs.validate()); - fs.resize(400); - EATEST_VERIFY(fs.validate()); - } - - - { - //Test clear(bool freeOverflow) - const size_t nodeCount = 4; - typedef fixed_vector<int, nodeCount, true> vInt4; - vInt4 fv; - for (int i = 0; (unsigned)i < nodeCount+1; i++) - { - fv.push_back(i); - } - vInt4::size_type capacity = fv.capacity(); - EATEST_VERIFY(capacity >= nodeCount+1); - fv.clear(false); - EATEST_VERIFY(fv.size() == 0); - EATEST_VERIFY(fv.capacity() == capacity); - fv.push_back(1); - fv.clear(true); - EATEST_VERIFY(fv.size() == 0); - EATEST_VERIFY(fv.capacity() == nodeCount); - } - - - { - // bool empty() const - // bool has_overflowed() const - // size_type size() const; - // size_type max_size() const - - // Test a vector that has overflow disabled. - fixed_vector<int, 5, false> vInt5; - - EATEST_VERIFY(vInt5.max_size() == 5); - EATEST_VERIFY(vInt5.size() == 0); - EATEST_VERIFY(vInt5.empty()); - EATEST_VERIFY(!vInt5.has_overflowed()); - - vInt5.push_back(37); - vInt5.push_back(37); - vInt5.push_back(37); - - EATEST_VERIFY(vInt5.size() == 3); - EATEST_VERIFY(!vInt5.empty()); - EATEST_VERIFY(!vInt5.has_overflowed()); - - vInt5.push_back(37); - vInt5.push_back(37); - - EATEST_VERIFY(vInt5.size() == 5); - EATEST_VERIFY(!vInt5.empty()); - EATEST_VERIFY(!vInt5.has_overflowed()); - - vInt5.pop_back(); - - EATEST_VERIFY(vInt5.size() == 4); - EATEST_VERIFY(!vInt5.empty()); - EATEST_VERIFY(!vInt5.has_overflowed()); - EATEST_VERIFY(vInt5.validate()); - } - - - { - // bool empty() const - // bool has_overflowed() const - // size_type size() const; - // size_type max_size() const - - // Test a list that has overflow enabled. - fixed_vector<int, 5, true> vInt5; - - EATEST_VERIFY(vInt5.max_size() == 5); - EATEST_VERIFY(vInt5.size() == 0); - EATEST_VERIFY(vInt5.empty()); - EATEST_VERIFY(!vInt5.has_overflowed()); - - vInt5.push_back(37); - vInt5.push_back(37); - vInt5.push_back(37); - - EATEST_VERIFY(vInt5.size() == 3); - EATEST_VERIFY(!vInt5.empty()); - EATEST_VERIFY(!vInt5.has_overflowed()); - - vInt5.push_back(37); - vInt5.push_back(37); - - EATEST_VERIFY(vInt5.size() == 5); - EATEST_VERIFY(!vInt5.empty()); - EATEST_VERIFY(!vInt5.has_overflowed()); - - vInt5.push_back(37); - - EATEST_VERIFY(vInt5.size() == 6); - EATEST_VERIFY(!vInt5.empty()); - EATEST_VERIFY(vInt5.has_overflowed()); - - vInt5.clear(); - - EATEST_VERIFY(vInt5.size() == 0); - EATEST_VERIFY(vInt5.empty()); - EATEST_VERIFY(vInt5.has_overflowed()); // Note that we declare the container full, as it is no longer using the fixed-capacity. - EATEST_VERIFY(vInt5.validate()); - } - - { - // void* push_back_uninitialized(); - - int64_t toCount0 = TestObject::sTOCount; - - eastl::fixed_vector<TestObject, 32, false> vTO1; // <-- bEnableOverflow = false - EATEST_VERIFY(TestObject::sTOCount == toCount0); - - for(int i = 0; i < 25; i++) // 25 is simply a number that is <= 32. - { - void* pTO1 = vTO1.push_back_uninitialized(); - EATEST_VERIFY(TestObject::sTOCount == (toCount0 + i)); - - new(pTO1) TestObject(i); - EATEST_VERIFY(TestObject::sTOCount == (toCount0 + i + 1)); - EATEST_VERIFY(vTO1.back().mX == i); - EATEST_VERIFY(vTO1.validate()); - } - } - - { - // void* push_back_uninitialized(); - - int64_t toCount0 = TestObject::sTOCount; - - eastl::fixed_vector<TestObject, 15, true> vTO2; // <-- bEnableOverflow = true - EATEST_VERIFY(TestObject::sTOCount == toCount0); - - for(int i = 0; i < 25; i++) // 25 is simply a number that is > 15. - { - void* pTO2 = vTO2.push_back_uninitialized(); - EATEST_VERIFY(TestObject::sTOCount == (toCount0 + i)); - - new(pTO2) TestObject(i); - EATEST_VERIFY(TestObject::sTOCount == (toCount0 + i + 1)); - EATEST_VERIFY(vTO2.back().mX == i); - EATEST_VERIFY(vTO2.validate()); - } - } - - { // Try to repro user report that fixed_vector on the stack crashes. - eastl::fixed_vector<int, 10, false> fvif; - eastl::fixed_vector<int, 10, true> fvit; - eastl::fixed_vector<TestObject, 10, false> fvof; - eastl::fixed_vector<TestObject, 10, true> fvot; - eastl::fixed_vector<int, 10, false, MallocAllocator> fvimf; - eastl::fixed_vector<int, 10, true, MallocAllocator> fvimt; - eastl::fixed_vector<TestObject, 10, false, MallocAllocator> fvomf; - eastl::fixed_vector<TestObject, 10, true, MallocAllocator> fvomt; - - fvif.push_back(1); - fvit.push_back(1); - fvimf.push_back(1); - fvimt.push_back(1); - - fvif.clear(); - fvit.clear(); - fvimf.clear(); - fvimt.clear(); - } - - { - // Test construction of a container with an overflow allocator constructor argument. - MallocAllocator overflowAllocator; - void* p = overflowAllocator.allocate(1); - fixed_vector<int, 64, true, MallocAllocator> c(overflowAllocator); - c.resize(65); - EATEST_VERIFY(c.get_overflow_allocator().mAllocCount == 2); // 1 for above, and 1 for overflowing from 64 to 65. - overflowAllocator.deallocate(p, 1); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - { // Test for crash bug reported by Arpit Baldeva. - eastl::fixed_vector<void*, 1, true> test; - - test.push_back(NULL); - test.push_back(NULL); - test.erase(eastl::find(test.begin(), test.end(), (void*)NULL)); - test.erase(eastl::find(test.begin(), test.end(), (void*)NULL)); - EATEST_VERIFY(test.empty()); - EATEST_VERIFY(test.validate()); - - test.set_capacity(0); // "Does nothing currently." - EATEST_VERIFY(test.capacity() == 0); - EATEST_VERIFY(test.validate()); - - } // "Crash here." - - { - const int FV_SIZE = 100; - fixed_vector<unique_ptr<unsigned int>, FV_SIZE> fvmv1; // to move via move assignment operator - fixed_vector<unique_ptr<unsigned int>, FV_SIZE> fvmv2; // to move via move copy constructor - - for (unsigned int i = 0; i < FV_SIZE; ++i) // populate fvmv1 - fvmv1.push_back(make_unique<unsigned int>(i)); - - fvmv2 = eastl::move(fvmv1); // Test move assignment operator - - for (unsigned int i = 0; i < FV_SIZE; ++i) - { - EATEST_VERIFY(!fvmv1[i]); - EATEST_VERIFY(*fvmv2[i] == i); - } - EATEST_VERIFY(fvmv2.validate()); - - swap(fvmv1, fvmv2); // Test swap with move-only objects - for (unsigned int i = 0; i < FV_SIZE; ++i) - { - EATEST_VERIFY(*fvmv1[i] == i); - EATEST_VERIFY(!fvmv2[i]); - } - EATEST_VERIFY(fvmv1.validate()); - EATEST_VERIFY(fvmv2.validate()); - - fixed_vector<unique_ptr<unsigned int>, FV_SIZE> fv = eastl::move(fvmv1); // Test move copy constructor - for (unsigned int i = 0; i < FV_SIZE; ++i) - { - EATEST_VERIFY(!fvmv1[i]); - EATEST_VERIFY(*fv[i] == i); - } - EATEST_VERIFY(fv.validate()); - } - - { // Test that ensures that move ctor that triggers realloc (e.g. > capacity) does so via move code path - eastl::fixed_vector<TestObject, 1, true> fv1; - fv1.push_back(TestObject(0)); - fv1.push_back(TestObject(0)); - int64_t copyCtorCount0 = TestObject::sTOCopyCtorCount, moveCtorCount0 = TestObject::sTOMoveCtorCount; - decltype(fv1) fv2 = eastl::move(fv1); - EATEST_VERIFY(TestObject::sTOCopyCtorCount == copyCtorCount0 && TestObject::sTOMoveCtorCount == (moveCtorCount0 + 2)); - } - { // Same as above but with custom statefull allocator - struct MyAlloc : public eastl::allocator - { - MyAlloc()=default; - MyAlloc(int i) : dummy(i) {} - int dummy; - }; - eastl::fixed_vector<TestObject, 1, true, MyAlloc> fv1; - fv1.push_back(TestObject(0)); - fv1.push_back(TestObject(0)); - int64_t copyCtorCount0 = TestObject::sTOCopyCtorCount, moveCtorCount0 = TestObject::sTOMoveCtorCount; - decltype(fv1) fv2(eastl::move(fv1), MyAlloc(123)); - EATEST_VERIFY(TestObject::sTOCopyCtorCount == copyCtorCount0 && TestObject::sTOMoveCtorCount == (moveCtorCount0 + 2)); - } - - #if defined(EA_COMPILER_CPP17_ENABLED) && __has_include(<variant>) - //Test pairing of std::variant with fixed_vector - { - eastl::fixed_vector<std::variant<int>, 4> v; - eastl::fixed_vector<std::variant<int>, 4> b = eastl::move(v); - } - #endif - return nErrorCount; -} - - - - - - - - - - diff --git a/test/source/TestFunctional.cpp b/test/source/TestFunctional.cpp deleted file mode 100644 index 1e25200..0000000 --- a/test/source/TestFunctional.cpp +++ /dev/null @@ -1,1529 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include <EABase/eabase.h> -#include <EAAssert/eaassert.h> -#include "EASTLTest.h" -#include <EASTL/memory.h> -#include <EASTL/functional.h> -#include <EASTL/hash_set.h> -#include <EASTL/set.h> -#include <EASTL/list.h> -#include <EAStdC/EAString.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#include <functional> -EA_RESTORE_ALL_VC_WARNINGS() - -namespace -{ - - // Used for eastl::function tests - static int TestIntRet(int* p) - { - int ret = *p; - *p += 1; - return ret; - } - - // Used for str_less tests below. - template <typename T> - struct Results - { - const T* p1; - const T* p2; - bool expectedResult; // The expected result of the expression (p1 < p2) - }; - - - // Used for const_mem_fun_t below. - struct X - { - X() { } - void DoNothing() const { } - }; - - template <typename T> - void foo(typename T::argument_type arg) - { - typename T::result_type (T::*pFunction)(typename T::argument_type) const = &T::operator(); - T t(&X::DoNothing); - (t.*pFunction)(arg); - } - - - // Used for equal_to_2 tests below. - struct N1{ - N1(int x) : mX(x) { } - int mX; - }; - - struct N2{ - N2(int x) : mX(x) { } - int mX; - }; - - bool operator==(const N1& n1, const N1& n1a){ return (n1.mX == n1a.mX); } - bool operator==(const N1& n1, const N2& n2) { return (n1.mX == n2.mX); } - bool operator==(const N2& n2, const N1& n1) { return (n2.mX == n1.mX); } - bool operator==(const volatile N1& n1, const volatile N1& n1a) { return (n1.mX == n1a.mX); } - - bool operator!=(const N1& n1, const N1& n1a){ return (n1.mX != n1a.mX); } - bool operator!=(const N1& n1, const N2& n2) { return (n1.mX != n2.mX); } - bool operator!=(const N2& n2, const N1& n1) { return (n2.mX != n1.mX); } - bool operator!=(const volatile N1& n1, const volatile N1& n1a) { return (n1.mX != n1a.mX); } - - bool operator< (const N1& n1, const N1& n1a){ return (n1.mX < n1a.mX); } - bool operator< (const N1& n1, const N2& n2) { return (n1.mX < n2.mX); } - bool operator< (const N2& n2, const N1& n1) { return (n2.mX < n1.mX); } - bool operator< (const volatile N1& n1, const volatile N1& n1a) { return (n1.mX < n1a.mX); } - - - // Used for mem_fun tests below. - struct TestClass - { - mutable int mX; - - TestClass() : mX(37) { } - - void Increment() - { - mX++; - } - - void IncrementConst() const - { - mX++; - } - - int MultiplyBy(int x) - { - return mX * x; - } - - int MultiplyByConst(int x) const - { - return mX * x; - } - }; -} - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -typedef eastl::basic_string<char8_t, MallocAllocator> String8MA; -typedef eastl::basic_string<char16_t, MallocAllocator> String16MA; - -template struct eastl::string_hash<String8MA>; -template struct eastl::string_hash<String16MA>; - -template class eastl::hash_set<String8MA, eastl::string_hash<String8MA> >; -template class eastl::hash_set<String16MA, eastl::string_hash<String16MA> >; - - -// Helper function for testing our default hash implementations for pod types which -// simply returns the static_cast<size_t> of the val passed in -template<typename T> -int TestHashHelper(T val) -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::hash<T>()(val) == static_cast<size_t>(val)); - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestFunctional -// -int TestFunctional() -{ - using namespace eastl; - - int nErrorCount = 0; - - { - // str_equal_to - char p0[] = ""; - char p1[] = "hello"; - char p2[] = "world"; - char p3[] = "helllllo"; - char p4[] = "hello"; // Intentionally the same value as p1. - - // str_equal_to - typedef hash_set<const char*, hash<const char*>, str_equal_to<const char*> > StringHashSet; - StringHashSet shs; - - shs.insert(p1); - shs.insert(p2); - shs.insert(p3); - - StringHashSet::iterator it = shs.find(p0); - EATEST_VERIFY(it == shs.end()); - - it = shs.find(p1); - EATEST_VERIFY(it != shs.end()); - - it = shs.find(p2); - EATEST_VERIFY(it != shs.end()); - - it = shs.find(p4); - EATEST_VERIFY(it != shs.end()); - } - - { - // str_less<const char8_t*> - Results<char> results8[] = - { - { "", "", false }, - { "", "a", true }, - { "a", "", false }, - { "a", "a", false }, - { "a", "b", true }, - { "____a", "____a", false }, - { "____a", "____b", true }, - { "____b", "____a", false }, - { "_\xff", "_a", false }, // Test high values, which exercises the signed/unsiged comparison behavior. - { "_a", "_\xff", true } - }; - - str_less<const char*> sl8; - for(size_t i = 0; i < EAArrayCount(results8); i++) - { - // Verify that our test is in line with the strcmp function. - bool bResult = (EA::StdC::Strcmp(results8[i].p1, results8[i].p2) < 0); - EATEST_VERIFY_F(bResult == results8[i].expectedResult, "Strcmp failure, test %zu. Expected \"%s\" to be %sless than \"%s\"", i, results8[i].p1, results8[i].expectedResult ? "" : "not ", results8[i].p2); - - // Verify that str_less achieves the expected results. - bResult = sl8(results8[i].p1, results8[i].p2); - EATEST_VERIFY_F(bResult == results8[i].expectedResult, "str_less test failure, test %zu. Expected \"%s\" to be %sless than \"%s\"", i, results8[i].p1, results8[i].expectedResult ? "" : "not ", results8[i].p2); - } - - // str_less<const wchar_t*> - Results<wchar_t> resultsW[] = - { - { L"", L"", false }, - { L"", L"a", true }, - { L"a", L"", false }, - { L"a", L"a", false }, - { L"a", L"b", true }, - { L"____a", L"____a", false }, - { L"____a", L"____b", true }, - { L"____b", L"____a", false }, - { L"_\xffff", L"_a", false }, // Test high values, which exercises the signed/unsiged comparison behavior. - { L"_a", L"_\xffff", true } - }; - - str_less<const wchar_t*> slW; - for(size_t i = 0; i < EAArrayCount(resultsW); i++) - { - // Verify that our test is in line with the strcmp function. - bool bResult = (EA::StdC::Strcmp(resultsW[i].p1, resultsW[i].p2) < 0); - EATEST_VERIFY_F(bResult == resultsW[i].expectedResult, "Strcmp failure, test %zu. Expected \"%s\" to be %sless than \"%s\"", i, results8[i].p1, results8[i].expectedResult ? "" : "not ", results8[i].p2); - - // Verify that str_less achieves the expected results. - bResult = slW(resultsW[i].p1, resultsW[i].p2); - EATEST_VERIFY_F(bResult == resultsW[i].expectedResult, "str_less test failure, test %zu. Expected \"%ls\" to be %sless than \"%ls\"", i, resultsW[i].p1, resultsW[i].expectedResult ? "" : "not ", resultsW[i].p2); - } - } - - { - // str_less - char p0[] = ""; - char p1[] = "hello"; - char p2[] = "world"; - char p3[] = "helllllo"; - char p4[] = "hello"; // Intentionally the same value as p1. - - typedef set<const char*, str_less<const char*> > StringSet; - StringSet ss; - - ss.insert(p1); - ss.insert(p2); - ss.insert(p3); - - StringSet::iterator it = ss.find(p0); - EATEST_VERIFY(it == ss.end()); - - it = ss.find(p1); - EATEST_VERIFY(it != ss.end()); - - it = ss.find(p2); - EATEST_VERIFY(it != ss.end()); - - it = ss.find(p4); - EATEST_VERIFY(it != ss.end()); - } - - { - // equal_to_2 - N1 n11(1); - N1 n13(3); - N2 n21(1); - N2 n22(2); - const N1 cn11(1); - const N1 cn13(3); - volatile N1 vn11(1); - volatile N1 vn13(3); - const volatile N1 cvn11(1); - const volatile N1 cvn13(3); - - equal_to_2<N1, N2> e; - EATEST_VERIFY(e(n11, n21)); - EATEST_VERIFY(e(n21, n11)); - - equal_to_2<N1, N1> es; - EATEST_VERIFY(es(n11, n11)); - EATEST_VERIFY(!es(n11, n13)); - - equal_to_2<const N1, N1> ec; - EATEST_VERIFY(ec(cn11, n11)); - EATEST_VERIFY(ec(n11, cn11)); - - equal_to_2<N1, const N1> ec2; - EATEST_VERIFY(ec2(n11, cn11)); - EATEST_VERIFY(ec2(cn11, n11)); - - equal_to_2<const N1, const N1> ecc; - EATEST_VERIFY(ecc(cn11, cn11)); - - equal_to_2<volatile N1, N1> ev; - EATEST_VERIFY(ev(vn11, n11)); - EATEST_VERIFY(ev(n11, vn11)); - - equal_to_2<N1, volatile N1> ev2; - EATEST_VERIFY(ev2(n11, vn11)); - EATEST_VERIFY(ev2(vn11, n11)); - - equal_to_2<volatile N1, volatile N1> evv; - EATEST_VERIFY(evv(vn11, vn11)); - - equal_to_2<const volatile N1, N1> ecv; - EATEST_VERIFY(ecv(cvn11, n11)); - EATEST_VERIFY(ecv(n11, cvn11)); - - equal_to_2<N1, const volatile N1> ecv2; - EATEST_VERIFY(ecv2(n11, cvn11)); - EATEST_VERIFY(ecv2(cvn11, n11)); - - equal_to_2<const volatile N1, const volatile N1> ecvcv; - EATEST_VERIFY(ecvcv(cvn11, cvn11)); - - // not_equal_to_2 - not_equal_to_2<N1, N2> n; - EATEST_VERIFY(n(n11, n22)); - EATEST_VERIFY(n(n22, n11)); - - not_equal_to_2<N1, N1> ns; - EATEST_VERIFY(ns(n11, n13)); - EATEST_VERIFY(!ns(n11, n11)); - - not_equal_to_2<const N1, N1> nc; - EATEST_VERIFY(nc(cn11, n13)); - EATEST_VERIFY(nc(n13, cn11)); - - not_equal_to_2<N1, const N1> nc2; - EATEST_VERIFY(nc2(n13, cn11)); - EATEST_VERIFY(nc2(cn11, n13)); - - not_equal_to_2<const N1, const N1> ncc; - EATEST_VERIFY(ncc(cn11, cn13)); - - not_equal_to_2<volatile N1, N1> nv; - EATEST_VERIFY(nv(vn11, n13)); - EATEST_VERIFY(nv(n11, vn13)); - - not_equal_to_2<N1, volatile N1> nv2; - EATEST_VERIFY(nv2(n11, vn13)); - EATEST_VERIFY(nv2(vn11, n13)); - - not_equal_to_2<volatile N1, volatile N1> nvv; - EATEST_VERIFY(nvv(vn11, vn13)); - - not_equal_to_2<const volatile N1, N1> ncv; - EATEST_VERIFY(ncv(cvn11, n13)); - EATEST_VERIFY(ncv(n11, cvn13)); - - not_equal_to_2<N1, const volatile N1> ncv2; - EATEST_VERIFY(ncv2(n11, cvn13)); - EATEST_VERIFY(ncv2(cvn11, n13)); - - not_equal_to_2<const volatile N1, const volatile N1> ncvcv; - EATEST_VERIFY(ncvcv(cvn11, cvn13)); - - // less_2 - less_2<N1, N2> le; - EATEST_VERIFY(le(n11, n22)); - EATEST_VERIFY(le(n22, n13)); - - less_2<N1, N1> les; - EATEST_VERIFY(les(n11, n13)); - - less_2<const N1, N1> lec; - EATEST_VERIFY(lec(cn11, n13)); - EATEST_VERIFY(lec(n11, cn13)); - - less_2<N1, const N1> lec2; - EATEST_VERIFY(lec2(n11, cn13)); - EATEST_VERIFY(lec2(cn11, n13)); - - less_2<const N1, const N1> lecc; - EATEST_VERIFY(lecc(cn11, cn13)); - - less_2<volatile N1, N1> lev; - EATEST_VERIFY(lev(vn11, n13)); - EATEST_VERIFY(lev(n11, vn13)); - - less_2<N1, volatile N1> lev2; - EATEST_VERIFY(lev2(n11, vn13)); - EATEST_VERIFY(lev2(vn11, n13)); - - less_2<volatile N1, volatile N1> levv; - EATEST_VERIFY(levv(vn11, vn13)); - - less_2<const volatile N1, N1> lecv; - EATEST_VERIFY(lecv(cvn11, n13)); - EATEST_VERIFY(lecv(n11, cvn13)); - - less_2<N1, const volatile N1> lecv2; - EATEST_VERIFY(lecv2(n11, cvn13)); - EATEST_VERIFY(lecv2(cvn11, n13)); - - less_2<const volatile N1, const volatile N1> lecvcv; - EATEST_VERIFY(lecvcv(cvn11, cvn13)); - } - - - { - // Test defect report entry #297. - const X x; - foo< const_mem_fun_t<void, X> >(&x); - } - - - { - // mem_fun (no argument version) - TestClass tc0, tc1, tc2; - TestClass* tcArray[3] = { &tc0, &tc1, &tc2 }; - - for_each(tcArray, tcArray + 3, mem_fun(&TestClass::Increment)); - EATEST_VERIFY((tc0.mX == 38) && (tc1.mX == 38) && (tc2.mX == 38)); - - for_each(tcArray, tcArray + 3, mem_fun(&TestClass::IncrementConst)); - EATEST_VERIFY((tc0.mX == 39) && (tc1.mX == 39) && (tc2.mX == 39)); - } - - - { - // mem_fun (one argument version) - TestClass tc0, tc1, tc2; - TestClass* tcArray[3] = { &tc0, &tc1, &tc2 }; - int intArray1[3] = { -1, 0, 2 }; - int intArray2[3] = { -9, -9, -9 }; - - transform(tcArray, tcArray + 3, intArray1, intArray2, mem_fun(&TestClass::MultiplyBy)); - EATEST_VERIFY((intArray2[0] == -37) && (intArray2[1] == 0) && (intArray2[2] == 74)); - - intArray2[0] = intArray2[1] = intArray2[2] = -9; - transform(tcArray, tcArray + 3, intArray1, intArray2, mem_fun(&TestClass::MultiplyByConst)); - EATEST_VERIFY((intArray2[0] == -37) && (intArray2[1] == 0) && (intArray2[2] == 74)); - } - - - { - // mem_fun_ref (no argument version) - TestClass tcArray[3]; - - for_each(tcArray, tcArray + 3, mem_fun_ref(&TestClass::Increment)); - EATEST_VERIFY((tcArray[0].mX == 38) && (tcArray[1].mX == 38) && (tcArray[2].mX == 38)); - - for_each(tcArray, tcArray + 3, mem_fun_ref(&TestClass::IncrementConst)); - EATEST_VERIFY((tcArray[0].mX == 39) && (tcArray[1].mX == 39) && (tcArray[2].mX == 39)); - } - - - { - // mem_fun_ref (one argument version) - TestClass tcArray[3]; - int intArray1[3] = { -1, 0, 2 }; - int intArray2[3] = { -9, -9, -9 }; - - transform(tcArray, tcArray + 3, intArray1, intArray2, mem_fun_ref(&TestClass::MultiplyBy)); - EATEST_VERIFY((intArray2[0] == -37) && (intArray2[1] == 0) && (intArray2[2] == 74)); - - intArray2[0] = intArray2[1] = intArray2[2] = -9; - transform(tcArray, tcArray + 3, intArray1, intArray2, mem_fun_ref(&TestClass::MultiplyByConst)); - EATEST_VERIFY((intArray2[0] == -37) && (intArray2[1] == 0) && (intArray2[2] == 74)); - } - - - { - // Template instantations. - // These tell the compiler to compile all the functions for the given class. - eastl::hash_set<String8MA, eastl::string_hash<String8MA> > hs8; - eastl::hash_set<String16MA, eastl::string_hash<String16MA> > hs16; - - EATEST_VERIFY(hs8.empty()); - EATEST_VERIFY(hs16.empty()); - } - - { - // unary_compose - /* - eastl::vector<double> angles; - eastl::vector<double> sines; - - eastl::transform(angles.begin(), angles.end(), sines.begin(), - eastl::compose1(eastl::negate<double>(), - eastl::compose1(eastl::ptr_fun(sin), - eastl::bind2nd(eastl::multiplies<double>(), 3.14159 / 180.0)))); - */ - - // binary_compose - list<int> L; - - eastl::list<int>::iterator in_range = - eastl::find_if(L.begin(), L.end(), - eastl::compose2(eastl::logical_and<bool>(), - eastl::bind2nd(eastl::greater_equal<int>(), 1), - eastl::bind2nd(eastl::less_equal<int>(), 10))); - EATEST_VERIFY(in_range == L.end()); - } - - { - nErrorCount += TestHashHelper<int>(4330); - nErrorCount += TestHashHelper<bool>(true); - nErrorCount += TestHashHelper<char>('E'); - nErrorCount += TestHashHelper<signed char>('E'); - nErrorCount += TestHashHelper<unsigned char>('E'); - nErrorCount += TestHashHelper<char8_t>('E'); - nErrorCount += TestHashHelper<char16_t>(0xEAEA); - nErrorCount += TestHashHelper<char32_t>(0x00EA4330); - #if !defined(EA_WCHAR_T_NON_NATIVE) - nErrorCount += TestHashHelper<wchar_t>(L'E'); - #endif - nErrorCount += TestHashHelper<signed short>(4330); - nErrorCount += TestHashHelper<unsigned short>(4330u); - nErrorCount += TestHashHelper<signed int>(4330); - nErrorCount += TestHashHelper<unsigned int>(4330u); - nErrorCount += TestHashHelper<signed long>(4330l); - nErrorCount += TestHashHelper<unsigned long>(4330ul); - nErrorCount += TestHashHelper<signed long long>(4330ll); - nErrorCount += TestHashHelper<unsigned long long>(4330ll); - nErrorCount += TestHashHelper<float>(4330.099999f); - nErrorCount += TestHashHelper<double>(4330.055); - nErrorCount += TestHashHelper<long double>(4330.0654l); - - { - enum hash_enum_test { e1, e2, e3 }; - nErrorCount += TestHashHelper<hash_enum_test>(e1); - nErrorCount += TestHashHelper<hash_enum_test>(e2); - nErrorCount += TestHashHelper<hash_enum_test>(e3); - } - } - - -#if defined(EA_COMPILER_CPP11_ENABLED) && EASTL_VARIADIC_TEMPLATES_ENABLED - // On platforms do not support variadic templates the eastl::invoke (eastl::mem_fn is built on eastl::invoke) - // implementation is extremely basic and does not hold up. A significant amount of code would have to be written - // and I don't believe the investment is justified at this point. If you require this functionality on older - // compilers please contact us. - // - - // eastl::invoke - { - struct TestStruct - { - TestStruct(int inValue) : value(inValue) {} - void Add(int addAmount) { value += addAmount; } - int GetValue() { return value; } - int& GetValueReference() { return value; } - void NoThrow(int inValue) EA_NOEXCEPT {} - int value; - }; - - struct TestFunctor - { - void operator()() { called = true; } - bool called = false; - }; - - struct TestFunctorNoThrow - { - void operator()() EA_NOEXCEPT { called = true; } - bool called = false; - }; - - struct TestFunctorArguments - { - void operator()(int i) { value = i; } - int value = 0; - }; - - { - TestStruct a(42); - eastl::invoke(&TestStruct::Add, a, 10); - EATEST_VERIFY(a.value == 52); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::Add), TestStruct, int>::type, void>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(&TestStruct::Add), TestStruct, int>::value, "incorrect value for is_invocable"); - static_assert(eastl::is_nothrow_invocable<decltype(&TestStruct::NoThrow), TestStruct, int>::value, "incorrect value for is_nothrow_invocable"); - static_assert(!eastl::is_nothrow_invocable<decltype(&TestStruct::Add), TestStruct, int>::value, "incorrect value for is_nothrow_invocable"); - } - { - TestStruct a(42); - eastl::invoke(&TestStruct::Add, &a, 10); - EATEST_VERIFY(a.value == 52); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::Add), TestStruct *, int>::type, void>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(&TestStruct::Add), TestStruct *, int>::value, "incorrect value for is_invocable"); - static_assert(eastl::is_nothrow_invocable<decltype(&TestStruct::NoThrow), TestStruct *, int>::value, "incorrect value for is_nothrow_invocable"); - static_assert(!eastl::is_nothrow_invocable<decltype(&TestStruct::Add), TestStruct *, int>::value, "incorrect value for is_nothrow_invocable"); - } - { - TestStruct a(42); - eastl::reference_wrapper<TestStruct> r(a); - eastl::invoke(&TestStruct::Add, r, 10); - EATEST_VERIFY(a.value == 52); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::Add), eastl::reference_wrapper<TestStruct>, int>::type, void>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(&TestStruct::Add), eastl::reference_wrapper<TestStruct>, int>::value, "incorrect value for is_invocable"); - static_assert(eastl::is_nothrow_invocable<decltype(&TestStruct::NoThrow), eastl::reference_wrapper<TestStruct>, int>::value, "incorrect value for is_nothrow_invocable"); - static_assert(!eastl::is_nothrow_invocable<decltype(&TestStruct::Add), eastl::reference_wrapper<TestStruct>, int>::value, "incorrect value for is_nothrow_invocable"); - } - { - TestStruct a(42); - eastl::invoke(&TestStruct::GetValueReference, a) = 43; - EATEST_VERIFY(a.value == 43); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::GetValueReference), TestStruct &>::type, int &>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(&TestStruct::GetValueReference), TestStruct &>::value, "incorrect value for is_invocable"); - } - { - TestStruct a(42); - EATEST_VERIFY(eastl::invoke(&TestStruct::value, a) == 42); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::value), TestStruct &>::type, int &>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(&TestStruct::value), TestStruct &>::value, "incorrect value for is_invocable"); - } - { - TestStruct a(42); - eastl::invoke(&TestStruct::value, a) = 43; - EATEST_VERIFY(a.value == 43); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::value), TestStruct &>::type, int &>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(&TestStruct::value), TestStruct &>::value, "incorrect value for is_invocable"); - } - { - TestStruct a(42); - eastl::invoke(&TestStruct::value, &a) = 43; - EATEST_VERIFY(a.value == 43); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::value), TestStruct *>::type, int &>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(&TestStruct::value), TestStruct *>::value, "incorrect value for is_invocable"); - } - { - TestStruct a(42); - eastl::reference_wrapper<TestStruct> r(a); - eastl::invoke(&TestStruct::value, r) = 43; - EATEST_VERIFY(a.value == 43); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::value), eastl::reference_wrapper<TestStruct>>::type, int &>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(&TestStruct::GetValue), eastl::reference_wrapper<TestStruct>>::value, "incorrect value for is_invocable"); - } - - #ifndef EA_COMPILER_GNUC - { - TestStruct a(42); - EATEST_VERIFY(eastl::invoke(&TestStruct::GetValue, a) == 42); - - static_assert( - eastl::is_same<typename eastl::invoke_result<decltype(&TestStruct::GetValue), TestStruct*>::type, int>::value, - "incorrect type for invoke_result"); - - static_assert(eastl::is_invocable<decltype(&TestStruct::GetValue), TestStruct*>::value, "incorrect value for is_invocable"); - } - #endif - { - TestFunctor f; - eastl::invoke(f); - EATEST_VERIFY(f.called); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(f)>::type, void>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(f)>::value, "incorrect value for is_invocable"); - static_assert(!eastl::is_nothrow_invocable<decltype(f)>::value, "incorrect value for is_nothrow_invocable"); - } - { - TestFunctorNoThrow f; - eastl::invoke(f); - EATEST_VERIFY(f.called); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(f)>::type, void>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(f)>::value, "incorrect value for is_invocable"); - static_assert(eastl::is_nothrow_invocable<decltype(f)>::value, "incorrect value for is_nothrow_invocable"); - } - { - TestFunctorArguments f; - eastl::invoke(f, 42); - EATEST_VERIFY(f.value == 42); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(f), int>::type, void>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(f), int>::value, "incorrect value for is_invocable"); - } - { - struct TestInvokeConstAccess - { - void ConstMemberFunc(int i) const {} - void ConstVolatileMemberFunc(int i) const volatile {} - - int mI; - }; - - static_assert(eastl::is_invocable<decltype(&TestInvokeConstAccess::ConstMemberFunc), const TestInvokeConstAccess*, int>::value, "incorrect value for is_invocable"); - static_assert(eastl::is_invocable<decltype(&TestInvokeConstAccess::ConstVolatileMemberFunc), const volatile TestInvokeConstAccess*, int>::value, "incorrect value for is_invocable"); - } - { - struct TestReferenceWrapperInvoke - { - int NonConstMemberFunc(int i) { return i; } - int ConstMemberFunc(int i) const { return i; } - - int mI = 1; - const int mIC = 1; - }; - - TestReferenceWrapperInvoke testStruct; - int ret; - - ret = eastl::invoke(&TestReferenceWrapperInvoke::NonConstMemberFunc, eastl::ref(testStruct), 1); - EATEST_VERIFY(ret == 1); - - ret = eastl::invoke(&TestReferenceWrapperInvoke::ConstMemberFunc, eastl::ref(testStruct), 1); - EATEST_VERIFY(ret == 1); - - ret = eastl::invoke(&TestReferenceWrapperInvoke::mI, eastl::ref(testStruct)); - EATEST_VERIFY(ret == 1); - - ret = eastl::invoke(&TestReferenceWrapperInvoke::mIC, eastl::ref(testStruct)); - EATEST_VERIFY(ret == 1); - } - { - static bool called = false; - auto f = [] {called = true;}; - eastl::invoke(f); - EATEST_VERIFY(called); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(f)>::type, void>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(f)>::value, "incorrect value for is_invocable"); - } - { - static int value = 0; - auto f = [](int i) {value = i;}; - eastl::invoke(f, 42); - EATEST_VERIFY(value == 42); - - static_assert(eastl::is_same<typename eastl::invoke_result<decltype(f), int>::type, void>::value, "incorrect type for invoke_result"); - static_assert(eastl::is_invocable<decltype(f), int>::value, "incorrect value for is_invocable"); - } - { - struct A {}; - struct B : public A {}; - struct C : public A {}; - - struct TestStruct - { - A a() { return A(); }; - B b() { return B(); }; - C c() EA_NOEXCEPT { return C(); }; - }; - - static_assert(!eastl::is_invocable_r<B, decltype(&TestStruct::a), TestStruct>::value, "incorrect value for is_invocable_r"); - static_assert(eastl::is_invocable_r<A, decltype(&TestStruct::b), TestStruct>::value, "incorrect value for is_invocable_r"); - static_assert(eastl::is_invocable_r<B, decltype(&TestStruct::b), TestStruct>::value, "incorrect value for is_invocable_r"); - static_assert(!eastl::is_nothrow_invocable_r<B, decltype(&TestStruct::b), TestStruct>::value, "incorrect value for is_nothrow_invocable_r"); - static_assert(eastl::is_nothrow_invocable_r<C, decltype(&TestStruct::c), TestStruct>::value, "incorrect value for is_nothrow_invocable_r"); - } - } - - // eastl::mem_fn - { - struct AddingStruct - { - AddingStruct(int inValue) : value(inValue) {} - void Add(int addAmount) { value += addAmount; } - void Add2(int add1, int add2) { value += (add1 + add2); } - int value; - }; - - struct OverloadedStruct - { - OverloadedStruct(int inValue) : value(inValue) {} - int &Value() { return value; } - const int &Value() const { return value; } - int value; - }; - - { - AddingStruct a(42); - eastl::mem_fn(&AddingStruct::Add)(a, 6); - EATEST_VERIFY(a.value == 48); - } - { - AddingStruct a(42); - eastl::mem_fn(&AddingStruct::Add2)(a, 3, 3); - EATEST_VERIFY(a.value == 48); - } - { - AddingStruct a(42); - auto fStructAdd = eastl::mem_fn(&AddingStruct::Add); - fStructAdd(a,6); - EATEST_VERIFY(a.value == 48); - } - { - OverloadedStruct a(42); - EATEST_VERIFY(eastl::mem_fn<int &()>(&OverloadedStruct::Value)(a) == 42); - EATEST_VERIFY(eastl::mem_fn<const int &() const>(&OverloadedStruct::Value)(a) == 42); - } - } -#endif - - // eastl::function - { - { - { - struct Functor { int operator()() { return 42; } }; - eastl::function<int(void)> fn = Functor(); - EATEST_VERIFY(fn() == 42); - } - - { - struct Functor { int operator()(int in) { return in; } }; - eastl::function<int(int)> fn = Functor(); - EATEST_VERIFY(fn(24) == 24); - } - } - - { - int val = 0; - auto lambda = [&val] { ++val; }; - { - eastl::function<void(void)> ff = std::bind(lambda); - ff(); - VERIFY(val == 1); - } - { - eastl::function<void(void)> ff = nullptr; - ff = std::bind(lambda); - ff(); - VERIFY(val == 2); - } - } - - { - int val = 0; - { - eastl::function<int(int*)> ff = &TestIntRet; - int ret = ff(&val); - EATEST_VERIFY(ret == 0); - EATEST_VERIFY(val == 1); - } - { - eastl::function<int(int*)> ff; - ff = &TestIntRet; - int ret = ff(&val); - EATEST_VERIFY(ret == 1); - EATEST_VERIFY(val == 2); - } - } - - { - struct Test { int x = 1; }; - Test t; - const Test ct; - - { - eastl::function<int(const Test&)> ff = &Test::x; - int ret = ff(t); - EATEST_VERIFY(ret == 1); - } - { - eastl::function<int(const Test&)> ff = &Test::x; - int ret = ff(ct); - EATEST_VERIFY(ret == 1); - } - { - eastl::function<int(const Test&)> ff; - ff = &Test::x; - int ret = ff(t); - EATEST_VERIFY(ret == 1); - } - { - eastl::function<int(const Test&)> ff; - ff = &Test::x; - int ret = ff(ct); - EATEST_VERIFY(ret == 1); - } - } - - { - struct TestVoidRet - { - void IncX() const - { - ++x; - } - - void IncX() - { - ++x; - } - - mutable int x = 0; - }; - - TestVoidRet voidRet; - const TestVoidRet cvoidRet; - - { - eastl::function<void(const TestVoidRet&)> ff = static_cast<void(TestVoidRet::*)() const>(&TestVoidRet::IncX); - ff(cvoidRet); - VERIFY(cvoidRet.x == 1); - } - { - eastl::function<void(const TestVoidRet&)> ff = static_cast<void(TestVoidRet::*)() const>(&TestVoidRet::IncX); - ff(voidRet); - VERIFY(voidRet.x == 1); - } - { - eastl::function<void(TestVoidRet&)> ff = static_cast<void(TestVoidRet::*)()>(&TestVoidRet::IncX); - ff(voidRet); - VERIFY(voidRet.x == 2); - } - } - - { - int val = 0; - struct Functor { void operator()(int* p) { *p += 1; } }; - Functor functor; - { - eastl::function<void(int*)> ff = eastl::reference_wrapper<Functor>(functor); - ff(&val); - EATEST_VERIFY(val == 1); - } - - { - eastl::function<void(int*)> ff; - ff = eastl::reference_wrapper<Functor>(functor); - ff(&val); - EATEST_VERIFY(val == 2); - } - } - - { - { - auto lambda = []{}; - EA_UNUSED(lambda); - static_assert(internal::is_functor_inplace_allocatable<decltype(lambda), EASTL_FUNCTION_DEFAULT_CAPTURE_SSO_SIZE>::value == true, "lambda equivalent to function pointer does not fit in eastl::function local memory."); - } - - { - eastl::function<void(void)> fn; - - EATEST_VERIFY(!fn); - fn = [] {}; - EATEST_VERIFY(!!fn); - } - - { - eastl::function<int(int)> fn = [](int param) { return param; }; - EATEST_VERIFY(fn(42) == 42); - } - - { - eastl::function<int(int)> fn = ReturnVal; - EATEST_VERIFY(fn(42) == 42); - } - - { - eastl::function<int()> fn0 = ReturnZero; - eastl::function<int()> fn1 = ReturnOne; - - EATEST_VERIFY(fn0() == 0 && fn1() == 1); - swap(fn0, fn1); - EATEST_VERIFY(fn0() == 1 && fn1() == 0); - } - - { - eastl::function<int()> fn0 = ReturnZero; - eastl::function<int()> fn1 = ReturnOne; - - EATEST_VERIFY(fn0() == 0 && fn1() == 1); - fn0 = fn1; - EATEST_VERIFY(fn0() == 1 && fn1() == 1); - } - - { - eastl::function<int()> fn0 = ReturnZero; - eastl::function<int()> fn1 = ReturnOne; - - EATEST_VERIFY(fn0() == 0 && fn1() == 1); - fn0 = eastl::move(fn1); - EATEST_VERIFY(fn0() == 1 && fn1 == nullptr); - } - - { - eastl::function<int(int)> f1(nullptr); - EATEST_VERIFY(!f1); - - eastl::function<int(int)> f2 = nullptr; - EATEST_VERIFY(!f2); - } - } - - { - // test the default allocator path by using a lambda capture too large to fit into the eastl::function local - // storage. - uint64_t a = 1, b = 2, c = 3, d = 4, e = 5, f = 6; - eastl::function<uint64_t(void)> fn = [=] { return a + b + c + d + e + f; }; - auto result = fn(); - EATEST_VERIFY(result == 21); - } - - { - struct Functor { void operator()() { return; } }; - eastl::function<void(void)> fn; - eastl::function<void(void)> fn2 = nullptr; - EATEST_VERIFY(!fn); - EATEST_VERIFY(!fn2); - EATEST_VERIFY(fn == nullptr); - EATEST_VERIFY(fn2 == nullptr); - EATEST_VERIFY(nullptr == fn); - EATEST_VERIFY(nullptr == fn2); - fn = Functor(); - fn2 = Functor(); - EATEST_VERIFY(!!fn); - EATEST_VERIFY(!!fn2); - EATEST_VERIFY(fn != nullptr); - EATEST_VERIFY(fn2 != nullptr); - EATEST_VERIFY(nullptr != fn); - EATEST_VERIFY(nullptr != fn2); - fn = nullptr; - fn2 = fn; - EATEST_VERIFY(!fn); - EATEST_VERIFY(!fn2); - EATEST_VERIFY(fn == nullptr); - EATEST_VERIFY(fn2 == nullptr); - EATEST_VERIFY(nullptr == fn); - EATEST_VERIFY(nullptr == fn2); - } - - { - using eastl::swap; - struct Functor { int operator()() { return 5; } }; - eastl::function<int(void)> fn = Functor(); - eastl::function<int(void)> fn2; - EATEST_VERIFY(fn() == 5); - EATEST_VERIFY(!fn2); - fn.swap(fn2); - EATEST_VERIFY(!fn); - EATEST_VERIFY(fn2() == 5); - swap(fn, fn2); - EATEST_VERIFY(fn() == 5); - EATEST_VERIFY(!fn2); - } - - { - uint64_t a = 1, b = 2, c = 3, d = 4, e = 5, f = 6; - eastl::function<uint64_t(void)> fn([=] { return a + b + c + d + e + f; }); - - auto result = fn(); - EATEST_VERIFY(result == 21); - } - - // user regression "self assigment" tests - { - eastl::function<int(void)> fn = [cache = 0] () mutable { return cache++; }; - - EATEST_VERIFY(fn() == 0); - EATEST_VERIFY(fn() == 1); - EATEST_VERIFY(fn() == 2); - - EA_DISABLE_CLANG_WARNING(-Wunknown-pragmas) - EA_DISABLE_CLANG_WARNING(-Wunknown-warning-option) - EA_DISABLE_CLANG_WARNING(-Wself-assign-overloaded) - fn = fn; - EA_RESTORE_CLANG_WARNING() - EA_RESTORE_CLANG_WARNING() - EA_RESTORE_CLANG_WARNING() - - EATEST_VERIFY(fn() == 3); - EATEST_VERIFY(fn() == 4); - EATEST_VERIFY(fn() == 5); - - fn = eastl::move(fn); - - EATEST_VERIFY(fn() == 6); - EATEST_VERIFY(fn() == 7); - EATEST_VERIFY(fn() == 8); - } - - // user regression for memory leak when re-assigning an eastl::function which already holds a large closure. - { - static int sCtorCount = 0; - static int sDtorCount = 0; - - { - struct local - { - local() { sCtorCount++; } - local(const local&) { sCtorCount++; } - local(local&&) { sCtorCount++; } - ~local() { sDtorCount++; } - - void operator=(const local&) = delete; // suppress msvc warning - } l; - - eastl::function<bool()> f; - - f = [l]() { return false; }; - - // ensure closure resources are cleaned up when assigning to a non-null eastl::function. - f = [l]() { return true; }; - } - - EATEST_VERIFY(sCtorCount == sDtorCount); - } - } - - // Checking _MSC_EXTENSIONS is required because the Microsoft calling convention classifiers are only available when - // compiler specific C/C++ language extensions are enabled. - #if defined(EA_PLATFORM_MICROSOFT) && defined(_MSC_EXTENSIONS) - { - // no arguments - typedef void(__stdcall * StdCallFunction)(); - typedef void(__cdecl * CDeclFunction)(); - - // only varargs - typedef void(__stdcall * StdCallFunctionWithVarargs)(...); - typedef void(__cdecl * CDeclFunctionWithVarargs)(...); - - // arguments and varargs - typedef void(__stdcall * StdCallFunctionWithVarargsAtEnd)(int, int, int, ...); - typedef void(__cdecl * CDeclFunctionWithVarargsAtEnd)(int, short, long, ...); - - static_assert(!eastl::is_function<StdCallFunction>::value, "is_function failure"); - static_assert(!eastl::is_function<CDeclFunction>::value, "is_function failure"); - static_assert(eastl::is_function<typename eastl::remove_pointer<StdCallFunction>::type>::value, "is_function failure"); - static_assert(eastl::is_function<typename eastl::remove_pointer<CDeclFunction>::type>::value, "is_function failure"); - static_assert(eastl::is_function<typename eastl::remove_pointer<StdCallFunctionWithVarargs>::type>::value, "is_function failure"); - static_assert(eastl::is_function<typename eastl::remove_pointer<CDeclFunctionWithVarargs>::type>::value, "is_function failure"); - static_assert(eastl::is_function<typename eastl::remove_pointer<StdCallFunctionWithVarargsAtEnd>::type>::value, "is_function failure"); - static_assert(eastl::is_function<typename eastl::remove_pointer<CDeclFunctionWithVarargsAtEnd>::type>::value, "is_function failure"); - } - #endif - - // Test Function Objects - #if defined(EA_COMPILER_CPP14_ENABLED) - { - // eastl::plus<void> - { - { - auto result = eastl::plus<>{}(40, 2); - EA_UNUSED(result); - EATEST_VERIFY(result == 42); - } - - { - auto result = eastl::plus<>{}(40.0, 2.0); - EA_UNUSED(result); - EATEST_VERIFY(result == 42.0); - } - - { - auto result = eastl::plus<>{}(eastl::string("4"), "2"); - EA_UNUSED(result); - EATEST_VERIFY(result == "42"); - } - } - - // eastl::minus<void> - { - { - auto result = eastl::minus<>{}(6, 2); - EA_UNUSED(result); - EATEST_VERIFY(result == 4); - } - - { - auto result = eastl::minus<>{}(6.0, 2.0); - EA_UNUSED(result); - EATEST_VERIFY(result == 4.0); - } - } - - // eastl::multiplies - { - { - auto result = eastl::multiplies<>{}(6, 2); - EA_UNUSED(result); - EATEST_VERIFY(result == 12); - } - - { - auto result = eastl::multiplies<>{}(6.0, 2.0); - EA_UNUSED(result); - EATEST_VERIFY(result == 12.0); - } - } - - - // eastl::divides - { - { - auto result = eastl::divides<>{}(6, 2); - EA_UNUSED(result); - EATEST_VERIFY(result == 3); - } - - { - auto result = eastl::divides<>{}(6.0, 2.0); - EA_UNUSED(result); - EATEST_VERIFY(result == 3.0); - } - } - - // eastl::modulus - { - { - auto result = eastl::modulus<>{}(6, 2); - EA_UNUSED(result); - EATEST_VERIFY(result == 0); - } - - { - auto result = eastl::modulus<>{}(7, 2); - EA_UNUSED(result); - EATEST_VERIFY(result == 1); - } - } - - // eastl::negate - { - { - auto result = eastl::negate<>{}(42); - EA_UNUSED(result); - EATEST_VERIFY(result == -42); - } - - { - auto result = eastl::negate<>{}(42.0); - EA_UNUSED(result); - EATEST_VERIFY(result == -42.0); - } - } - - // eastl::equal_to - { - { - auto result = eastl::equal_to<>{}(40, 2); - EA_UNUSED(result); - EATEST_VERIFY(!result); - } - - { - auto result = eastl::equal_to<>{}(40, 40); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - } - - // eastl::not_equal_to - { - { - auto result = eastl::not_equal_to<>{}(40, 2); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - - { - auto result = eastl::not_equal_to<>{}(40, 40); - EA_UNUSED(result); - EATEST_VERIFY(!result); - } - } - - // eastl::greater<void> - { - { - auto result = eastl::greater<>{}(40, 2); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - - { - auto result = eastl::greater<>{}(1, 2); - EA_UNUSED(result); - EATEST_VERIFY(!result); - } - - { - auto result = eastl::greater<>{}(eastl::string("4"), "2"); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - } - - // eastl::less<void> - { - { - auto result = eastl::less<>{}(40, 2); - EA_UNUSED(result); - EATEST_VERIFY(!result); - } - - { - auto result = eastl::less<>{}(1, 2); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - - { - auto result = eastl::less<>{}(eastl::string("4"), "2"); - EA_UNUSED(result); - EATEST_VERIFY(!result); - } - } - - // eastl::greater_equal<void> - { - { - auto result = eastl::greater_equal<>{}(40, 2); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - - { - auto result = eastl::greater_equal<>{}(40, 40); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - - { - auto result = eastl::greater_equal<>{}(40, 43); - EA_UNUSED(result); - EATEST_VERIFY(!result); - } - } - - // eastl::less_equal<void> - { - { - auto result = eastl::less_equal<>{}(40, 2); - EA_UNUSED(result); - EATEST_VERIFY(!result); - } - - { - auto result = eastl::less_equal<>{}(40, 40); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - - { - auto result = eastl::less_equal<>{}(40, 43); - EA_UNUSED(result); - EATEST_VERIFY(result); - } - } - - // eastl::logical_and - { - auto result = eastl::logical_and<>{}(true, true); - EATEST_VERIFY(result); - result = eastl::logical_and<>{}(true, false); - EATEST_VERIFY(!result); - result = eastl::logical_and<>{}(false, true); - EATEST_VERIFY(!result); - result = eastl::logical_and<>{}(false, false); - EATEST_VERIFY(!result); - - bool b = false; - result = eastl::logical_and<>{}(b, false); - EATEST_VERIFY(!result); - } - - // eastl::logical_or - { - auto result = eastl::logical_or<>{}(true, true); - EATEST_VERIFY(result); - result = eastl::logical_or<>{}(true, false); - EATEST_VERIFY(result); - result = eastl::logical_or<>{}(false, true); - EATEST_VERIFY(result); - result = eastl::logical_or<>{}(false, false); - EATEST_VERIFY(!result); - - bool b = false; - result = eastl::logical_or<>{}(b, false); - EATEST_VERIFY(!result); - result = eastl::logical_or<>{}(b, true); - EATEST_VERIFY(result); - } - - // eastl::logical_not - { - auto result = eastl::logical_not<>{}(true); - EATEST_VERIFY(!result); - result = eastl::logical_not<>{}(result); - EATEST_VERIFY(result); - result = eastl::logical_not<>{}(false); - EATEST_VERIFY(result); - } - } - #endif - - // not_fn - { - { - auto ft = eastl::not_fn([] { return true; }); - auto ff = eastl::not_fn([] { return false; }); - - EATEST_VERIFY(ft() == false); - EATEST_VERIFY(ff() == true); - } - } - - // reference_wrapper - { - // operator T& - { - int i = 0; - eastl::reference_wrapper<int> r(i); - int &j = r; - j = 42; - - EATEST_VERIFY(i == 42); - } - - // get - { - int i = 0; - eastl::reference_wrapper<int> r(i); - r.get() = 42; - - EATEST_VERIFY(i == 42); - } - - // copy constructor - { - int i = 0; - eastl::reference_wrapper<int> r(i); - eastl::reference_wrapper<int> copy(r); - copy.get() = 42; - - EATEST_VERIFY(i == 42); - } - - // assignment - { - int i = 0; - int j = 0; - - eastl::reference_wrapper<int> r1(i); - eastl::reference_wrapper<int> r2(j); - - r2 = r1; // rebind r2 to refer to i - r2.get() = 42; - - EATEST_VERIFY(i == 42); - EATEST_VERIFY(j == 0); - } - - // invoke - { - struct Functor - { - bool called = false; - void operator()() {called = true;} - }; - - Functor f; - eastl::reference_wrapper<Functor> r(f); - r(); - - EATEST_VERIFY(f.called == true); - } - - // ref/cref - { - { - int i = 0; - eastl::reference_wrapper<int> r1 = eastl::ref(i); - r1.get() = 42; - - eastl::reference_wrapper<int> r2 = eastl::ref(r1); - - EATEST_VERIFY(i == 42); - EATEST_VERIFY(r2 == 42); - } - - { - int i = 1337; - eastl::reference_wrapper<const int> r1 = eastl::cref(i); - EATEST_VERIFY(r1 == 1337); - - eastl::reference_wrapper<const int> r2 = eastl::cref(r1); - EATEST_VERIFY(r2 == 1337); - } - } - } - - return nErrorCount; -} - -// Test that we can instantiate invoke_result with incorrect argument types. -// This should be instantiable, but should not have a `type` typedef. -struct TestInvokeResult -{ - int f(int i) {return i;} -}; - -template struct eastl::invoke_result<decltype(&TestInvokeResult::f), TestInvokeResult, void>; - -static_assert(!eastl::is_invocable<decltype(&TestInvokeResult::f), TestInvokeResult, void>::value, "incorrect value for is_invocable"); -static_assert(!eastl::is_invocable<decltype(&TestInvokeResult::f), TestInvokeResult, int, int>::value, "incorrect value for is_invocable"); -static_assert(eastl::is_invocable<decltype(&TestInvokeResult::f), TestInvokeResult, int>::value, "incorrect value for is_invocable"); - -static_assert(!eastl::is_invocable_r<int, decltype(&TestInvokeResult::f), TestInvokeResult, void>::value, "incorrect value for is_invocable_r"); -static_assert(!eastl::is_invocable_r<void, decltype(&TestInvokeResult::f), TestInvokeResult, int, int>::value, "incorrect value for is_invocable_r"); -static_assert(eastl::is_invocable_r<void, decltype(&TestInvokeResult::f), TestInvokeResult, int>::value, "incorrect value for is_invocable_r"); -static_assert(eastl::is_invocable_r<int, decltype(&TestInvokeResult::f), TestInvokeResult, int>::value, "incorrect value for is_invocable_r"); - -struct TestCallableInvokeResult -{ - int operator()(int i) {return i;} -}; - -template struct eastl::invoke_result<TestCallableInvokeResult, void>; - -static_assert(!eastl::is_invocable<TestCallableInvokeResult, void>::value, "incorrect value for is_invocable"); -static_assert(!eastl::is_invocable<TestCallableInvokeResult, int, int>::value, "incorrect value for is_invocable"); -static_assert(eastl::is_invocable<TestCallableInvokeResult, int>::value, "incorrect value for is_invocable"); - -static_assert(!eastl::is_invocable_r<int, TestCallableInvokeResult, void>::value, "incorrect value for is_invocable_r"); -static_assert(!eastl::is_invocable_r<void, TestCallableInvokeResult, int, int>::value, "incorrect value for is_invocable_r"); -static_assert(eastl::is_invocable_r<void, TestCallableInvokeResult, int>::value, "incorrect value for is_invocable_r"); -static_assert(eastl::is_invocable_r<int, TestCallableInvokeResult, int>::value, "incorrect value for is_invocable_r"); - -typedef decltype(eastl::ref(eastl::declval<TestCallableInvokeResult&>())) TestCallableRefInvokeResult; - -static_assert(!eastl::is_invocable<TestCallableRefInvokeResult, void>::value, "incorrect value for is_invocable"); -static_assert(!eastl::is_invocable<TestCallableRefInvokeResult, int, int>::value, "incorrect value for is_invocable"); -static_assert(eastl::is_invocable<TestCallableRefInvokeResult, int>::value, "incorrect value for is_invocable"); - -static_assert(!eastl::is_invocable_r<int, TestCallableRefInvokeResult, void>::value, "incorrect value for is_invocable_r"); -static_assert(!eastl::is_invocable_r<void, TestCallableRefInvokeResult, int, int>::value, "incorrect value for is_invocable_r"); -static_assert(eastl::is_invocable_r<void, TestCallableRefInvokeResult, int>::value, "incorrect value for is_invocable_r"); -static_assert(eastl::is_invocable_r<int, TestCallableRefInvokeResult, int>::value, "incorrect value for is_invocable_r"); diff --git a/test/source/TestHash.cpp b/test/source/TestHash.cpp deleted file mode 100644 index 1bcf996..0000000 --- a/test/source/TestHash.cpp +++ /dev/null @@ -1,1505 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include "TestMap.h" -#include "TestSet.h" -#include <EASTL/hash_set.h> -#include <EASTL/hash_map.h> -#include <EASTL/unordered_set.h> -#include <EASTL/unordered_map.h> -#include <EASTL/map.h> -#include <EASTL/string.h> -#include <EASTL/algorithm.h> -#include <EASTL/vector.h> -#include <EASTL/unique_ptr.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#include <string.h> -EA_RESTORE_ALL_VC_WARNINGS() - - -using namespace eastl; - -namespace eastl -{ - template <> - struct hash<Align32> - { - size_t operator()(const Align32& a32) const - { return static_cast<size_t>(a32.mX); } - }; - - // extension to hash an eastl::pair - template <typename T1, typename T2> - struct hash<pair<T1, T2>> - { - size_t operator()(const pair<T1, T2>& c) const - { - return static_cast<size_t>(hash<T1>()(c.first) ^ hash<T2>()(c.second)); - } - }; -} - -// For regression code below. -class HashRegressionA { public: int x; }; -class HashRegressionB { public: int y; }; - - -// For regression code below. -struct Struct { - char8_t name[128]; -}; - - -// For regression code below. -template<class HashType> -struct HashTest -{ - template<typename... Args> - auto operator()(Args&&... args) - { - return eastl::hash<HashType>{}(eastl::forward<Args>(args)...); - } -}; - - - -// What we are doing here is creating a special case of a hashtable where the key compare -// function is not the same as the value operator==. 99% of the time when you create a -// hashtable the key compare (predicate) is simply key_equal or something else that's -// identical to operator== for the hashtable value type. But for some tests we want -// to exercise the case that these aren't different. A result of this difference is that -// you can lookup an element in a hash table and the returned value is not == to the -// value you looked up, because it succeeds the key compare but not operator==. -struct HashtableValue -{ - HashtableValue(eastl_size_t d = 0, eastl_size_t e = 0) : mData(d), mExtra(e){} - void Set(eastl_size_t d, eastl_size_t e = 0) { mData = d; mExtra = e; } - - eastl_size_t mData; - eastl_size_t mExtra; -}; - -bool operator==(const HashtableValue& htv1, const HashtableValue& htv2) -{ - return (htv1.mData == htv2.mData) && (htv1.mExtra == htv2.mExtra); // Fully compare the HashTableValue. -} - -struct HashtableValuePredicate -{ - bool operator()(const HashtableValue& htv1, const HashtableValue& htv2) const - { return (htv1.mData == htv2.mData); } // Compare just the mData portion of HashTableValue. -}; - -struct HashtableValueHash -{ - size_t operator()(const HashtableValue& htv) const - { return static_cast<size_t>(htv.mData); } -}; - - - - -// Explicit Template instantiations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::hashtable<int, - eastl::pair<const int, int>, - eastl::allocator, - eastl::use_first<eastl::pair<const int, int>>, - eastl::equal_to<int>, - eastl::hash<int>, - mod_range_hashing, - default_ranged_hash, - prime_rehash_policy, - true, // bCacheHashCode - true, // bMutableIterators - true // bUniqueKeys - >; -template class eastl::hashtable<int, - eastl::pair<const int, int>, - eastl::allocator, - eastl::use_first<eastl::pair<const int, int>>, - eastl::equal_to<int>, - eastl::hash<int>, - mod_range_hashing, - default_ranged_hash, - prime_rehash_policy, - false, // bCacheHashCode - true, // bMutableIterators - true // bUniqueKeys - >; -// TODO(rparolin): known compiler error, we should fix this. -// template class eastl::hashtable<int, -// eastl::pair<const int, int>, -// eastl::allocator, -// eastl::use_first<eastl::pair<const int, int>>, -// eastl::equal_to<int>, -// eastl::hash<int>, -// mod_range_hashing, -// default_ranged_hash, -// prime_rehash_policy, -// false, // bCacheHashCode -// true, // bMutableIterators -// false // bUniqueKeys -// >; - -// Note these will only compile non-inherited functions. We provide explicit -// template instantiations for the hashtable base class above to get compiler -// coverage of those inherited hashtable functions. -template class eastl::hash_set<int>; -template class eastl::hash_multiset<int>; -template class eastl::hash_map<int, int>; -template class eastl::hash_multimap<int, int>; -template class eastl::hash_set<Align32>; -template class eastl::hash_multiset<Align32>; -template class eastl::hash_map<Align32, Align32>; -template class eastl::hash_multimap<Align32, Align32>; - -// validate static assumptions about hashtable core types -typedef eastl::hash_node<int, false> HashNode1; -typedef eastl::hash_node<int, true> HashNode2; -static_assert(eastl::is_default_constructible<HashNode1>::value, "hash_node static error"); -static_assert(eastl::is_default_constructible<HashNode2>::value, "hash_node static error"); -static_assert(eastl::is_copy_constructible<HashNode1>::value, "hash_node static error"); -static_assert(eastl::is_copy_constructible<HashNode2>::value, "hash_node static error"); -static_assert(eastl::is_move_constructible<HashNode1>::value, "hash_node static error"); -static_assert(eastl::is_move_constructible<HashNode2>::value, "hash_node static error"); - -// A custom hash function that has a high number of collisions is used to ensure many keys share the same hash value. -struct colliding_hash -{ - size_t operator()(const int& val) const - { return static_cast<size_t>(val % 3); } -}; - - - -int TestHash() -{ - int nErrorCount = 0; - - { // Test declarations - hash_set<int> hashSet; - hash_multiset<int> hashMultiSet; - hash_map<int, int> hashMap; - hash_multimap<int, int> hashMultiMap; - - hash_set<int> hashSet2(hashSet); - EATEST_VERIFY(hashSet2.size() == hashSet.size()); - EATEST_VERIFY(hashSet2 == hashSet); - - hash_multiset<int> hashMultiSet2(hashMultiSet); - EATEST_VERIFY(hashMultiSet2.size() == hashMultiSet.size()); - EATEST_VERIFY(hashMultiSet2 == hashMultiSet); - - hash_map<int, int> hashMap2(hashMap); - EATEST_VERIFY(hashMap2.size() == hashMap.size()); - EATEST_VERIFY(hashMap2 == hashMap); - - hash_multimap<int, int> hashMultiMap2(hashMultiMap); - EATEST_VERIFY(hashMultiMap2.size() == hashMultiMap.size()); - EATEST_VERIFY(hashMultiMap2 == hashMultiMap); - - - // allocator_type& get_allocator(); - // void set_allocator(const allocator_type& allocator); - hash_set<int>::allocator_type& allocator = hashSet.get_allocator(); - hashSet.set_allocator(EASTLAllocatorType()); - hashSet.set_allocator(allocator); - // To do: Try to find something better to test here. - - - // const key_equal& key_eq() const; - // key_equal& key_eq(); - hash_set<int> hs; - const hash_set<int> hsc; - - const hash_set<int>::key_equal& ke = hsc.key_eq(); - hs.key_eq() = ke; - - - // const char* get_name() const; - // void set_name(const char* pName); - #if EASTL_NAME_ENABLED - hashMap.get_allocator().set_name("test"); - const char* pName = hashMap.get_allocator().get_name(); - EATEST_VERIFY(equal(pName, pName + 5, "test")); - #endif - } - - - { - hash_set<int> hashSet; - - // Clear a newly constructed, already empty container. - hashSet.clear(true); - EATEST_VERIFY(hashSet.validate()); - EATEST_VERIFY(hashSet.size() == 0); - EATEST_VERIFY(hashSet.bucket_count() == 1); - - for(int i = 0; i < 100; ++i) - hashSet.insert(i); - EATEST_VERIFY(hashSet.validate()); - EATEST_VERIFY(hashSet.size() == 100); - - hashSet.clear(true); - EATEST_VERIFY(hashSet.validate()); - EATEST_VERIFY(hashSet.size() == 0); - EATEST_VERIFY(hashSet.bucket_count() == 1); - - for(int i = 0; i < 100; ++i) - hashSet.insert(i); - EATEST_VERIFY(hashSet.validate()); - EATEST_VERIFY(hashSet.size() == 100); - - hashSet.clear(true); - EATEST_VERIFY(hashSet.validate()); - EATEST_VERIFY(hashSet.size() == 0); - EATEST_VERIFY(hashSet.bucket_count() == 1); - } - - - { // Test hash_set - - // size_type size() const - // bool empty() const - // insert_return_type insert(const value_type& value); - // insert_return_type insert(const value_type& value, hash_code_t c, node_type* pNodeNew = NULL); - // iterator insert(const_iterator, const value_type& value); - // iterator find(const key_type& k); - // const_iterator find(const key_type& k) const; - // size_type count(const key_type& k) const; - - typedef hash_set<int> HashSetInt; - - HashSetInt hashSet; - const HashSetInt::size_type kCount = 10000; - - EATEST_VERIFY(hashSet.empty()); - EATEST_VERIFY(hashSet.size() == 0); - EATEST_VERIFY(hashSet.count(0) == 0); - - for(int i = 0; i < (int)kCount; i++) - hashSet.insert(i); - - EATEST_VERIFY(!hashSet.empty()); - EATEST_VERIFY(hashSet.size() == kCount); - EATEST_VERIFY(hashSet.count(0) == 1); - - for(HashSetInt::iterator it = hashSet.begin(); it != hashSet.end(); ++it) - { - int value = *it; - EATEST_VERIFY(value < (int)kCount); - } - - for(int i = 0; i < (int)kCount * 2; i++) - { - HashSetInt::iterator it = hashSet.find(i); - - if(i < (int)kCount) - EATEST_VERIFY(it != hashSet.end()); - else - EATEST_VERIFY(it == hashSet.end()); - } - - // insert_return_type insert(const value_type& value, hash_code_t c, node_type* pNodeNew = NULL); - HashSetInt::node_type* pNode = hashSet.allocate_uninitialized_node(); - HashSetInt::insert_return_type r = hashSet.insert(eastl::hash<int>()(999999), pNode, 999999); - EATEST_VERIFY(r.second == true); - pNode = hashSet.allocate_uninitialized_node(); - r = hashSet.insert(eastl::hash<int>()(999999), pNode, 999999); - EATEST_VERIFY(r.second == false); - hashSet.free_uninitialized_node(pNode); - hashSet.erase(999999); - - - // iterator begin(); - // const_iterator begin() const; - // iterator end(); - // const_iterator end() const; - - int* const pIntArray = new int[kCount]; - memset(pIntArray, 0, kCount * sizeof(int)); // We want to make sure each element is present only once. - int nCount = 0; - - for(HashSetInt::iterator it = hashSet.begin(); it != hashSet.end(); ++it, ++nCount) - { - int i = *it; - - EATEST_VERIFY((i >= 0) && (i < (int)kCount) && (pIntArray[i] == 0)); - pIntArray[i] = 1; - } - - EATEST_VERIFY(nCount == (int)kCount); - delete[] pIntArray; - } - - - { - // size_type bucket_count() const - // size_type bucket_size(size_type n) const - // float load_factor() const - // float get_max_load_factor() const; - // void set_max_load_factor(float fMaxLoadFactor); - // void rehash(size_type n); - // const RehashPolicy& rehash_policy() const - // void rehash_policy(const RehashPolicy& rehashPolicy); - - typedef hash_set<int> HashSetInt; - - HashSetInt hashSet; - - float fLoadFactor = hashSet.load_factor(); - EATEST_VERIFY(fLoadFactor == 0.f); - - hashSet.set_max_load_factor(65536.f * 512.f); - float fMaxLoadFactor = hashSet.get_max_load_factor(); - EATEST_VERIFY(fMaxLoadFactor == (65536.f * 512.f)); - - hashSet.rehash(20); - HashSetInt::size_type n = hashSet.bucket_count(); - EATEST_VERIFY((n >= 20) && (n < 25)); - - for(int i = 0; i < 100000; i++) - hashSet.insert(i); // This also tests for high loading. - - HashSetInt::size_type n2 = hashSet.bucket_count(); - EATEST_VERIFY(n2 == n); // Verify no rehashing has occured, due to our high load factor. - - n = hashSet.bucket_size(0); - EATEST_VERIFY(n >= ((hashSet.size() / hashSet.bucket_count()) / 2)); // It will be some high value. We divide by 2 to give it some slop. - EATEST_VERIFY(hashSet.validate()); - - hash_set<int>::rehash_policy_type rp = hashSet.rehash_policy(); - rp.mfGrowthFactor = 1.5f; - hashSet.rehash_policy(rp); - EATEST_VERIFY(hashSet.validate()); - - - // local_iterator begin(size_type n); - // local_iterator end(size_type n); - // const_local_iterator begin(size_type n) const; - // const_local_iterator end(size_type n) const; - - HashSetInt::size_type b = hashSet.bucket_count() - 1; - hash<int> IntHash; - for(HashSetInt::const_local_iterator cli = hashSet.begin(b); cli != hashSet.end(b); ++cli) - { - int v = *cli; - EATEST_VERIFY((IntHash(v) % hashSet.bucket_count()) == b); - } - - - // clear(); - - hashSet.clear(); - EATEST_VERIFY(hashSet.validate()); - EATEST_VERIFY(hashSet.empty()); - EATEST_VERIFY(hashSet.size() == 0); - EATEST_VERIFY(hashSet.count(0) == 0); - - hashSet.clear(true); - EATEST_VERIFY(hashSet.validate()); - EATEST_VERIFY(hashSet.bucket_count() == 1); - } - - - { - // void reserve(size_type nElementCount); - nErrorCount += HashContainerReserveTest<hash_set<int>>()(); - nErrorCount += HashContainerReserveTest<hash_multiset<int>>()(); - nErrorCount += HashContainerReserveTest<hash_map<int, int>>()(); - nErrorCount += HashContainerReserveTest<hash_multimap<int, int>>()(); - } - - - { // Test hash_set with cached hash code. - - // insert_return_type insert(const value_type& value) ; - // iterator find(const key_type& k); - // const_iterator find(const key_type& k) const; - - typedef hash_set<int, hash<int>, equal_to<int>, EASTLAllocatorType, true> HashSetIntC; - - HashSetIntC hashSet; - const int kCount = 10000; - - for(int i = 0; i < kCount; i++) - hashSet.insert(i); - - for(HashSetIntC::iterator it = hashSet.begin(); it != hashSet.end(); ++it) - { - int value = *it; - EATEST_VERIFY(value < kCount); - } - - for(int i = 0; i < kCount * 2; i++) - { - HashSetIntC::iterator it = hashSet.find(i); - if(i < kCount) - EATEST_VERIFY(it != hashSet.end()); - else - EATEST_VERIFY(it == hashSet.end()); - } - } - - { - // ENABLE_IF_HASHCODE_U32(HashCodeT, iterator) find_by_hash(HashCodeT c) - // ENABLE_IF_HASHCODE_U32(HashCodeT, const_iterator) find_by_hash(HashCodeT c) const - { - // NOTE(rparolin): - // these overloads of find_by_hash contains a static assert that forces a compiler error in the event it is - // used with a hashtable configured to not cache the hash value in the node. - } - - // iterator find_by_hash(const key_type& k, hash_code_t c) - // const_iterator find_by_hash(const key_type& k, hash_code_t c) const - #ifdef EA_COMPILER_CPP14_ENABLED - { - auto FindByHashTest = [&nErrorCount](auto& hashSet) - { - const int kCount = 10000; - for(int i = 0; i < kCount; i++) - hashSet.insert(i); - - for(int i = 0; i < kCount * 2; i++) - { - auto it = hashSet.find_by_hash(i, i); - - if(i < kCount) - EATEST_VERIFY(it != hashSet.end()); - else - EATEST_VERIFY(it == hashSet.end()); - } - }; - - { - typedef hash_set<int, hash<int>, equal_to<int>, EASTLAllocatorType, true> HashSetIntC; - HashSetIntC hashSetC; - FindByHashTest(hashSetC); - - typedef hash_set<int, hash<int>, equal_to<int>, EASTLAllocatorType, false> HashSetInt; - HashSetInt hashSet; - FindByHashTest(hashSet); - } - } - #endif - } - - - { - // hash_set(const allocator_type& allocator); - // hashtable& operator=(const this_type& x); - // bool validate() const; - - hash_set<int> hashSet1(EASTLAllocatorType("hash_set name")); - hash_set<int> hashSet2(hashSet1); - - for(int i = 0; i < 10; i++) - { - hashSet1.insert(i); - hashSet2.insert(i); - } - - hashSet1 = hashSet2; - - EATEST_VERIFY(hashSet1.validate()); - EATEST_VERIFY(hashSet2.validate()); - } - - - { - // hash_set(size_type nBucketCount, const Hash& hashFunction = Hash(), const Predicate& predicate = Predicate(), const allocator_type& allocator); - // hashtable(const hashtable& x); - // hashtable& operator=(const this_type& x); - // void swap(this_type& x); - // bool validate() const; - { - hash_set<int> hashSet3(0); - hash_set<int> hashSet4(1); - hash_set<int> hashSet5(2); - hash_set<int> hashSet6(3); - hash_set<int> hashSet7(4); - - hashSet4 = hashSet3; - hashSet6 = hashSet5; - hashSet3 = hashSet7; - - for(int i = 0; i < 10; i++) - { - hashSet3.insert(i); - hashSet4.insert(i); - hashSet5.insert(i); - hashSet6.insert(i); - hashSet7.insert(i); - } - - hashSet4 = hashSet3; - hashSet6 = hashSet5; - hashSet3 = hashSet7; - - EATEST_VERIFY(hashSet3.validate()); - EATEST_VERIFY(hashSet4.validate()); - EATEST_VERIFY(hashSet5.validate()); - EATEST_VERIFY(hashSet6.validate()); - EATEST_VERIFY(hashSet7.validate()); - - swap(hashSet4, hashSet3); - swap(hashSet6, hashSet5); - swap(hashSet3, hashSet7); - - EATEST_VERIFY(hashSet3.validate()); - EATEST_VERIFY(hashSet4.validate()); - EATEST_VERIFY(hashSet5.validate()); - EATEST_VERIFY(hashSet6.validate()); - EATEST_VERIFY(hashSet7.validate()); - - hash_set<int> hashSet8(hashSet6); - hash_set<int> hashSet9(hashSet7); - hash_set<int> hashSet10(hashSet8); - - EATEST_VERIFY(hashSet8.validate()); - EATEST_VERIFY(hashSet9.validate()); - EATEST_VERIFY(hashSet10.validate()); - } - - // test hashtable::swap using different allocator instances - { - typedef hash_set<int, eastl::hash<int>, eastl::equal_to<int>, InstanceAllocator> HS; - HS hashSet1(InstanceAllocator("hash_set1 name", 111)); - HS hashSet2(InstanceAllocator("hash_set2 name", 222)); - - for(int i = 0; i < 10; i++) - { - hashSet1.insert(i); - hashSet2.insert(i+10); - } - - hashSet2.swap(hashSet1); - - EATEST_VERIFY(hashSet1.validate()); - EATEST_VERIFY(hashSet2.validate()); - - EATEST_VERIFY(hashSet1.get_allocator().mInstanceId == 222); - EATEST_VERIFY(hashSet2.get_allocator().mInstanceId == 111); - - EATEST_VERIFY(eastl::all_of(eastl::begin(hashSet2), eastl::end(hashSet2), [](int i) { return i < 10; })); - EATEST_VERIFY(eastl::all_of(eastl::begin(hashSet1), eastl::end(hashSet1), [](int i) { return i >= 10; })); - } - } - - - { - // hash_set(InputIterator first, InputIterator last, size_type nBucketCount = 8, const Hash& hashFunction = Hash(), const Predicate& predicate = Predicate(), const allocator_type& allocator); - // bool validate() const; - - vector<int> intArray; - for(int i = 0; i < 1000; i++) - intArray.push_back(i); - - hash_set<int> hashSet1(intArray.begin(), intArray.end(), 0); - hash_set<int> hashSet2(intArray.begin(), intArray.end(), 1); - hash_set<int> hashSet3(intArray.begin(), intArray.end(), 2); - hash_set<int> hashSet4(intArray.begin(), intArray.end(), 3); - - EATEST_VERIFY(hashSet1.validate()); - EATEST_VERIFY(hashSet2.validate()); - EATEST_VERIFY(hashSet3.validate()); - EATEST_VERIFY(hashSet4.validate()); - - - // bool validate_iterator(const_iterator i) const; - hash_set<int>::iterator it; - int result = hashSet1.validate_iterator(it); - EATEST_VERIFY(result == isf_none); - - it = hashSet1.begin(); - result = hashSet2.validate_iterator(it); - EATEST_VERIFY(result == isf_none); - result = hashSet1.validate_iterator(it); - EATEST_VERIFY(result == (isf_valid | isf_current | isf_can_dereference)); - - it = hashSet1.end(); - result = hashSet1.validate_iterator(it); - EATEST_VERIFY(result == (isf_valid | isf_current)); - - - // void reset_lose_memory(); - hashSet1.reset_lose_memory(); - hashSet1 = hashSet2; - - EATEST_VERIFY(hashSet1.validate()); - EATEST_VERIFY(hashSet2.validate()); - - hashSet3.reset_lose_memory(); - hashSet4 = hashSet3; - - EATEST_VERIFY(hashSet3.validate()); - EATEST_VERIFY(hashSet4.validate()); - - hashSet2.reset_lose_memory(); - hashSet3.reset_lose_memory(); - swap(hashSet2, hashSet3); - - EATEST_VERIFY(hashSet3.validate()); - EATEST_VERIFY(hashSet4.validate()); - - hashSet2 = hashSet3; - EATEST_VERIFY(hashSet2.validate()); - } - - - { - // void insert(InputIterator first, InputIterator last); - vector<int> intArray1; - vector<int> intArray2; - - for(int i = 0; i < 1000; i++) - { - intArray1.push_back(i + 0); - intArray2.push_back(i + 500); - } - - hash_set<int> hashSet1(intArray1.begin(), intArray1.end()); - hashSet1.insert(intArray2.begin(), intArray2.end()); - EATEST_VERIFY(hashSet1.validate()); - - hash_set<int> hashSet2; - hashSet2.insert(intArray1.begin(), intArray1.end()); - hashSet2.insert(intArray2.begin(), intArray2.end()); - EATEST_VERIFY(hashSet2.validate()); - - EATEST_VERIFY(hashSet1 == hashSet2); - - - // insert_return_type insert(const_iterator, const value_type& value) - for(int j = 0; j < 1000; j++) - hashSet1.insert(hashSet1.begin(), j); - - insert_iterator< hash_set<int> > ii(hashSet1, hashSet1.begin()); - for(int j = 0; j < 1000; j++) - *ii++ = j; - } - - - { - // C++11 emplace and related functionality - nErrorCount += TestMapCpp11<eastl::hash_map<int, TestObject>>(); - nErrorCount += TestMapCpp11<eastl::unordered_map<int, TestObject>>(); - - nErrorCount += TestSetCpp11<eastl::hash_set<TestObject>>(); - nErrorCount += TestSetCpp11<eastl::unordered_set<TestObject>>(); - - nErrorCount += TestMultimapCpp11<eastl::hash_multimap<int, TestObject>>(); - nErrorCount += TestMultimapCpp11<eastl::unordered_multimap<int, TestObject>>(); - - nErrorCount += TestMultisetCpp11<eastl::hash_multiset<TestObject>>(); - nErrorCount += TestMultisetCpp11<eastl::unordered_multiset<TestObject>>(); - - nErrorCount += TestMapCpp11NonCopyable<eastl::hash_map<int, NonCopyable>>(); - nErrorCount += TestMapCpp11NonCopyable<eastl::unordered_map<int, NonCopyable>>(); - } - - { - // C++17 try_emplace and related functionality - nErrorCount += TestMapCpp17<eastl::hash_map<int, TestObject>>(); - nErrorCount += TestMapCpp17<eastl::unordered_map<int, TestObject>>(); - } - - - { - // initializer_list support. - // hash_set(std::initializer_list<value_type> ilist, size_type nBucketCount = 0, const Hash& hashFunction = Hash(), - // const Predicate& predicate = Predicate(), const allocator_type& allocator = EASTL_HASH_SET_DEFAULT_ALLOCATOR) - // this_type& operator=(std::initializer_list<value_type> ilist); - // void insert(std::initializer_list<value_type> ilist); - hash_set<int> intHashSet = { 12, 13, 14 }; - EATEST_VERIFY(intHashSet.size() == 3); - EATEST_VERIFY(intHashSet.find(12) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(13) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(14) != intHashSet.end()); - - intHashSet = { 22, 23, 24 }; - EATEST_VERIFY(intHashSet.size() == 3); - EATEST_VERIFY(intHashSet.find(22) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(23) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(24) != intHashSet.end()); - - intHashSet.insert({ 42, 43, 44 }); - EATEST_VERIFY(intHashSet.size() == 6); - EATEST_VERIFY(intHashSet.find(42) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(43) != intHashSet.end()); - EATEST_VERIFY(intHashSet.find(44) != intHashSet.end()); - } - - { - // eastl::pair<iterator, iterator> equal_range(const key_type& k); - // eastl::pair<const_iterator, const_iterator> equal_range(const key_type& k) const; - // const_iterator erase(const_iterator, const_iterator); - // size_type erase(const key_type&); - // To do. - } - - - { // hash_set erase_if - hash_set<int> m = {0, 1, 2, 3, 4}; - auto numErased = eastl::erase_if(m, [](auto i) { return i % 2 == 0; }); - VERIFY((m == hash_set<int>{1, 3})); - VERIFY(numErased == 3); - } - - { // hash_multiset erase_if - hash_multiset<int> m = {0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4}; - auto numErased = eastl::erase_if(m, [](auto i) { return i % 2 == 0; }); - VERIFY((m == hash_multiset<int>{1, 1, 1, 3})); - VERIFY(numErased == 12); - } - - - - - - - { // Test hash_map - - // insert_return_type insert(const value_type& value); - // insert_return_type insert(const key_type& key); - // iterator find(const key_type& k); - // const_iterator find(const key_type& k) const; - - typedef hash_map<int, int> HashMapIntInt; - HashMapIntInt hashMap; - const int kCount = 10000; - - for(int i = 0; i < kCount; i++) - { - HashMapIntInt::value_type vt(i, i); - hashMap.insert(vt); - } - - const HashMapIntInt const_hashMap = hashMap; // creating a const version to test for const correctness - - for(auto& e : hashMap) - { - int k = e.first; - int v = e.second; - EATEST_VERIFY(k < kCount); - EATEST_VERIFY(v == k); - EATEST_VERIFY(hashMap.at(k) == k); - EATEST_VERIFY(const_hashMap.at(k) == k); - hashMap.at(k) = k << 4; - } - - for(auto& e : hashMap) - { - int k = e.first; - int v = e.second; - EATEST_VERIFY(k < kCount); - EATEST_VERIFY(v == (k << 4)); - } - - for(int i = 0; i < kCount * 2; i++) - { - HashMapIntInt::iterator it = hashMap.find(i); - - if(i < kCount) - { - EATEST_VERIFY(it != hashMap.end()); - - int k = (*it).first; - int v = (*it).second; - EATEST_VERIFY(v == (k << 4)); - } - else - EATEST_VERIFY(it == hashMap.end()); - } - - for(int i = 0; i < kCount; i++) - { - int v = hashMap.at(i); - EATEST_VERIFY(v == (i << 4)); - } - - #if EASTL_EXCEPTIONS_ENABLED - try - { - hashMap.at(kCount); - EASTL_ASSERT_MSG(false, "at accessor did not throw out_of_range exception"); - } - catch(const std::out_of_range) { } - catch(const std::exception& e) - { - string e_msg(e.what()); - string msg = "wrong exception with message \"" + e_msg + "\" thrown"; - EASTL_ASSERT_MSG(false, msg.c_str()); - } - #endif - HashMapIntInt::insert_return_type result = hashMap.insert(88888); - EATEST_VERIFY(result.second == true); - result = hashMap.insert(88888); - EATEST_VERIFY(result.second == false); - result.first->second = 0; - - // const_iterator erase(const_iterator); - size_t nExpectedSize = hashMap.size(); - - HashMapIntInt::iterator it50 = hashMap.find(50); - EATEST_VERIFY(it50 != hashMap.end()); - - HashMapIntInt::iterator itNext = hashMap.erase(it50); - nExpectedSize--; - EATEST_VERIFY(itNext != hashMap.end()); // Strictly speaking, this isn't guaranteed to be so. But statistically it is very likely. We'll fix this if it becomes a problem. - EATEST_VERIFY(hashMap.size() == nExpectedSize); - - HashMapIntInt::size_type n = hashMap.erase(10); - nExpectedSize--; - EATEST_VERIFY(n == 1); - EATEST_VERIFY(hashMap.size() == nExpectedSize); - - HashMapIntInt::iterator it60 = hashMap.find(60); - EATEST_VERIFY(itNext != hashMap.end()); - - HashMapIntInt::iterator it60Incremented(it60); - for(int i = 0; (i < 5) && (it60Incremented != hashMap.end()); ++i) - { - ++it60Incremented; - --nExpectedSize; - } - - hashMap.erase(it60, it60Incremented); - EATEST_VERIFY(hashMap.size() == nExpectedSize); - - - // insert_return_type insert(const value_type& value, hash_code_t c, node_type* pNodeNew = NULL); - HashMapIntInt::node_type* pNode = hashMap.allocate_uninitialized_node(); - HashMapIntInt::insert_return_type r = hashMap.insert(eastl::hash<int>()(999999), pNode, HashMapIntInt::value_type(999999, 999999)); - EATEST_VERIFY(r.second == true); - pNode = hashMap.allocate_uninitialized_node(); - r = hashMap.insert(eastl::hash<int>()(999999), pNode, HashMapIntInt::value_type(999999, 999999)); - EATEST_VERIFY(r.second == false); - hashMap.free_uninitialized_node(pNode); - hashMap.erase(999999); - - - // mapped_type& operator[](const key_type& key) - // hash_map is unique among the map/set containers in having this function. - hashMap.clear(); - - int x = hashMap[0]; // A default-constructed int (i.e. 0) should be returned. - EATEST_VERIFY(x == 0); - - hashMap[1] = 1; - x = hashMap[1]; - EATEST_VERIFY(x == 1); // Verify that the value we assigned is returned and a default-constructed value is not returned. - - hashMap[0] = 10; // Overwrite our previous 0 with 10. - hashMap[1] = 11; - x = hashMap[0]; - EATEST_VERIFY(x == 10); // Verify the value is as expected. - x = hashMap[1]; - EATEST_VERIFY(x == 11); - } - - - { // Test hash_map - - // Aligned objects should be CustomAllocator instead of the default, because the - // EASTL default might be unable to do aligned allocations, but CustomAllocator always can. - hash_map<Align32, int, eastl::hash<Align32>, eastl::equal_to<Align32>, CustomAllocator> hashMap; - const int kCount = 10000; - - for(int i = 0; i < kCount; i++) - { - Align32 a32(i); // GCC 2.x doesn't like the Align32 object being created in the ctor below. - hash_map<Align32, int>::value_type vt(a32, i); - hashMap.insert(vt); - } - - for(hash_map<Align32, int>::iterator it = hashMap.begin(); it != hashMap.end(); ++it) - { - const Align32& k = (*it).first; - int v = (*it).second; - EATEST_VERIFY(k.mX < 10000); - EATEST_VERIFY(v == k.mX); - } - - for(int i = 0; i < kCount * 2; i++) - { - hash_map<Align32, int>::iterator it = hashMap.find(Align32(i)); - - if(i < kCount) - { - EATEST_VERIFY(it != hashMap.end()); - - const Align32& k = (*it).first; - int v = (*it).second; - EATEST_VERIFY(v == k.mX); - } - else - EATEST_VERIFY(it == hashMap.end()); - } - } - - { // hash_map erase_if - hash_map<int, int> m = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}}; - auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; }); - VERIFY((m == hash_map<int, int>{{1, 1}, {3, 3}})); - VERIFY(numErased == 3); - } - - { // hash_multimap erase_if - hash_multimap<int, int> m = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 1}, {2, 2}, - {2, 2}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {4, 4}}; - auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; }); - VERIFY((m == hash_multimap<int, int>{{1, 1}, {3, 3}, {3, 3}})); - VERIFY(numErased == 9); - } - - - - { - // template <typename U, typename UHash, typename BinaryPredicate> - // iterator find_as(const U& u, UHash uhash, BinaryPredicate predicate); - // template <typename U, typename UHash, typename BinaryPredicate> - // const_iterator find_as(const U& u, UHash uhash, BinaryPredicate predicate) const; - // template <typename U> - // iterator find_as(const U& u); - // template <typename U> - // const_iterator find_as(const U& u) const; - - typedef hash_set<string> HashSetString; - - HashSetString hashSet; - const int kCount = 100; - - for(int i = 0; i < kCount; i++) - { - string::CtorSprintf cs; // GCC 2.x doesn't like this value being created in the ctor below. - string s(cs, "%d", i); - hashSet.insert(s); - } - - for(int i = 0; i < kCount * 2; i++) - { - char pString[32]; - sprintf(pString, "%d", i); - - HashSetString::iterator it = hashSet.find_as(pString); - if(i < kCount) - EATEST_VERIFY(it != hashSet.end()); - else - EATEST_VERIFY(it == hashSet.end()); - - it = hashSet.find_as(pString, hash<const char*>(), equal_to_2<string, const char*>()); - if(i < kCount) - EATEST_VERIFY(it != hashSet.end()); - else - EATEST_VERIFY(it == hashSet.end()); - - string::CtorSprintf cs; - string s(cs, "%d", i); - - it = hashSet.find_as(s); - if (i < kCount) - EATEST_VERIFY(it != hashSet.end()); - else - EATEST_VERIFY(it == hashSet.end()); - } - } - - - { - // Test const containers. - const hash_set<int> constHashSet; - - hash_set<int>::const_iterator i = constHashSet.begin(); - hash_set<int>::const_iterator i3 = i; - hash_set<int>::iterator i2; - i3 = i2; - - EATEST_VERIFY(i3 == i2); - - //const std::tr1::unordered_set<int> constUSet; - //std::tr1::unordered_set<int>::const_iterator i = constUSet.begin(); - //*i = 0; - } - - { - // global operator ==, != - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - const eastl_size_t kIterationCount = 100; - const eastl_size_t kDataRange = 50; - - { - typedef hash_set<HashtableValue, HashtableValueHash, HashtableValuePredicate> HashSet; - HashtableValue value; - - HashSet h1; - HashSet h2; - EATEST_VERIFY(h1 == h2); - - for(eastl_size_t i = 0; i < kIterationCount; i++) - { - value.mData = rng.RandLimit(kDataRange); - h1.insert(value); // Leave value.mExtra as 0. - } - - EATEST_VERIFY(h1 != h2); - h2 = h1; - EATEST_VERIFY(h1 == h2); - - // Test the case of the containers being the same size but having a single different value, despite that it's key compare yields equal. - HashSet h2Saved(h2); - HashSet::iterator it = h2.find(value); - HashtableValue valueModified(value.mData, 1); - h2.erase(it); - h2.insert(valueModified); - EATEST_VERIFY(h1 != h2); - h2 = h2Saved; - - // Test the case of the containers being the same size but having a single different key. - h2Saved = h2; - h2.erase(h2.find(value)); - h2.insert(kDataRange); // Insert something that could not have been in h2. - EATEST_VERIFY(h1 != h2); - h2 = h2Saved; - - h1.erase(h1.find(value)); // Erase from h1 whatever the last value was. - EATEST_VERIFY(h1 != h2); - } - - { - typedef hash_multiset<HashtableValue, HashtableValueHash, HashtableValuePredicate> HashSet; - HashtableValue value; - - HashSet h1; - HashSet h2; - EATEST_VERIFY(h1 == h2); - - for(eastl_size_t i = 0; i < kIterationCount; i++) - { - value.mData = rng.RandLimit(kDataRange); - h1.insert(value); // Leave value.mExtra as 0. - } - - EATEST_VERIFY(h1 != h2); - h2 = h1; - EATEST_VERIFY(h1 == h2); - - // Test the case of the containers being the same size but having a single different value, despite that it's key compare yields equal. - HashSet h2Saved(h2); - HashSet::iterator it = h2.find(value); - HashtableValue valueModified(value.mData, 1); - h2.erase(it); - h2.insert(valueModified); - EATEST_VERIFY(h1 != h2); - h2 = h2Saved; - - // Test the case of the containers being the same size but having a single different key. - h2Saved = h2; - h2.erase(h2.find(value)); - h2.insert(kDataRange); // Insert something that could not have been in h2. - EATEST_VERIFY(h1 != h2); - h2 = h2Saved; - - h1.erase(h1.find(value)); // Erase from h1 whatever the last value was. - EATEST_VERIFY(h1 != h2); - } - - { - // For simplicity we duplicate the HashtableValue::mData member as the hash map key. - typedef hash_map<eastl_size_t, HashtableValue, HashtableValueHash, HashtableValuePredicate> HashMap; - HashtableValue value; - - HashMap h1; - HashMap h2; - EATEST_VERIFY(h1 == h2); - - for(eastl_size_t i = 0; i < kIterationCount; i++) - { - value.mData = rng.RandLimit(kDataRange); - h1.insert(HashMap::value_type(value.mData, value)); // Leave value.mExtra as 0. - } - - EATEST_VERIFY(h1 != h2); - h2 = h1; - EATEST_VERIFY(h1 == h2); - - // Test the case of the containers being the same size but having a single different value, despite that it's key compare yields equal. - HashMap h2Saved(h2); - HashMap::iterator it = h2.find(value.mData); // We are using value.mData as the key as well, so we can do a find via it. - HashtableValue valueModified(value.mData, 1); - h2.erase(it); - h2.insert(HashMap::value_type(valueModified.mData, valueModified)); - EATEST_VERIFY(h1 != h2); - h2 = h2Saved; - - // Test the case of the containers being the same size but having a single different key. - h2Saved = h2; - h2.erase(h2.find(value.mData)); - h2.insert(HashMap::value_type(kDataRange, HashtableValue(kDataRange))); // Insert something that could not have been in h2. - EATEST_VERIFY(h1 != h2); - h2 = h2Saved; - - h1.erase(h1.find(value.mData)); // Erase from h1 whatever the last value was. - EATEST_VERIFY(h1 != h2); - } - - { - // For simplicity we duplicate the HashtableValue::mData member as the hash map key. - typedef hash_multimap<eastl_size_t, HashtableValue, HashtableValueHash, HashtableValuePredicate> HashMap; - HashtableValue value; - - HashMap h1; - HashMap h2; - EATEST_VERIFY(h1 == h2); - - for(eastl_size_t i = 0; i < kIterationCount; i++) - { - value.mData = rng.RandLimit(kDataRange); - h1.insert(HashMap::value_type(value.mData, value)); // Leave value.mExtra as 0. - } - - EATEST_VERIFY(h1 != h2); - h2 = h1; - EATEST_VERIFY(h1 == h2); - - // Test the case of the containers being the same size but having a single different value, despite that it's key compare yields equal. - HashMap h2Saved(h2); - HashMap::iterator it = h2.find(value.mData); // We are using value.mData as the key as well, so we can do a find via it. - HashtableValue valueModified(value.mData, 1); - h2.erase(it); - h2.insert(HashMap::value_type(valueModified.mData, valueModified)); - EATEST_VERIFY(h1 != h2); - h2 = h2Saved; - - // Test the case of the containers being the same size but having a single different key. - h2Saved = h2; - h2.erase(h2.find(value.mData)); - h2.insert(HashMap::value_type(kDataRange, HashtableValue(kDataRange))); // Insert something that could not have been in h2. - EATEST_VERIFY(h1 != h2); - h2 = h2Saved; - - h1.erase(h1.find(value.mData)); // Erase from h1 whatever the last value was. - EATEST_VERIFY(h1 != h2); - } - } - - { - typedef eastl::hash_multiset<int> HashMultisetInt; - - HashMultisetInt hashMultiSet; - - // insert_return_type insert(const value_type& value, hash_code_t c, node_type* pNodeNew = NULL); - HashMultisetInt::node_type* pNode = hashMultiSet.allocate_uninitialized_node(); - HashMultisetInt::iterator it1 = hashMultiSet.insert(eastl::hash<int>()(999999), pNode, 999999); - EATEST_VERIFY(it1 != hashMultiSet.end()); - pNode = hashMultiSet.allocate_uninitialized_node(); - HashMultisetInt::iterator it2 = hashMultiSet.insert(eastl::hash<int>()(999999), pNode, 999999); - EATEST_VERIFY(it2 != hashMultiSet.end() && it2 != it1); - } - - { - // Regression of compiler warning reported by Jeff Litz/Godfather regarding - // strict aliasing (EASTL 1.09.01) December 2007). - typedef eastl::hash_multimap<uint32_t, uint32_t*> Map; - Map* pMap = new Map; - delete pMap; - } - - { - // Regression of user-reported crash. - eastl::hash_map<int, eastl::string*>* _hmTextureList; - _hmTextureList = new eastl::hash_map<int, eastl::string*>(); - eastl::string* a = NULL; - (*_hmTextureList)[0] = a; - delete _hmTextureList; - } - - { - // Regression of user-reported Android compiler error. - typedef eastl::hash_multimap<HashRegressionA*, HashRegressionB> HMM; - HMM m_hash; - - // Section 1 - for (HMM::iterator it = m_hash.begin(); it != m_hash.end(); it++) - it->second.y = 1; - - // Section 2 - HashRegressionA* pA = NULL; - eastl::pair<HMM::iterator, HMM::iterator> pair = m_hash.equal_range(pA); - (void)pair; - } - - { - // Regression of user-reported GCC 4.8 compile failure. - typedef eastl::hash_map<int64_t, Struct> AuditByBlazeIdMap; - - AuditByBlazeIdMap auditBlazeIds; - AuditByBlazeIdMap tempAuditBlazeIds; - - auditBlazeIds.swap(tempAuditBlazeIds); // This line was generating an unexpected compiler failure. - EATEST_VERIFY(auditBlazeIds.empty() && tempAuditBlazeIds.empty()); - } - - { - // This test is designed to designed to use the find_range_by_hash method to walk over all keys in a hash bucket (located by a hash value). - - // Use the 'colliding_hash' hash function to intentionally create lots of collisions in a predictable way. - typedef hash_map<int, int, colliding_hash> HM; - HM hashMap; - - // Add some numbers to the hashMap. - for(int i=0; i<90; i++) - { - hashMap[i] = i; - } - - // Try to find a hash value that doesn't exist - { - eastl::pair<HM::iterator, HM::iterator> i = hashMap.find_range_by_hash(1000); - EATEST_VERIFY(i.first == hashMap.end()); - EATEST_VERIFY(i.second == hashMap.end()); - } - - { - int iterations = 0; - for(eastl::pair<HM::iterator, HM::iterator> i = hashMap.find_range_by_hash(1); i.first != i.second; i.first++) - { - int nodeValue = i.first.get_node()->mValue.first; - EATEST_VERIFY(nodeValue % 3 == 1); // Verify the hash of the node matches the expected value - iterations++; - } - EATEST_VERIFY(iterations == 30); - } - - { - const HM &constHashMap = hashMap; - int iterations = 0; - for(eastl::pair<HM::const_iterator, HM::const_iterator> i = constHashMap.find_range_by_hash(1); i.first != i.second; i.first++) - { - int nodeValue = i.first.get_node()->mValue.first; - EATEST_VERIFY(nodeValue % 3 == 1); // Verify the hash of the node matches the expected value - iterations++; - } - EATEST_VERIFY(iterations == 30); - } - } - - // test hashtable holding move-only types - #if !defined(EA_COMPILER_MSVC_2013) - { - struct Movable - { - Movable() {} - Movable(Movable&&) = default; - Movable& operator=(Movable&&) = default; - Movable(const Movable&) = delete; - Movable& operator=(const Movable&) = delete; - - bool operator==(Movable) const { return true; } - - struct Hash - { - size_t operator()(Movable) const { return 0; } - }; - }; - - eastl::unordered_set<Movable, Movable::Hash> a, b; - swap(a,b); - } - #endif - - { - // hashtable(this_type&& x); - // hashtable(this_type&& x, const allocator_type& allocator); - // this_type& operator=(this_type&& x); - - // template <class... Args> - // insert_return_type emplace(Args&&... args); - - // template <class... Args> - // iterator emplace_hint(const_iterator position, Args&&... args); - - // template <class P> // Requires that "value_type is constructible from forward<P>(otherValue)." - // insert_return_type insert(P&& otherValue); - - // iterator insert(const_iterator hint, value_type&& value); - - // Regression of user reported compiler error in hashtable sfinae mechanism - { - TestObject::Reset(); - eastl::hash_set<TestObject> toSet; - toSet.emplace(3, 4, 5); - } - } - - - - { - // initializer_list support. - // hash_map(std::initializer_list<value_type> ilist, size_type nBucketCount = 0, const Hash& hashFunction = Hash(), - // const Predicate& predicate = Predicate(), const allocator_type& allocator = EASTL_HASH_MAP_DEFAULT_ALLOCATOR) - // this_type& operator=(std::initializer_list<value_type> ilist); - // void insert(std::initializer_list<value_type> ilist); - - // VS2013 has a known issue when dealing with std::initializer_lists - // https://connect.microsoft.com/VisualStudio/feedback/details/792355/compiler-confused-about-whether-to-use-a-initializer-list-assignment-operator - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) && !(defined(_MSC_VER) && _MSC_VER == 1800) - hash_map<int, double> intHashMap = { {12,12.0}, {13,13.0}, {14,14.0} }; - EATEST_VERIFY(intHashMap.size() == 3); - EATEST_VERIFY(intHashMap.find(12) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(13) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(14) != intHashMap.end()); - - intHashMap = { {22,22.0}, {23,23.0}, {24,24.0} }; - EATEST_VERIFY(intHashMap.size() == 3); - EATEST_VERIFY(intHashMap.find(22) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(23) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(24) != intHashMap.end()); - - intHashMap.insert({ {42,42.0}, {43,43.0}, {44,44.0} }); - EATEST_VERIFY(intHashMap.size() == 6); - EATEST_VERIFY(intHashMap.find(42) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(43) != intHashMap.end()); - EATEST_VERIFY(intHashMap.find(44) != intHashMap.end()); - #endif - } - - // Can't use move semantics with hash_map::operator[] - // - // GCC has a bug with overloading rvalue and lvalue function templates. - // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54425 - // - // error: 'eastl::pair<T1, T2>::pair(T1&&) [with T1 = const int&; T2 = const int&]' cannot be overloaded - // error: with 'eastl::pair<T1, T2>::pair(const T1&) [with T1 = const int&; T2 = const int&]' - #if !defined(EA_COMPILER_GNUC) - { - EA_DISABLE_VC_WARNING(4626) - struct Key - { - Key() {} - Key(Key&&) {} - Key(const Key&&) {} - bool operator==(const Key&) const { return true; } - - private: - Key(const Key&) {} - }; - EA_RESTORE_VC_WARNING() - - struct Hash - { - std::size_t operator()(const Key&) const { return 0; } - }; - - Key key1, key2; - eastl::hash_map<Key, int, Hash> hm; - hm[eastl::move(key1)] = 12345; - - EATEST_VERIFY(hm[eastl::move(key2)] == 12345); - } - #endif - - { - using AllocatorType = CountingAllocator; - using String = eastl::basic_string<char8_t, AllocatorType>; - using StringStringMap = eastl::map<String, String, eastl::equal_to<String>, AllocatorType>; - using StringStringHashMap = eastl::hash_map<String, String, eastl::string_hash<String>, eastl::equal_to<String>, AllocatorType>; - AllocatorType::resetCount(); - - { - StringStringHashMap myMap(5); // construct map with 5 buckets, so we don't rehash on insert - String key("mykey01234567890000000000000000000000000000"); - String value("myvalue01234567890000000000000000000000000000"); - AllocatorType::resetCount(); - - myMap.insert(eastl::make_pair(eastl::move(key), eastl::move(value))); - EATEST_VERIFY(AllocatorType::getTotalAllocationCount() == 1); - } - { - StringStringHashMap myMap(5); // construct map with 5 buckets, so we don't rehash on insert - String key("mykey01234567890000000000000000000000000000"); - String value("myvalue01234567890000000000000000000000000000"); - AllocatorType::resetCount(); - - myMap.emplace(eastl::move(key), eastl::move(value)); - EATEST_VERIFY(AllocatorType::getTotalAllocationCount() == 1); - } - { - StringStringMap myMap; - String key("mykey01234567890000000000000000000000000000"); - String value("myvalue01234567890000000000000000000000000000"); - AllocatorType::resetCount(); - - myMap.insert(eastl::make_pair(eastl::move(key), eastl::move(value))); - EATEST_VERIFY(AllocatorType::getTotalAllocationCount() == 1); - } - { - StringStringMap myMap; - String key("mykey01234567890000000000000000000000000000"); - String value("myvalue01234567890000000000000000000000000000"); - AllocatorType::resetCount(); - - myMap.emplace(eastl::move(key), eastl::move(value)); - EATEST_VERIFY(AllocatorType::getTotalAllocationCount() == 1); - } - } - - - { - struct name_equals - { - bool operator()(const eastl::pair<int, const char*>& a, const eastl::pair<int, const char*>& b) const - { - if (a.first != b.first) - return false; - - return strcmp(a.second, b.second) == 0; - } - }; - - { - int n = 42; - const char* pCStrName = "electronic arts"; - eastl::hash_map<eastl::pair<int, const char*>, bool, eastl::hash<eastl::pair<int, const char*>>, name_equals, eastl::allocator> m_TempNames; - m_TempNames[eastl::make_pair(n, pCStrName)] = true; - - auto isFound = (m_TempNames.find(eastl::make_pair(n, pCStrName)) != m_TempNames.end()); - VERIFY(isFound); - } - } - - { // User reported regression for code changes limiting hash code generated for non-arithmetic types. - { VERIFY(HashTest<char>{}('a') == size_t('a')); } - { VERIFY(HashTest<int>{}(42) == 42); } - { VERIFY(HashTest<unsigned>{}(42) == 42); } - { VERIFY(HashTest<signed>{}(42) == 42); } - { VERIFY(HashTest<short>{}(short(42)) == 42); } - { VERIFY(HashTest<unsigned short>{}((unsigned short)42) == 42); } - { VERIFY(HashTest<int>{}(42) == 42); } - { VERIFY(HashTest<unsigned int>{}(42) == 42); } - { VERIFY(HashTest<long int>{}(42) == 42); } - { VERIFY(HashTest<unsigned long int>{}(42) == 42); } - { VERIFY(HashTest<long long int>{}(42) == 42); } - { VERIFY(HashTest<unsigned long long int>{}(42) == 42); } - - #if defined(EA_HAVE_INT128) && EA_HAVE_INT128 - { VERIFY(HashTest<uint128_t>{}(UINT128_C(0, 42)) == 42); } - #endif - } - - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestHeap.cpp b/test/source/TestHeap.cpp deleted file mode 100644 index 4709ecf..0000000 --- a/test/source/TestHeap.cpp +++ /dev/null @@ -1,295 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/heap.h> -#include <EASTL/vector.h> -#include <EASTL/algorithm.h> -#include <EASTL/sort.h> -#include <EABase/eabase.h> -#include <algorithm> //std::pop_heap - -#ifdef _MSC_VER - #pragma warning(push, 0) -#endif - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <algorithm> -#endif - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - -using namespace eastl; - - - - -int VerifyHeaps(uint32_t* pArray2, uint32_t* pArray3, uint32_t nArraySize) -{ - int nErrorCount = 0; - bool bResult; - - bResult = is_heap(pArray2, pArray2 + nArraySize); - EATEST_VERIFY(bResult); - - bResult = is_heap(pArray3, pArray3 + nArraySize); - EATEST_VERIFY(bResult); - - // bResult = (memcmp(pArray2, pArray3, nArraySize * sizeof(uint32_t)) == 0); - // EATEST_VERIFY(bResult); - // - // The above does not work on iOS since CM added -stdlib=libc++ to the linker switch - // even though it was already used in our compile switches. - // It would appear that on clang or iOS the heap is actually structured in a unique way, - // possibly for optimization. Iterating over the array and using pop_heap verifies - // that the heaps have the same elements and are retrieved in the same manner. - // The underlying storage may be different. - uint32_t* pArray2_copy = new uint32_t[nArraySize]; - uint32_t* pArray3_copy = new uint32_t[nArraySize]; - - memcpy(pArray2_copy, pArray2, sizeof(uint32_t) * nArraySize); - memcpy(pArray3_copy, pArray3, sizeof(uint32_t) * nArraySize); - - for(uint32_t i = 0; i < nArraySize; i++) - { - EATEST_VERIFY(pArray2_copy[0] == pArray3_copy[0]); - std::pop_heap(pArray2_copy, pArray2_copy + nArraySize - i); - pop_heap(pArray3_copy, pArray3_copy + nArraySize - i); - } - delete[] pArray2_copy; - delete[] pArray3_copy; - return nErrorCount; -} - - - -int TestHeap() -{ - int nErrorCount = 0; - - // We do a bit of our heap testing by simply doing rng operations and comparing - // to a standard STL implementation of the heap functions. - - { - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - EA::UnitTest::Rand rng(EA::UnitTest::GetRandSeed()); - - const int32_t kMinArraySize = 2; - const int32_t kMaxArraySize = 1000; - const int32_t kMinValue = 0; - const int32_t kMaxValue = 500; - - // To consider, instead of using 25, try conditioning on EA::UnitTest::GetSystemSpeed(). - // I tried this, but even though Caps and PC are the same system speed, Caps was quite slower - // than PC doing 75 loops - for(int i = 0; (i < 25) && (nErrorCount == 0); i++) - { - // - // Set up an array of data to work with as a heap. - uint32_t nArraySizeInitial = (uint32_t)rng.RandRange(kMinArraySize, kMaxArraySize); - uint32_t nArraySize = nArraySizeInitial; - uint32_t* pArray1 = new uint32_t[nArraySize + 1]; // Array1 is the original data. // +1 because we append an additional element in the is_heap_until test below. - uint32_t* pArray2 = new uint32_t[nArraySize + 1]; // Array2 is the data in std::make_heap - uint32_t* pArray3 = new uint32_t[nArraySize + 1]; // Array3 is the data in eastl::make_heap. - - for(uint32_t j = 0; j < nArraySize; j++) - pArray1[j] = pArray2[j] = pArray3[j] = (uint32_t)rng.RandRange(kMinValue, kMaxValue); - - - // make_heap - std::make_heap(pArray2, pArray2 + nArraySize); - make_heap(pArray3, pArray3 + nArraySize); - VerifyHeaps(pArray2, pArray3, nArraySize); - - - // is_heap_until - { - pArray3[nArraySize] = kMaxValue + 1; // Append a value which is guaranteed to break the heap. - uint32_t* pUntil = is_heap_until(pArray3, pArray3 + (nArraySize + 1)); - EATEST_VERIFY_F(pUntil == (pArray3 + nArraySize), "is_heap_until failure in iteration %d for array size %I32u.", nArraySize); - } - - - // pop_heap - const int popCount = min<uint32_t>(200, nArraySize); - for(int k = 0; (k < popCount) && (nErrorCount == 0); k++, nArraySize--) - { - std::pop_heap(pArray2, pArray2 + nArraySize); - pArray2[nArraySize - 1] = 0xffffffff; // Set it to some value so we can recognize it in a debugger. - - pop_heap(pArray3, pArray3 + nArraySize); - pArray3[nArraySize - 1] = 0xffffffff; - - VerifyHeaps(pArray2, pArray3, nArraySize - 1); - } - - - // push_heap - const int pushCount = popCount; - for(int m = 0; (m < pushCount) && (nErrorCount == 0); m++, nArraySize++) - { - const uint32_t n = (uint32_t)rng.RandRange(kMinValue, kMaxValue); - - pArray2[nArraySize] = n; - std::push_heap(pArray2, pArray2 + nArraySize + 1); - - pArray3[nArraySize] = n; - push_heap(pArray3, pArray3 + nArraySize + 1); - - VerifyHeaps(pArray2, pArray3, nArraySize + 1); - } - - uint32_t originalSize = nArraySize; - // remove_heap - // Because the heap that stdlib on iOS and other platforms differs, different elements - // will be removed. After calling remove heap, we cannot call VerifyHeaps anymore, but - // can still check that heap format is retained. - const int eraseCount = popCount; - for(int e = 0; (e < eraseCount) && (nErrorCount == 0); e++, nArraySize--) - { - const uint32_t position = (uint32_t)rng.RandRange(0, nArraySize); - - remove_heap(pArray2, nArraySize, position); - pArray2[nArraySize - 1] = 0xffffffff; - - remove_heap(pArray3, nArraySize, position); - pArray3[nArraySize - 1] = 0xffffffff; - - //use is_heap_until to verify remove_heap is working. - if(nArraySize > 1) //If we just popped last element, don't use is_heap_until - { - uint32_t* pUntil = is_heap_until(pArray2, pArray2 + (nArraySize)); - EATEST_VERIFY_F(pUntil == (pArray2 + nArraySize - 1), "pUntil failure for pArray2 with array size %I32u.", nArraySize); - - pUntil = is_heap_until(pArray3, pArray3 + (nArraySize)); - EATEST_VERIFY_F(pUntil == (pArray3 + nArraySize - 1), "failure for pArray3 with array size %I32u.", nArraySize); - } - } - - // push_heap -- increase the heap size back to the original size. - for(int m = 0; (m < pushCount) && (nErrorCount == 0); m++, nArraySize++) - { - const uint32_t n = (uint32_t)rng.RandRange(kMinValue, kMaxValue); - - pArray2[nArraySize] = n; - std::push_heap(pArray2, pArray2 + nArraySize + 1); - - pArray3[nArraySize] = n; - push_heap(pArray3, pArray3 + nArraySize + 1); - } - - EATEST_VERIFY_F(nArraySize == originalSize, "Array size is %d not original size %d", nArraySize , originalSize); - - uint32_t* pUntil = is_heap_until(pArray2, pArray2 + (nArraySize)); - EATEST_VERIFY_F(pUntil == (pArray2 + nArraySize), "failure for pArray2 with array size %I32u.", nArraySize); - pUntil = is_heap_until(pArray3, pArray3 + (nArraySize)); - EATEST_VERIFY_F(pUntil == (pArray3 + nArraySize), "failure for pArray3 with array size %I32u.", nArraySize); - - - // change_heap - const int changeCount = popCount; - for(int r = 0; (r < changeCount) && (nErrorCount == 0); r++, nArraySize--) - { - uint32_t position = (uint32_t)rng.RandRange(0, nArraySize); - uint32_t newValue = (uint32_t)rng.RandRange(kMinValue, kMaxValue); - - if(rng.RandLimit(5) == 0) // One in five chance that we use the heap top position. - position = 0; - if(rng.RandLimit(5) != 0) // One in five chance that we do no change. - pArray2[position] = pArray3[position] = newValue; - - // There is no std::change_heap, so we just use ours for this test. - change_heap(pArray2, nArraySize, position); - pArray2[nArraySize - 1] = 0xffffffff; - - change_heap(pArray3, nArraySize, position); - pArray3[nArraySize - 1] = 0xffffffff; - - if(nArraySize > 1) //If we just removed last element, don't use is_heap_until - { - uint32_t* pUntilChanged = is_heap_until(pArray2, pArray2 + (nArraySize)); - EATEST_VERIFY_F(pUntilChanged == (pArray2 + nArraySize - 1), "failure for pArray2 with array size %I32u.", nArraySize); - pUntilChanged = is_heap_until(pArray3, pArray3 + (nArraySize)); - EATEST_VERIFY_F(pUntilChanged == (pArray3 + nArraySize - 1), "failure for pArray3 with array size %I32u.", nArraySize); - } - } - - - // sort_heap - std::sort_heap(pArray2, pArray2 + nArraySize); - sort_heap(pArray3, pArray3 + nArraySize); - - for(uint32_t q = 1; (q < nArraySize) && (nErrorCount == 0); q++) - { - EATEST_VERIFY(pArray2[q-1] <= pArray2[q]); - EATEST_VERIFY(pArray3[q-1] <= pArray3[q]); - } - // Free our heap data. - delete[] pArray1; - delete[] pArray2; - delete[] pArray3; - } - - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - } - - { - // Test aligned types. - - // Aligned objects should be CustomAllocator instead of the default, because the - // EASTL default might be unable to do aligned allocations, but CustomAllocator always can. - eastl::vector<Align64, CustomAllocator> heap; - - for(int i = 0; i < 16; i++) - heap.push_back(Align64(i)); - - eastl::make_heap(heap.begin(), heap.end()); - EATEST_VERIFY(is_heap(heap.begin(), heap.end())); - - heap.push_back(Align64(7)); - eastl::push_heap(heap.begin(), heap.end()); - EATEST_VERIFY(is_heap(heap.begin(), heap.end())); - - heap.push_back(Align64(7)); - eastl::push_heap(heap.begin(), heap.end()); - heap.pop_back(); - EATEST_VERIFY(is_heap(heap.begin(), heap.end())); - - eastl::remove_heap(heap.begin(), heap.size(), (eastl_size_t)4); - heap.pop_back(); - EATEST_VERIFY(is_heap(heap.begin(), heap.end())); - - eastl::sort_heap(heap.begin(), heap.end()); - EATEST_VERIFY(is_sorted(heap.begin(), heap.end())); - } - - { - Align16 heap[5]; - - eastl::make_heap(heap, heap + 5); - EATEST_VERIFY(is_heap(heap, heap + 5)); - - eastl::partial_sort(heap, heap + 3, heap + 5); - } - - return nErrorCount; -} - - - - - - - - - - - - - diff --git a/test/source/TestIntrusiveHash.cpp b/test/source/TestIntrusiveHash.cpp deleted file mode 100644 index f089aab..0000000 --- a/test/source/TestIntrusiveHash.cpp +++ /dev/null @@ -1,773 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/internal/intrusive_hashtable.h> -#include <EASTL/intrusive_hash_set.h> -#include <EASTL/intrusive_hash_map.h> -#include <EABase/eabase.h> - - - -using namespace eastl; - - -namespace -{ - struct SetWidget : public intrusive_hash_node - { - SetWidget(int x = 0) - : mX(x) { } - int mX; - }; - - inline bool operator==(const SetWidget& a, const SetWidget& b) - { return a.mX == b.mX; } - - struct SWHash - { - size_t operator()(const SetWidget& sw) const - { - return (size_t)sw.mX; - } - }; - - struct SetWidgetComparable // Exists for the sole purpose of testing the find_as function. - { - SetWidgetComparable(int x = 0) - : mX(x) { } - int mX; - }; - - struct SWCHash - { - size_t operator()(const SetWidgetComparable& swc) const - { - return (size_t)swc.mX; - } - }; - - bool operator==(const SetWidget& a, const SetWidgetComparable& b) - { return a.mX == b.mX; } - - - - struct MapWidget : public intrusive_hash_node_key<int> - { - MapWidget(int x = 0) - : mX(x) { } - int mX; - }; - - inline bool operator==(const MapWidget& a, const MapWidget& b) - { return a.mX == b.mX; } - - //struct MapWidgetComparable // Exists for the sole purpose of testing the find_as function. - //{ - // MapWidgetComparable(int x = 0) - // : mX(x) { } - // int mX; - //}; - // - //bool operator==(const SetWidget& a, const MapWidgetComparable& b) - // { return a.mX == b.mX; } - - - - - // IHWidget - // - // Implements the intrusive node data directly instead of inheriting from intrusive_hash_node. - // - struct IHWidget - { - IHWidget(int x = 0) - : mX(x) { } - - int mX; - IHWidget* mpNext; - typedef int key_type; - int mKey; - - }; - - inline bool operator==(const IHWidget& a, const IHWidget& b) - { return a.mX == b.mX; } - - struct IHWHash - { - size_t operator()(const IHWidget& ihw) const - { - return (size_t)ihw.mX; - } - }; - -} // namespace - - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -//template class intrusive_hash_set<SetWidget>; -//template class intrusive_hash_map<MapWidget>; - - -template class eastl::intrusive_hashtable<SetWidget, SetWidget, SWHash, eastl::equal_to<SetWidget>, 37, true, true>; -template class eastl::intrusive_hashtable<int, MapWidget, eastl::hash<int>, eastl::equal_to<int>, 37, false, true>; - -template class eastl::intrusive_hash_set<SetWidget, 37, SWHash>; -template class eastl::intrusive_hash_multiset<SetWidget, 37, SWHash>; - -template class eastl::intrusive_hash_map<int, MapWidget, 37>; -template class eastl::intrusive_hash_multimap<int, MapWidget, 37>; - -template class eastl::intrusive_hash_set<IHWidget, 37, IHWHash>; -template class eastl::intrusive_hash_multiset<IHWidget, 37, IHWHash>; - -template class eastl::intrusive_hash_map<int, IHWidget, 37, IHWHash>; -template class eastl::intrusive_hash_multimap<int, IHWidget, 37, IHWHash>; - - - - - -int TestIntrusiveHash() -{ - int nErrorCount = 0; - - { - SetWidget sw1, sw2; - VERIFY(sw1 == sw2); - - MapWidget mw1, mw2; - VERIFY(mw1 == mw2); - - IHWidget iw1, iw2; - VERIFY(iw1 == iw2); - - IHWHash ih1; - VERIFY(ih1.operator()(iw1) == ih1.operator()(iw2)); - } - - { - // Test intrusive_hash_set - - const size_t kBucketCount = 37; - typedef intrusive_hash_set<SetWidget, kBucketCount, SWHash> IHM_SW; - - const size_t kArraySize = 100; - SetWidget swArray[kArraySize]; - - int nExpectedKeySum = 0; // We use this as a checksum in order to do validity checks below. - - for(size_t i = 0; i < kArraySize; i++) - { - swArray[i].mX = (int)i; - nExpectedKeySum += (int)i; - } - - - // const key_equal& key_eq() const; - // key_equal& key_eq(); - IHM_SW ih; - const IHM_SW ihc; - - const IHM_SW::key_equal& ke = ihc.key_eq(); - ih.key_eq() = ke; - - - // intrusive_hashtable(const Hash&, const Equal&); - // void swap(this_type& x); - // size_type size() const; - // bool empty() const; - // size_type bucket_count() const; - // size_type bucket_size(size_type n) const; - // float load_factor() const; - // void clear(); - // bool validate() const; - - IHM_SW ihmSW1; - IHM_SW ihmSW2; - - VERIFY(ihmSW1.size() == 0); - VERIFY(ihmSW1.empty()); - VERIFY(ihmSW1.validate()); - VERIFY(ihmSW2.validate()); - - ihmSW1.swap(ihmSW2); - - VERIFY(ihmSW1.validate()); - VERIFY(ihmSW2.validate()); - VERIFY(ihmSW2.bucket_count() == kBucketCount); - VERIFY(ihmSW2.bucket_size(0) == 0); - VERIFY(ihmSW2.bucket_size(kBucketCount - 1) == 0); - VERIFY(ihmSW1.load_factor() == 0.f); - VERIFY(ihmSW2.load_factor() == 0.f); - - ihmSW1.clear(); - VERIFY(ihmSW1.validate()); - VERIFY(ihmSW1.begin() == ihmSW1.end()); - - - // void insert(InputIterator first, InputIterator last); - // insert_return_type insert(value_type& value); - // void swap(this_type& x); - // void clear(); - - ihmSW1.clear(); - ihmSW1.insert(swArray, swArray + (kArraySize - 10)); - for(int i = 0; i < 10; i++) // insert the remaining elements via the other insert function. - { - pair<IHM_SW::iterator, bool> result = ihmSW1.insert(swArray[(kArraySize - 10) + i]); - VERIFY(result.second == true); - } - - VERIFY(ihmSW1.size() == kArraySize); - VERIFY(ihmSW1.validate()); - - for(size_t i = 0; i < kArraySize; i++) - { - // Try to re-insert the elements. All insertions should fail. - pair<IHM_SW::iterator, bool> result = ihmSW1.insert(swArray[i]); - VERIFY(result.second == false); - } - - VERIFY(ihmSW1.size() == kArraySize); - VERIFY(!ihmSW1.empty()); - VERIFY(ihmSW1.validate()); - - ihmSW2.clear(); - ihmSW1.swap(ihmSW2); - - - // size_type size() const; - // bool empty() const; - // size_type count(const key_type& k) const; - // size_type bucket_size(size_type n) const; - // float load_factor() const; - // size_type bucket(const key_type& k) const - - VERIFY(ihmSW1.validate()); - VERIFY(ihmSW2.validate()); - VERIFY(ihmSW1.size() == 0); - VERIFY(ihmSW1.empty()); - VERIFY(ihmSW2.size() == kArraySize); - VERIFY(!ihmSW2.empty()); - VERIFY(ihmSW1.load_factor() == 0.f); - VERIFY(ihmSW2.load_factor() > 2.f); - VERIFY(ihmSW1.count(0) == 0); - VERIFY(ihmSW1.count(999999) == 0); - VERIFY(ihmSW2.count(0) == 1); - VERIFY(ihmSW2.count(999999) == 0); - VERIFY(ihmSW2.bucket_size(0) == 3); // We just happen to know this should be so based on the distribution. - VERIFY(ihmSW2.bucket(13) == (13 % kBucketCount)); // We know this is so because our hash function simply returns n. - VERIFY(ihmSW2.bucket(10000) == (10000 % kBucketCount)); // We know this is so because our hash function simply returns n. - - - // iterator begin(); - // const_iterator begin() const; - - ihmSW1.swap(ihmSW2); - int nSum = 0; - - for(IHM_SW::iterator it = ihmSW1.begin(); it != ihmSW1.end(); ++it) - { - const SetWidget& sw = *it; // Recall that set iterators are const_iterators. - - nSum += sw.mX; - - const int iresult = ihmSW1.validate_iterator(it); - VERIFY(iresult == (isf_valid | isf_current | isf_can_dereference)); - - IHM_SW::iterator itf = ihmSW1.find(sw.mX); - VERIFY(itf == it); - } - - VERIFY(nSum == nExpectedKeySum); - - - // iterator end(); - // const_iterator end() const; - - const IHM_SW& ihmSW1Const = ihmSW1; - - for(IHM_SW::const_iterator itc = ihmSW1Const.begin(); itc != ihmSW1Const.end(); ++itc) - { - const SetWidget& sw = *itc; - - IHM_SW::const_iterator itf = ihmSW1.find(sw.mX); - VERIFY(itf == itc); - } - - - // local_iterator begin(size_type n) - // local_iterator end(size_type) - - for(IHM_SW::local_iterator itl = ihmSW1.begin(5); itl != ihmSW1.end(5); ++itl) - { - const SetWidget& sw = *itl; // Recall that set iterators are const_iterators. - - VERIFY((sw.mX % kBucketCount) == 5); - } - - - // const_local_iterator begin(size_type n) const - // const_local_iterator end(size_type) const - - for(IHM_SW::const_local_iterator itlc = ihmSW1Const.begin(5); itlc != ihmSW1Const.end(5); ++itlc) - { - const SetWidget& sw = *itlc; - - VERIFY((sw.mX % kBucketCount) == 5); - } - - - // iterator find(const key_type& k); - // const_iterator find(const key_type& k) const; - - IHM_SW::iterator itf = ihmSW1.find(SetWidget(99999)); - VERIFY(itf == ihmSW1.end()); - - IHM_SW::const_iterator itfc = ihmSW1Const.find(SetWidget(99999)); - VERIFY(itfc == ihmSW1Const.end()); - - - // iterator find_as(const U& u); - // const_iterator find_as(const U& u) const; - - //itf = ihmSW1.find_as(SetWidget(7)); // Can't work unless there was a default eastl::hash function for SetWidget. - //VERIFY(itf->mX == 7); - - //itfc = ihmSW1Const.find_as(SetWidget(7)); - //VERIFY(itfc->mX == 7); - - - // iterator find_as(const U& u, UHash uhash, BinaryPredicate predicate); - // const_iterator find_as(const U& u, UHash uhash, BinaryPredicate predicate) const; - - itf = ihmSW1.find_as(SetWidgetComparable(7), SWCHash(), eastl::equal_to_2<SetWidget, SetWidgetComparable>()); - VERIFY(itf->mX == 7); - - itfc = ihmSW1Const.find_as(SetWidgetComparable(7), SWCHash(), eastl::equal_to_2<SetWidget, SetWidgetComparable>()); - VERIFY(itfc->mX == 7); - - - // iterator erase(iterator); - // iterator erase(iterator, iterator); - // size_type erase(const key_type&); - - eastl_size_t n = ihmSW1.erase(SetWidget(99999)); - VERIFY(n == 0); - - n = ihmSW1.erase(SetWidget(17)); - VERIFY(n == 1); - - itf = ihmSW1.find(SetWidget(18)); - VERIFY(itf != ihmSW1.end()); - VERIFY(ihmSW1.validate_iterator(itf) == (isf_valid | isf_current | isf_can_dereference)); - - itf = ihmSW1.erase(itf); - VERIFY(itf != ihmSW1.end()); - VERIFY(ihmSW1.validate_iterator(itf) == (isf_valid | isf_current | isf_can_dereference)); - - itf = ihmSW1.find(SetWidget(18)); - VERIFY(itf == ihmSW1.end()); - - itf = ihmSW1.find(SetWidget(19)); - VERIFY(itf != ihmSW1.end()); - - IHM_SW::iterator itf2(itf); - eastl::advance(itf2, 7); - VERIFY(itf2 != ihmSW1.end()); - VERIFY(ihmSW1.validate_iterator(itf2) == (isf_valid | isf_current | isf_can_dereference)); - - itf = ihmSW1.erase(itf, itf2); - VERIFY(itf != ihmSW1.end()); - VERIFY(ihmSW1.validate_iterator(itf) == (isf_valid | isf_current | isf_can_dereference)); - - itf = ihmSW1.find(SetWidget(19)); - VERIFY(itf == ihmSW1.end()); - - - // eastl::pair<iterator, iterator> equal_range(const key_type& k); - // eastl::pair<const_iterator, const_iterator> equal_range(const key_type& k) const; - - eastl::pair<IHM_SW::iterator, IHM_SW::iterator> p = ihmSW1.equal_range(SetWidget(1)); - VERIFY(p.first != ihmSW1.end()); - VERIFY(p.second != ihmSW1.end()); - - eastl::pair<IHM_SW::const_iterator, IHM_SW::const_iterator> pc = ihmSW1Const.equal_range(SetWidget(1)); - VERIFY(pc.first != ihmSW1Const.end()); - VERIFY(pc.second != ihmSW1Const.end()); - - - // void clear(); - // bool validate() const; - // int validate_iterator(const_iterator i) const; - - IHM_SW::iterator itTest; - int iresult = ihmSW1.validate_iterator(itTest); - VERIFY(iresult == isf_none); - - itTest = ihmSW1.begin(); - iresult = ihmSW1.validate_iterator(itTest); - VERIFY(iresult == (isf_valid | isf_current | isf_can_dereference)); - - itTest = ihmSW1.end(); - iresult = ihmSW1.validate_iterator(itTest); - VERIFY(iresult == (isf_valid | isf_current)); - - ihmSW1.clear(); - ihmSW2.clear(); - VERIFY(ihmSW1.validate()); - VERIFY(ihmSW2.validate()); - - itTest = ihmSW1.begin(); - iresult = ihmSW1.validate_iterator(itTest); - VERIFY(iresult == (isf_valid | isf_current)); - } - - - { - // Test intrusive_hash_map - - const size_t kBucketCount = 37; - typedef intrusive_hash_map<int, MapWidget, kBucketCount> IHM_MW; - - const size_t kArraySize = 100; - MapWidget mwArray[kArraySize]; - - int nExpectedKeySum = 0; // We use this as a checksum in order to do validity checks below. - - for(size_t i = 0; i < kArraySize; i++) - { - mwArray[i].mKey = (int)i; - mwArray[i].mX = (int)i; - nExpectedKeySum += (int)i; - } - - - // intrusive_hashtable(const Hash&, const Equal&); - // void swap(this_type& x); - // size_type size() const; - // bool empty() const; - // size_type bucket_count() const; - // size_type bucket_size(size_type n) const; - // float load_factor() const; - // void clear(); - // bool validate() const; - - IHM_MW ihmMW1; - IHM_MW ihmMW2; - - VERIFY(ihmMW1.size() == 0); - VERIFY(ihmMW1.empty()); - VERIFY(ihmMW1.validate()); - VERIFY(ihmMW2.validate()); - - ihmMW1.swap(ihmMW2); - - VERIFY(ihmMW1.validate()); - VERIFY(ihmMW2.validate()); - VERIFY(ihmMW2.bucket_count() == kBucketCount); - VERIFY(ihmMW2.bucket_size(0) == 0); - VERIFY(ihmMW2.bucket_size(kBucketCount - 1) == 0); - VERIFY(ihmMW1.load_factor() == 0.f); - VERIFY(ihmMW2.load_factor() == 0.f); - - ihmMW1.clear(); - VERIFY(ihmMW1.validate()); - VERIFY(ihmMW1.begin() == ihmMW1.end()); - - - // void insert(InputIterator first, InputIterator last); - // insert_return_type insert(value_type& value); - // void swap(this_type& x); - // void clear(); - - ihmMW1.clear(); - ihmMW1.insert(mwArray, mwArray + (kArraySize - 10)); - for(int i = 0; i < 10; i++) // insert the remaining elements via the other insert function. - { - pair<IHM_MW::iterator, bool> result = ihmMW1.insert(mwArray[(kArraySize - 10) + i]); - VERIFY(result.second == true); - } - - VERIFY(ihmMW1.size() == kArraySize); - VERIFY(ihmMW1.validate()); - - for(size_t i = 0; i < kArraySize; i++) - { - // Try to re-insert the elements. All insertions should fail. - pair<IHM_MW::iterator, bool> result = ihmMW1.insert(mwArray[i]); - VERIFY(result.second == false); - } - - VERIFY(ihmMW1.size() == kArraySize); - VERIFY(!ihmMW1.empty()); - VERIFY(ihmMW1.validate()); - - ihmMW2.clear(); - ihmMW1.swap(ihmMW2); - - - // size_type size() const; - // bool empty() const; - // size_type count(const key_type& k) const; - // size_type bucket_size(size_type n) const; - // float load_factor() const; - // size_type bucket(const key_type& k) const - - VERIFY(ihmMW1.validate()); - VERIFY(ihmMW2.validate()); - VERIFY(ihmMW1.size() == 0); - VERIFY(ihmMW1.empty()); - VERIFY(ihmMW2.size() == kArraySize); - VERIFY(!ihmMW2.empty()); - VERIFY(ihmMW1.load_factor() == 0.f); - VERIFY(ihmMW2.load_factor() > 2.f); - VERIFY(ihmMW1.count(0) == 0); - VERIFY(ihmMW1.count(999999) == 0); - VERIFY(ihmMW2.count(0) == 1); - VERIFY(ihmMW2.count(999999) == 0); - VERIFY(ihmMW2.bucket_size(0) == 3); // We just happen to know this should be so based on the distribution. - VERIFY(ihmMW2.bucket(13) == (13 % kBucketCount)); // We know this is so because our hash function simply returns n. - VERIFY(ihmMW2.bucket(10000) == (10000 % kBucketCount)); // We know this is so because our hash function simply returns n. - - - // iterator begin(); - // const_iterator begin() const; - - ihmMW1.swap(ihmMW2); - int nSum = 0; - - for(IHM_MW::iterator it = ihmMW1.begin(); it != ihmMW1.end(); ++it) - { - IHM_MW::value_type& v = *it; - - VERIFY(v.mKey == v.mX); // We intentionally made this so above. - nSum += v.mKey; - - const int iresult = ihmMW1.validate_iterator(it); - VERIFY(iresult == (isf_valid | isf_current | isf_can_dereference)); - - IHM_MW::iterator itf = ihmMW1.find(v.mKey); - VERIFY(itf == it); - } - - VERIFY(nSum == nExpectedKeySum); - - - // iterator end(); - // const_iterator end() const; - - const IHM_MW& ihmMW1Const = ihmMW1; - - for(IHM_MW::const_iterator itc = ihmMW1Const.begin(); itc != ihmMW1Const.end(); ++itc) - { - const IHM_MW::value_type& v = *itc; - - VERIFY(v.mKey == v.mX); // We intentionally made this so above. - - IHM_MW::const_iterator itf = ihmMW1Const.find(v.mKey); - VERIFY(itf == itc); - } - - - // local_iterator begin(size_type n) - // local_iterator end(size_type) - - for(IHM_MW::local_iterator itl = ihmMW1.begin(5); itl != ihmMW1.end(5); ++itl) - { - IHM_MW::value_type& v = *itl; - - VERIFY(v.mKey == v.mX); // We intentionally made this so above. - } - - - // const_local_iterator begin(size_type n) const - // const_local_iterator end(size_type) const - - for(IHM_MW::const_local_iterator itlc = ihmMW1Const.begin(5); itlc != ihmMW1Const.end(5); ++itlc) - { - const IHM_MW::value_type& v = *itlc; - - VERIFY(v.mKey == v.mX); // We intentionally made this so above. - } - - - // iterator find(const key_type& k); - // const_iterator find(const key_type& k) const; - - IHM_MW::iterator itf = ihmMW1.find(99999); - VERIFY(itf == ihmMW1.end()); - - IHM_MW::const_iterator itfc = ihmMW1Const.find(99999); - VERIFY(itfc == ihmMW1Const.end()); - - - // iterator find_as(const U& u); - // const_iterator find_as(const U& u) const; - - itf = ihmMW1.find_as(7.f); - VERIFY(itf->mKey == 7); - - itfc = ihmMW1Const.find_as(7.f); - VERIFY(itfc->mKey == 7); - - itf = ihmMW1.find_as(8); - VERIFY(itf->mKey == 8); - - itfc = ihmMW1Const.find_as(8); - VERIFY(itfc->mKey == 8); - - - // iterator find_as(const U& u, UHash uhash, BinaryPredicate predicate); - // const_iterator find_as(const U& u, UHash uhash, BinaryPredicate predicate) const; - - itf = ihmMW1.find_as(7.f, eastl::hash<float>(), eastl::equal_to_2<int, float>()); - VERIFY(itf->mKey == 7); - - itfc = ihmMW1Const.find_as(7.f, eastl::hash<float>(), eastl::equal_to_2<int, float>()); - VERIFY(itfc->mKey == 7); - - - // iterator erase(iterator); - // iterator erase(iterator, iterator); - // size_type erase(const key_type&); - - eastl_size_t n = ihmMW1.erase(99999); - VERIFY(n == 0); - - n = ihmMW1.erase(17); - VERIFY(n == 1); - - itf = ihmMW1.find(18); - VERIFY(itf != ihmMW1.end()); - VERIFY(ihmMW1.validate_iterator(itf) == (isf_valid | isf_current | isf_can_dereference)); - - itf = ihmMW1.erase(itf); - VERIFY(itf != ihmMW1.end()); - VERIFY(ihmMW1.validate_iterator(itf) == (isf_valid | isf_current | isf_can_dereference)); - - itf = ihmMW1.find(18); - VERIFY(itf == ihmMW1.end()); - - itf = ihmMW1.find(19); - VERIFY(itf != ihmMW1.end()); - - IHM_MW::iterator itf2(itf); - eastl::advance(itf2, 7); - VERIFY(itf2 != ihmMW1.end()); - VERIFY(ihmMW1.validate_iterator(itf2) == (isf_valid | isf_current | isf_can_dereference)); - - itf = ihmMW1.erase(itf, itf2); - VERIFY(itf != ihmMW1.end()); - VERIFY(ihmMW1.validate_iterator(itf) == (isf_valid | isf_current | isf_can_dereference)); - - itf = ihmMW1.find(19); - VERIFY(itf == ihmMW1.end()); - - - // eastl::pair<iterator, iterator> equal_range(const key_type& k); - // eastl::pair<const_iterator, const_iterator> equal_range(const key_type& k) const; - - eastl::pair<IHM_MW::iterator, IHM_MW::iterator> p = ihmMW1.equal_range(1); - VERIFY(p.first != ihmMW1.end()); - VERIFY(p.second != ihmMW1.end()); - - eastl::pair<IHM_MW::const_iterator, IHM_MW::const_iterator> pc = ihmMW1Const.equal_range(1); - VERIFY(pc.first != ihmMW1Const.end()); - VERIFY(pc.second != ihmMW1Const.end()); - - - // void clear(); - // bool validate() const; - // int validate_iterator(const_iterator i) const; - - IHM_MW::iterator itTest; - int iresult = ihmMW1.validate_iterator(itTest); - VERIFY(iresult == isf_none); - - itTest = ihmMW1.begin(); - iresult = ihmMW1.validate_iterator(itTest); - VERIFY(iresult == (isf_valid | isf_current | isf_can_dereference)); - - itTest = ihmMW1.end(); - iresult = ihmMW1.validate_iterator(itTest); - VERIFY(iresult == (isf_valid | isf_current)); - - ihmMW1.clear(); - ihmMW2.clear(); - VERIFY(ihmMW1.validate()); - VERIFY(ihmMW2.validate()); - - itTest = ihmMW1.begin(); - iresult = ihmMW1.validate_iterator(itTest); - VERIFY(iresult == (isf_valid | isf_current)); - } - - - { - // Test case of single bucket. - eastl::intrusive_hash_set<SetWidget, 1, SWHash> hs; - SetWidget node1, node2, node3; - - node1.mX = 1; - node2.mX = 2; - node3.mX = 3; - - hs.insert(node1); - hs.insert(node2); - hs.insert(node3); - - const eastl_size_t removeCount = hs.erase(node3); - VERIFY(removeCount == 1); - } - - - { - // Test intrusive_hashtable_iterator(value_type* pNode, value_type** pBucket = NULL) - eastl::intrusive_hash_set<SetWidget, 37, SWHash> hs; - SetWidget node1, node2, node3; - - node1.mX = 1; - node2.mX = 2; - node3.mX = 3; - - hs.insert(node1); - hs.insert(node2); - hs.insert(node3); - - VERIFY(hs.validate()); - - hs.remove(node1); - hs.remove(node2); - hs.remove(node3); - - VERIFY(hs.validate()); - - hs.insert(node1); - hs.insert(node2); - hs.insert(node3); - - VERIFY(hs.validate()); - } - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestIntrusiveList.cpp b/test/source/TestIntrusiveList.cpp deleted file mode 100644 index 60b2378..0000000 --- a/test/source/TestIntrusiveList.cpp +++ /dev/null @@ -1,403 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/intrusive_list.h> -#include <EABase/eabase.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#include <stdio.h> -#include <stdarg.h> -#include <stddef.h> - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <string> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -using namespace eastl; - - -namespace -{ - - /// IntNode - /// - /// Test intrusive_list node. - /// - struct IntNode : public eastl::intrusive_list_node - { - int mX; - - IntNode(int x = 0) - : mX(x) { } - - operator int() const - { return mX; } - }; - - - /// ListInit - /// - /// Utility class for setting up a list. - /// - class ListInit - { - public: - ListInit(intrusive_list<IntNode>& container, IntNode* pNodeArray) - : mpContainer(&container), mpNodeArray(pNodeArray) - { - mpContainer->clear(); - } - - ListInit& operator+=(int x) - { - mpNodeArray->mX = x; - mpContainer->push_back(*mpNodeArray++); - return *this; - } - - ListInit& operator,(int x) - { - mpNodeArray->mX = x; - mpContainer->push_back(*mpNodeArray++); - return *this; - } - - protected: - intrusive_list<IntNode>* mpContainer; - IntNode* mpNodeArray; - }; - -} // namespace - - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::intrusive_list<IntNode>; - - - -int TestIntrusiveList() -{ - int nErrorCount = 0; - int i; - - { - // Verify that intrusive_list_node is a POD, at least when EASTL_VALIDATE_INTRUSIVE_LIST is disabled. - #if !EASTL_VALIDATE_INTRUSIVE_LIST - // is_pod doesn't currently detect structs as PODs, even though it should. - // This is due to limitations in C++. - // VERIFY(eastl::is_pod<eastl::intrusive_list_node>::value); - - const size_t offset = offsetof(intrusive_list_node, mpPrev); - VERIFY(offset == sizeof(intrusive_list_node*)); - #endif - } - - { - IntNode nodes[20]; - - intrusive_list<IntNode> ilist; - - // Enforce that the intrusive_list copy ctor is visible. If it is not, - // then the class is not a POD type as it is supposed to be. - delete new intrusive_list<IntNode>(ilist); - - #ifndef __GNUC__ // GCC warns on this, though strictly specaking it is allowed to. - // Enforce that offsetof() can be used with an intrusive_list in a struct; - // it requires a POD type. Some compilers will flag warnings or even errors - // when this is violated. - struct Test { - intrusive_list<IntNode> m; - }; - (void)offsetof(Test, m); - #endif - - // begin / end - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "ctor()", -1)); - - - // push_back - ListInit(ilist, nodes) += 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "push_back()", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1)); - - - // iterator / begin - intrusive_list<IntNode>::iterator it = ilist.begin(); - VERIFY(it->mX == 0); - ++it; - VERIFY(it->mX == 1); - ++it; - VERIFY(it->mX == 2); - ++it; - VERIFY(it->mX == 3); - - - // const_iterator / begin - const intrusive_list<IntNode> cilist; - intrusive_list<IntNode>::const_iterator cit; - for(cit = cilist.begin(); cit != cilist.end(); ++cit) - VERIFY(cit == cilist.end()); // This is guaranteed to be false. - - - // reverse_iterator / rbegin - intrusive_list<IntNode>::reverse_iterator itr = ilist.rbegin(); - VERIFY(itr->mX == 9); - ++itr; - VERIFY(itr->mX == 8); - ++itr; - VERIFY(itr->mX == 7); - ++itr; - VERIFY(itr->mX == 6); - - - // iterator++/-- - { - intrusive_list<IntNode>::iterator it1(ilist.begin()); - intrusive_list<IntNode>::iterator it2(ilist.begin()); - - ++it1; - ++it2; - if ((it1 != it2++) || (++it1 != it2)) - VERIFY(!"[iterator::increment] fail\n"); - - if ((it1 != it2--) || (--it1 != it2)) - VERIFY(!"[iterator::decrement] fail\n"); - } - - - // clear / empty - VERIFY(!ilist.empty()); - - ilist.clear(); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "clear()", -1)); - VERIFY(ilist.empty()); - - - // splice - ListInit(ilist, nodes) += 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; - - ilist.splice(++ilist.begin(), ilist, --ilist.end()); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "splice(single)", 0, 9, 1, 2, 3, 4, 5, 6, 7, 8, -1)); - - intrusive_list<IntNode> ilist2; - ListInit(ilist2, nodes+10) += 10, 11, 12, 13, 14, 15, 16, 17, 18, 19; - - ilist.splice(++++ilist.begin(), ilist2); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "splice(whole)", -1)); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "splice(whole)", 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 2, 3, 4, 5, 6, 7, 8, -1)); - - ilist.splice(ilist.begin(), ilist, ++++ilist.begin(), ----ilist.end()); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "splice(range)", 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 2, 3, 4, 5, 6, 0, 9, 7, 8, -1)); - - ilist.clear(); - ilist.swap(ilist2); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "swap(empty)", -1)); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "swap(empty)", -1)); - - ilist2.push_back(nodes[0]); - ilist.splice(ilist.begin(), ilist2); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "splice(single)", 0, -1)); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "splice(single)", -1)); - - - // splice(single) -- evil case (splice at or right after current position) - ListInit(ilist, nodes) += 0, 1, 2, 3, 4; - ilist.splice(++++ilist.begin(), *++++ilist.begin()); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "splice(single)", 0, 1, 2, 3, 4, -1)); - ilist.splice(++++++ilist.begin(), *++++ilist.begin()); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "splice(single)", 0, 1, 2, 3, 4, -1)); - - - // splice(range) -- evil case (splice right after current position) - ListInit(ilist, nodes) += 0, 1, 2, 3, 4; - ilist.splice(++++ilist.begin(), ilist, ++ilist.begin(), ++++ilist.begin()); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "splice(range)", 0, 1, 2, 3, 4, -1)); - - - // push_front / push_back - ilist.clear(); - ilist2.clear(); - for(i = 4; i >= 0; --i) - ilist.push_front(nodes[i]); - for(i = 5; i < 10; ++i) - ilist2.push_back(nodes[i]); - - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "push_front()", 0, 1, 2, 3, 4, -1)); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "push_back()", 5, 6, 7, 8, 9, -1)); - - for(i = 4; i >= 0; --i) - { - ilist.pop_front(); - ilist2.pop_back(); - } - - VERIFY(ilist.empty() && ilist2.empty()); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "pop_front()", -1)); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "pop_back()", -1)); - - - // contains / locate - for(i = 0; i < 5; ++i) - ilist.push_back(nodes[i]); - - VERIFY( ilist.contains(nodes[2])); - VERIFY(!ilist.contains(nodes[7])); - - it = ilist.locate(nodes[3]); - VERIFY(it->mX == 3); - - it = ilist.locate(nodes[8]); - VERIFY(it == ilist.end()); - - - // reverse - ilist.reverse(); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "push_front()", 4, 3, 2, 1, 0, -1)); - - - // validate / validate_iterator - VERIFY(ilist.validate()); - it = ilist.locate(nodes[3]); - VERIFY((ilist.validate_iterator(it) & (isf_valid | isf_can_dereference)) != 0); - VERIFY( ilist.validate_iterator(intrusive_list<IntNode>::iterator(NULL)) == isf_none); - - - // swap() - ilist.swap(ilist2); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "swap()", -1)); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "swap()", 4, 3, 2, 1, 0, -1)); - - - // erase() - ListInit(ilist2, nodes) += 0, 1, 2, 3, 4; - ListInit(ilist, nodes+5) += 5, 6, 7, 8, 9; - ilist.erase(++++ilist.begin()); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "erase(single)", 5, 6, 8, 9, -1)); - - ilist.erase(ilist.begin(), ilist.end()); - VERIFY(VerifySequence(ilist.begin(), ilist.end(), int(), "erase(all)", -1)); - - ilist2.erase(++ilist2.begin(), ----ilist2.end()); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "erase(range)", 0, 3, 4, -1)); - - - // size - VERIFY(ilist2.size() == 3); - - - // pop_front / pop_back - ilist2.pop_front(); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "pop_front()", 3, 4, -1)); - - ilist2.pop_back(); - VERIFY(VerifySequence(ilist2.begin(), ilist2.end(), int(), "pop_back()", 3, -1)); - } - - - { - // Test copy construction and assignment. - // The following *should* not compile. - - intrusive_list<IntNode> ilist1; - intrusive_list<IntNode> ilist2(ilist1); - ilist1 = ilist2; - } - - - { - // void sort() - // void sort(Compare compare) - - const int kSize = 10; - IntNode nodes[kSize]; - - intrusive_list<IntNode> listEmpty; - listEmpty.sort(); - VERIFY(VerifySequence(listEmpty.begin(), listEmpty.end(), int(), "list::sort", -1)); - - intrusive_list<IntNode> list1; - ListInit(list1, nodes) += 1; - list1.sort(); - VERIFY(VerifySequence(list1.begin(), list1.end(), int(), "list::sort", 1, -1)); - list1.clear(); - - intrusive_list<IntNode> list4; - ListInit(list4, nodes) += 1, 9, 2, 3; - list4.sort(); - VERIFY(VerifySequence(list4.begin(), list4.end(), int(), "list::sort", 1, 2, 3, 9, -1)); - list4.clear(); - - intrusive_list<IntNode> listA; - ListInit(listA, nodes) += 1, 9, 2, 3, 5, 7, 4, 6, 8, 0; - listA.sort(); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "list::sort", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1)); - listA.clear(); - - intrusive_list<IntNode> listB; - ListInit(listB, nodes) += 1, 9, 2, 3, 5, 7, 4, 6, 8, 0; - listB.sort(eastl::less<int>()); - VERIFY(VerifySequence(listB.begin(), listB.end(), int(), "list::sort", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1)); - listB.clear(); - } - - - { - // void merge(this_type& x); - // void merge(this_type& x, Compare compare); - - const int kSize = 8; - IntNode nodesA[kSize]; - IntNode nodesB[kSize]; - - intrusive_list<IntNode> listA; - ListInit(listA, nodesA) += 1, 2, 3, 4, 4, 5, 9, 9; - - intrusive_list<IntNode> listB; - ListInit(listB, nodesB) += 1, 2, 3, 4, 4, 5, 9, 9; - - listA.merge(listB); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "list::merge", 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 9, 9, 9, 9, -1)); - VERIFY(VerifySequence(listB.begin(), listB.end(), int(), "list::merge", -1)); - } - - - { - // void unique(); - // void unique(BinaryPredicate); - - const int kSize = 8; - IntNode nodesA[kSize]; - IntNode nodesB[kSize]; - - intrusive_list<IntNode> listA; - ListInit(listA, nodesA) += 1, 2, 3, 4, 4, 5, 9, 9; - listA.unique(); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "list::unique", 1, 2, 3, 4, 5, 9, -1)); - - intrusive_list<IntNode> listB; - ListInit(listB, nodesB) += 1, 2, 3, 4, 4, 5, 9, 9; - listB.unique(eastl::equal_to<int>()); - VERIFY(VerifySequence(listA.begin(), listA.end(), int(), "list::unique", 1, 2, 3, 4, 5, 9, -1)); - } - - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestIntrusiveSDList.cpp b/test/source/TestIntrusiveSDList.cpp deleted file mode 100644 index 13a4802..0000000 --- a/test/source/TestIntrusiveSDList.cpp +++ /dev/null @@ -1,315 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/bonus/intrusive_sdlist.h> -#include <EASTL/string.h> -#include <EABase/eabase.h> - -#ifdef _MSC_VER - #pragma warning(push, 0) -#endif - -#include <stdarg.h> -#include <stdio.h> - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - - -using namespace eastl; - - -namespace TestSDListLocal -{ - - struct IntNode : public intrusive_sdlist_node - { - IntNode() {} - IntNode(int x) : mX(x) {} - operator int() const { return mX; } - - int mX; - }; - - typedef intrusive_sdlist<IntNode> IntrusiveSDList; - - template <class T> - eastl::string IntListToString8(const T& cont) - { - eastl::string s("<"); - char buf[64]; - - for(typename T::const_iterator it(cont.begin()), itEnd(cont.end()); it != itEnd; ++it) - { - const int& v = *it; - sprintf(buf, " %d", v); - s += buf; - } - - s += " >"; - return s; - } - - - template <class T> - bool VerifyContainer(const T& cont, const char *testname, ...) - { - //if (!cont.validate()) { - // EASTLTest_Printf("intrusive_list[%s] container damaged!\n", testname); - // return false; - //} - - typename T::const_iterator it(cont.begin()), itEnd(cont.end()); - va_list val; - int index = 0; - - va_start(val, testname); - while(it != itEnd) - { - int next = va_arg(val, int); - - if (next == -1 || next != *it) - { - const int value = *it; - const char* const pString = IntListToString8(cont).c_str(); - EASTLTest_Printf("intrusive_list[%s] Mismatch at index %d: expected %d, found %d; contents: %s\n", testname, index, next, value, pString); - va_end(val); - return false; - } - - ++it; - ++index; - } - - if (va_arg(val, int) != -1) - { - do { - ++index; - } while(va_arg(val, int) != -1); - - const int countainerSize = (int)cont.size(); - const char* const pString = IntListToString8(cont).c_str(); - EASTLTest_Printf("intrusive_list[%s] Too many elements: expected %d, found %d; contents: %s\n", testname, index, countainerSize, pString); - va_end(val); - return false; - } - - va_end(val); - - // We silence this by default for a quieter test run. - // EASTLTest_Printf("intrusive_list[%s] pass\n", testname); - return true; - } - - - class ListInit - { - public: - ListInit(intrusive_sdlist<IntNode>& container, IntNode* pNodeArray) - : mpContainer(&container), mpNodeArray(pNodeArray) - { - mpContainer->clear(); - } - - ListInit& operator+=(int x) - { - mpNodeArray->mX = x; - mpContainer->push_back(*mpNodeArray++); - return *this; - } - - ListInit& operator,(int x) - { - mpNodeArray->mX = x; - mpContainer->push_back(*mpNodeArray++); - return *this; - } - - protected: - intrusive_sdlist<IntNode>* mpContainer; - IntNode* mpNodeArray; - }; - -} // namespace - - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::intrusive_sdlist<TestSDListLocal::IntNode>; - - - -int TestIntrusiveSDList() -{ - using namespace TestSDListLocal; - - int nErrorCount = 0; - - IntNode nodes[20]; - - IntrusiveSDList l; - - // Enforce that the intrusive_list copy ctor is visible. If it is not, then - // the class is not a POD type as it is supposed to. - delete new IntrusiveSDList(l); - - // Enforce that offsetof() can be used with an intrusive_list in a struct; - // it requires a POD type. Some compilers will flag warnings or even errors - // when this is violated. - struct Test { IntrusiveSDList m; }; - - #ifndef __GNUC__ // GCC warns on this, though strictly specaking it is allowed to. - (void)offsetof(Test, m); - #endif - - VERIFY(VerifyContainer(l, "ctor()", -1)); - - // push_back - ListInit(l, nodes) += 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; - VERIFY(VerifyContainer(l, "push_back()", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1)); - - // iterator++ - { - IntrusiveSDList::iterator it1(l.begin()); - IntrusiveSDList::iterator it2(l.begin()); - - ++it1; - ++it2; - - if (it1 != it2++ || ++it1 != it2) { - VERIFY(!"[iterator::increment] fail\n"); - } - } - - // clear()/empty() - VERIFY(!l.empty()); - - l.clear(); - VERIFY(VerifyContainer(l, "clear()", -1)); - VERIFY(l.empty()); - - l.erase(l.begin(), l.end()); // Erase an already empty container. - VERIFY(l.empty()); - - IntrusiveSDList l2; - - // splice - //ListInit(l, nodes) += 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; - // - //l.splice(++l.begin(), l, --l.end()); - //VERIFY(VerifyContainer(l, "splice(single)", 0, 9, 1, 2, 3, 4, 5, 6, 7, 8, -1)); - // - //ListInit(l2, nodes+10) += 10, 11, 12, 13, 14, 15, 16, 17, 18, 19; - // - //l.splice(++++l.begin(), l2); - //VERIFY(VerifyContainer(l2, "splice(whole)", -1)); - //VERIFY(VerifyContainer(l, "splice(whole)", 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 2, 3, 4, 5, 6, 7, 8, -1)); - - //l.splice(l.begin(), l, ++++l.begin(), ----l.end()); - //VERIFY(VerifyContainer(l, "splice(range)", 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 2, 3, 4, 5, 6, 0, 9, 7, 8, -1)); - - //l.clear(); - //l.swap(l2); - //VERIFY(VerifyContainer(l, "swap(empty)", -1)); - //VERIFY(VerifyContainer(l2, "swap(empty)", -1)); - - //l2.push_back(nodes[0]); - //l.splice(l.begin(), l2); - //VERIFY(VerifyContainer(l, "splice(single)", 0, -1)); - //VERIFY(VerifyContainer(l2, "splice(single)", -1)); - - // splice(single) -- evil case (splice at or right after current position) - //ListInit(l, nodes) += 0, 1, 2, 3, 4; - //l.splice(++++l.begin(), *++++l.begin()); - //VERIFY(VerifyContainer(l, "splice(single)", 0, 1, 2, 3, 4, -1)); - //l.splice(++++++l.begin(), *++++l.begin()); - //VERIFY(VerifyContainer(l, "splice(single)", 0, 1, 2, 3, 4, -1)); - - // splice(range) -- evil case (splice right after current position) - //ListInit(l, nodes) += 0, 1, 2, 3, 4; - //l.splice(++++l.begin(), l, ++l.begin(), ++++l.begin()); - //VERIFY(VerifyContainer(l, "splice(range)", 0, 1, 2, 3, 4, -1)); - - // push_front() - l.clear(); - l2.clear(); - for(int i=4; i>=0; --i) { - l.push_front(nodes[i]); - l2.push_front(nodes[i+5]); - } - - VERIFY(VerifyContainer(l, "push_front()", 0, 1, 2, 3, 4, -1)); - VERIFY(VerifyContainer(l2, "push_front()", 5, 6, 7, 8, 9, -1)); - - // swap() - l.swap(l2); - VERIFY(VerifyContainer(l, "swap()", 5, 6, 7, 8, 9, -1)); - VERIFY(VerifyContainer(l2, "swap()", 0, 1, 2, 3, 4, -1)); - - // erase() - ListInit(l2, nodes) += 0, 1, 2, 3, 4; - ListInit(l, nodes+5) += 5, 6, 7, 8, 9; - l.erase(++++l.begin()); - VERIFY(VerifyContainer(l, "erase(single)", 5, 6, 8, 9, -1)); - - l.erase(l.begin(), l.end()); - VERIFY(VerifyContainer(l, "erase(all)", -1)); - - ListInit(l, nodes) += 0, 1, 2; - VERIFY(l2.size() == 3); - - l2.pop_front(); - VERIFY(VerifyContainer(l2, "pop_front()", 1, 2, -1)); - - l2.pop_back(); - VERIFY(VerifyContainer(l2, "pop_back()", 1, -1)); - - // remove - IntNode i1(1), i2(2), i3(3); - l.clear(); - - l.push_front(i1); - IntrusiveSDList::remove(i1); - VERIFY(VerifyContainer(l, "remove()", -1)); - - l.push_front(i1); - l.push_front(i2); - IntrusiveSDList::remove(i1); - VERIFY(VerifyContainer(l, "remove()", 2, -1)); - - l.push_front(i1); - IntrusiveSDList::remove(i2); - VERIFY(VerifyContainer(l, "remove()", 1, -1)); - - l.push_back(i2); - l.push_back(i3); - IntrusiveSDList::remove(i2); - VERIFY(VerifyContainer(l, "remove()", 1, 3, -1)); - - - // const_iterator / begin - const intrusive_sdlist<IntNode> cilist; - intrusive_sdlist<IntNode>::const_iterator cit; - for(cit = cilist.begin(); cit != cilist.end(); ++cit) - VERIFY(cit == cilist.end()); // This is guaranteed to be false. - - - - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestIntrusiveSList.cpp b/test/source/TestIntrusiveSList.cpp deleted file mode 100644 index 0112eea..0000000 --- a/test/source/TestIntrusiveSList.cpp +++ /dev/null @@ -1,38 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/bonus/intrusive_slist.h> -#include <EABase/eabase.h> - - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -//template class intrusive_slist<int>; - - - -int TestIntrusiveSList() -{ - int nErrorCount = 0; - - // As of this writing, we don't yet have a completed intrusive_slist implementation. - // The interface is in place but the implementation hasn't been done yet. - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestIterator.cpp b/test/source/TestIterator.cpp deleted file mode 100644 index b6c6f76..0000000 --- a/test/source/TestIterator.cpp +++ /dev/null @@ -1,579 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/deque.h> -#include <EASTL/iterator.h> -#include <EASTL/vector.h> -#include <EASTL/set.h> -#include <EASTL/array.h> -#include <EASTL/numeric.h> -#include <EASTL/list.h> -#include <EASTL/slist.h> -#include <EASTL/string.h> -#include <EASTL/intrusive_list.h> -#include <EASTL/memory.h> -#include <EASTL/unique_ptr.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#include <stdio.h> -#include <string.h> -EA_RESTORE_ALL_VC_WARNINGS() - -template <class T> -using detect_iterator_traits_reference = typename eastl::iterator_traits<T>::reference; - -// This is used below, though is currently disabled as documented below. -struct IListNode : public eastl::intrusive_list_node{}; - -int TestIterator_advance() -{ - int nErrorCount = 0; - - { - // void advance(InputIterator& i, Distance n) - const int num_elements = 10; - int i; - - eastl::vector<int> v; - for(i = 0; i < num_elements; i++) - v.push_back(i); - - // test forward advancement - eastl::vector<int>::iterator it = v.begin(); - for(i = 0; i < num_elements; i++) - { - EATEST_VERIFY(*it == v[i]); - eastl::advance(it, 1); - } - - // test backwards advancement - eastl::vector<int>::iterator it2 = v.end(); - i = num_elements - 1; - do - { - eastl::advance(it2, -1); - EATEST_VERIFY(*it2 == v[i]); - } - while(i-- != 0); - } - - { - // void advance(InputIterator& i, Distance n) - eastl::list<int> intList; - intList.push_back(0); - intList.push_back(1); - intList.push_back(42); - intList.push_back(2); - - eastl::list<int>::iterator it = intList.begin(); - eastl::advance(it, intList.size()); - EATEST_VERIFY(it == intList.end()); - - // Exercise advance with an signed Distance type. - it = intList.begin(); - eastl::advance(it, (ssize_t)intList.size()); - EATEST_VERIFY(it == intList.end()); - - - eastl::slist<int> intSlist; - intSlist.push_front(0); - intSlist.push_front(1); - intSlist.push_front(42); - intSlist.push_front(2); - - eastl::slist<int>::iterator its = intSlist.begin(); - eastl::advance(its, intSlist.size()); - EATEST_VERIFY(its == intSlist.end()); - - // Exercise advance with an signed Distance type. - its = intSlist.begin(); - eastl::advance(its, (ssize_t)intSlist.size()); - EATEST_VERIFY(its == intSlist.end()); - } - - { - // void next(InputIterator& i, Distance n) - eastl::vector<int> v; - v.push_back(0); - v.push_back(1); - v.push_back(42); - v.push_back(2); - - eastl::vector<int>::iterator it = v.begin(); - EATEST_VERIFY(*eastl::next(it, 0) == 0); - EATEST_VERIFY(*eastl::next(it /*testing the iterator distance default value*/) == 1); - EATEST_VERIFY(*eastl::next(it, 2) == 42); - } - - { - // void prev(InputIterator& i, Distance n) - eastl::vector<int> v; - v.push_back(0); - v.push_back(1); - v.push_back(42); - v.push_back(2); - - eastl::vector<int>::iterator it = v.end(); - EATEST_VERIFY(*eastl::prev(it, 2) == 42); - EATEST_VERIFY(*eastl::prev(it /*testing the iterator distance default value*/) == 2); - } - - return nErrorCount; -} - -int TestIterator_moveIterator() -{ - int nErrorCount = 0; - - { - eastl::vector<int> v = {0, 1, 42, 2}; - const auto constBeginMoveIter = eastl::make_move_iterator(v.begin()); - - // operator++(int) - auto moveIter = constBeginMoveIter; - moveIter++; // the result of the expression is the incremented value, we need this test to read the existing state of the iterator. - EATEST_VERIFY(*moveIter != *constBeginMoveIter); - - // operator--(int) - moveIter = constBeginMoveIter + 2; // points to '42' - moveIter--; // the result of the expression is the incremented value, we need this test to read the existing state of the iterator. - EATEST_VERIFY(*moveIter != *(constBeginMoveIter + 2)); - } - - { - // Ensure that move_iterator indeed move yielded value whenever possible. - auto x = eastl::make_unique<int>(42); - auto* pX = &x; - auto moveIter = eastl::make_move_iterator(pX); - - constexpr bool isCorrectReferenceType = eastl::is_same_v<decltype(moveIter)::reference, eastl::unique_ptr<int>&&>; - constexpr bool isCorrectReturnType = eastl::is_same_v<decltype(*moveIter), eastl::unique_ptr<int>&&>; - - static_assert(isCorrectReferenceType, "move_iterator::reference has wrong type."); - static_assert(isCorrectReturnType, "move_iterator::operator*() has wrong return type."); - EATEST_VERIFY(isCorrectReferenceType); - EATEST_VERIFY(isCorrectReturnType); - - auto pMoveX = *moveIter; - EATEST_VERIFY(*pMoveX == 42); - } - - // Bellow are regression tests that ensure we are covering the defect LWG 2106: http://cplusplus.github.io/LWG/lwg-defects.html#2106 - { - // Check that we support iterators yielding const references. - const int x = 42; - const int* pX = &x; - auto moveIter = eastl::make_move_iterator(pX); - - constexpr bool isCorrectReferenceType = eastl::is_same_v<decltype(moveIter)::reference, const int&&>; - constexpr bool isCorrectReturnType = eastl::is_same_v<decltype(*moveIter), const int&&>; - - static_assert(isCorrectReferenceType, "move_iterator::reference has wrong type."); - static_assert(isCorrectReturnType, "move_iterator::operator*() has wrong return type."); - EATEST_VERIFY(isCorrectReferenceType); - EATEST_VERIFY(isCorrectReturnType); - - auto pCopiedX = *moveIter; - EATEST_VERIFY(pCopiedX == 42); - } - - { - // Check that we support iterators yielding plain value (typically a proxy-iterator). - struct FakeProxyIterator - { - using iterator_category = EASTL_ITC_NS::forward_iterator_tag; - using difference_type = ptrdiff_t; - using value_type = int; - using pointer = int; // Note that we are yielding by value. - using reference = int; // Note that we are yielding by value. - - reference operator*() const { return 42; } - pointer operator->() { return 42; } - FakeProxyIterator& operator++() { return *this; } - FakeProxyIterator operator++(int) { return {}; } - - bool operator==(const FakeProxyIterator& rhs) { return true; }; - bool operator!=(const FakeProxyIterator& rhs) { return false; }; - }; - - FakeProxyIterator it = {}; - auto moveIter = eastl::make_move_iterator(it); - - constexpr bool isCorrectReferenceType = eastl::is_same_v<decltype(moveIter)::reference, int>; - constexpr bool isCorrectReturnType = eastl::is_same_v<decltype(*moveIter), int>; - - static_assert(isCorrectReferenceType, "move_iterator::reference has wrong type."); - static_assert(isCorrectReturnType, "move_iterator::operator*() has wrong return type."); - EATEST_VERIFY(isCorrectReferenceType); - EATEST_VERIFY(isCorrectReturnType); - - auto pCopiedX = *moveIter; - EATEST_VERIFY(pCopiedX == 42); - } - - return nErrorCount; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// TestIterator -// -int TestIterator() -{ - int nErrorCount = 0; - nErrorCount += TestIterator_advance(); - nErrorCount += TestIterator_moveIterator(); - - { - // reverse_iterator - // reverse_iterator<Iterator> make_reverse_iterator(Iterator mi) - { - eastl::vector<int> src; - for(int i = 0; i < 10; i++) - src.push_back(i); // src should become {0,1,2,3,4,5,6,7,8,9} - - auto itr = eastl::make_reverse_iterator(src.end()); - EATEST_VERIFY(*itr == 9); ++itr; - EATEST_VERIFY(*itr == 8); ++itr; - EATEST_VERIFY(*itr == 7); ++itr; - EATEST_VERIFY(*itr == 6); ++itr; - EATEST_VERIFY(*itr == 5); ++itr; - EATEST_VERIFY(*itr == 4); ++itr; - EATEST_VERIFY(*itr == 3); ++itr; - EATEST_VERIFY(*itr == 2); ++itr; - EATEST_VERIFY(*itr == 1); ++itr; - EATEST_VERIFY(*itr == 0); ++itr; - EATEST_VERIFY( itr == src.rend()); - EATEST_VERIFY( itr == eastl::make_reverse_iterator(src.begin())); - } - } - - { - // Regression bug with assign/insert combined with reverse iterator. - eastl::vector<int> a; - for (int i = 0; i < 10; ++i) { - a.push_back(i); - } - - eastl::deque<int> d; - d.assign(a.rbegin(), a.rend()); - for (int i = 0; i < 10; ++i) { - EATEST_VERIFY(a[i] == d[a.size() - i - 1]); - } - d.insert(d.end(), a.rbegin(), a.rend()); - for (int i = 0; i < 10; ++i) { - EATEST_VERIFY(a[i] == d[d.size() - i - 1]); - } - - eastl::vector<int> b; - b.assign(a.rbegin(), a.rend()); - for (int i = 0; i < 10; ++i) { - EATEST_VERIFY(a[i] == b[a.size() - i - 1]); - } - b.insert(b.end(), a.rbegin(), a.rend()); - for (int i = 0; i < 10; ++i) { - EATEST_VERIFY(a[i] == b[b.size() - i - 1]); - } - } - - { - // move_iterator - // move_iterator<Iterator> make_move_iterator(Iterator mi) - typedef eastl::vector<eastl::string> StringArray; - - StringArray src; - for(eastl_size_t i = 0; i < 4; i++) - src.push_back(eastl::string(1, (char8_t)('0' + i))); // v should become {"0", "1", "2", "3"}; - - // Moves the values out of the string array and into the result. - StringArray dst(eastl::make_move_iterator(src.begin()), eastl::make_move_iterator(src.end())); - - EATEST_VERIFY((src.size() == 4) && (src[0] == "") && (src[3] == "")); - EATEST_VERIFY((dst.size() == 4) && (dst[0] == "0") && (dst[3] == "3")); - } - - { - // back_insert_iterator - // back_inserter - EA_CPP14_CONSTEXPR int n = 3; - eastl::vector<TestObject> v1, v2, v3; - v1.resize(n); v2.reserve(n); v3.reserve(n); - { - int64_t copyCtorCount0 = TestObject::sTOCopyCtorCount, moveCtorCount0 = TestObject::sTOMoveCtorCount; - eastl::copy(v1.begin(), v1.end(), eastl::back_inserter(v2)); - EATEST_VERIFY(v1.size() == v2.size() && TestObject::sTOCopyCtorCount == (copyCtorCount0 + n) && - TestObject::sTOMoveCtorCount == moveCtorCount0); - } - { - int64_t copyCtorCount0 = TestObject::sTOCopyCtorCount, moveCtorCount0 = TestObject::sTOMoveCtorCount; - eastl::move(v1.begin(), v1.end(), eastl::back_inserter(v3)); - EATEST_VERIFY(v1.size() == v3.size() && TestObject::sTOCopyCtorCount == copyCtorCount0 && - TestObject::sTOMoveCtorCount == (moveCtorCount0 + n)); - } - } - - { - // front_insert_iterator - // front_inserter - // To do. - } - - { - // insert_iterator - // inserter - // To do. - } - - { - // difference_type distance(InputIterator first, InputIterator last) - eastl::vector<int> intVector = {0, 1, 2, 3, 4, 5, 6, 7}; - EATEST_VERIFY(eastl::distance(intVector.begin(), intVector.end()) == 8); - } - - - { - #if EASTL_BEGIN_END_ENABLED - // begin / end - // auto inline begin(Container& container) -> decltype(container.begin()) - // auto inline end(Container& container) -> decltype(container.end()) - - eastl::vector<int> intVector; - eastl::vector<int>::iterator intVectorIterator = eastl::begin(intVector); - EATEST_VERIFY(intVectorIterator == eastl::end(intVector)); - - eastl::list<int> intList; - eastl::list<int>::iterator intListIterator = eastl::begin(intList); - EATEST_VERIFY(intListIterator == eastl::end(intList)); - - eastl::set<int> intSet; - eastl::set<int>::iterator intSetIterator = eastl::begin(intSet); - EATEST_VERIFY(intSetIterator == eastl::end(intSet)); - - eastl::array<int, 0> intArray; - eastl::array<int>::iterator intArrayIterator = eastl::begin(intArray); - EATEST_VERIFY(intArrayIterator == eastl::end(intArray)); - - eastl::intrusive_list<IListNode> intIList; - eastl::intrusive_list<IListNode>::iterator intIListIterator = eastl::begin(intIList); - EATEST_VERIFY(intIListIterator == eastl::end(intIList)); - - eastl::string8 str8; - eastl::string8::iterator string8Iterator = eastl::begin(str8); - EATEST_VERIFY(string8Iterator == eastl::end(str8)); - #endif - } - - // eastl::data - { - eastl::array<int, 0> intArray; - int* pIntArrayData = eastl::data(intArray); - EATEST_VERIFY(pIntArrayData == intArray.data()); - - eastl::vector<int> intVector; - int* pIntVectorData = eastl::data(intVector); - EATEST_VERIFY(pIntVectorData == intVector.data()); - - int intCArray[34]; - int* pIntCArray = eastl::data(intCArray); - EATEST_VERIFY(pIntCArray == intCArray); - - std::initializer_list<int> intInitList; - const int* pIntInitList = eastl::data(intInitList); - EATEST_VERIFY(pIntInitList == intInitList.begin()); - } - - // eastl::size - { - eastl::vector<int> intVector; - intVector.push_back(); - intVector.push_back(); - intVector.push_back(); - EATEST_VERIFY(eastl::size(intVector) == 3); - - int intCArray[34]; - EATEST_VERIFY(eastl::size(intCArray) == 34); - static_assert(eastl::size(intCArray) == 34, "eastl::size failure"); - } - - // eastl::ssize - { - eastl::vector<int> intVector; - intVector.push_back(); - intVector.push_back(); - intVector.push_back(); - EATEST_VERIFY(eastl::ssize(intVector) == (signed)3); - - int intCArray[34]; - EATEST_VERIFY(eastl::ssize(intCArray) == (signed)34); - static_assert(eastl::ssize(intCArray) == 34, "eastl::ssize failure"); - } - - // eastl::empty - { - eastl::vector<int> intVector; - EATEST_VERIFY(eastl::empty(intVector)); - intVector.push_back(); - EATEST_VERIFY(!eastl::empty(intVector)); - - std::initializer_list<int> intInitListEmpty; - EATEST_VERIFY(eastl::empty(intInitListEmpty)); - EATEST_VERIFY(!eastl::empty({1, 2, 3, 4, 5, 6})); - } - - // Range-based for loops - { - { - eastl::vector<int> v; - int I = 0; - - v.push_back(0); - v.push_back(1); - - for(int i : v) - EATEST_VERIFY(i == I++); - } - - { - eastl::string s8; - char C = 'a'; - - s8.push_back('a'); - s8.push_back('b'); - - for(char c : s8) - EATEST_VERIFY(c == C++); - } - } - - - { - // is_iterator_wrapper - static_assert((eastl::is_iterator_wrapper<void>::value == false), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<int>::value == false), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<int*>::value == false), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<eastl::array<int>::iterator>::value == false), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<eastl::array<char>*>::value == false), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<eastl::vector<char> >::value == false), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<eastl::generic_iterator<int*> >::value == true), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<eastl::move_iterator<eastl::array<int>::iterator> >::value == true), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<eastl::reverse_iterator<eastl::array<int>::iterator> >::value == false), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<eastl::reverse_iterator<int*> >::value == false), "is_iterator_wrapper failure"); - static_assert((eastl::is_iterator_wrapper<eastl::reverse_iterator<eastl::move_iterator<int*>> >::value == true), "is_iterator_wrapper failure"); - } - - - { - // unwrap_iterator - int intArray[2]; - int* pInt = eastl::unwrap_iterator(&intArray[0]); - intArray[0] = 17; - EATEST_VERIFY(*pInt == 17); - static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(&intArray[0])), int*>::value == true), "unwrap_iterator failure"); - - eastl::generic_iterator<int*> giIntArray(intArray); - pInt = eastl::unwrap_iterator(giIntArray); - intArray[0] = 18; - EATEST_VERIFY(*pInt == 18); - static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(giIntArray)), int*>::value == true), "unwrap_iterator failure"); - - eastl::vector<int> intVector(4, 19); - eastl::vector<int>::iterator itVector = eastl::unwrap_iterator(intVector.begin()); - EATEST_VERIFY(*itVector == 19); - static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(intVector.begin())), eastl::vector<int>::iterator>::value == true), "unwrap_iterator failure"); - - eastl::move_iterator<eastl::vector<int>::iterator> miIntVector(intVector.begin()); - itVector = eastl::unwrap_iterator(miIntVector); - intVector[0] = 20; - EATEST_VERIFY(*itVector == 20); - static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(miIntVector)), eastl::vector<int>::iterator>::value == true), "unwrap_iterator failure"); - - eastl::reverse_iterator<eastl::vector<int>::iterator> riIntVector = intVector.rbegin(); - eastl::reverse_iterator<eastl::vector<int>::iterator> riUnwrapped = eastl::unwrap_iterator(riIntVector); - EATEST_VERIFY(*riUnwrapped == 19); - static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(riIntVector)), eastl::reverse_iterator<eastl::vector<int>::iterator>>::value == true), "unwrap_iterator failure"); - - eastl::reverse_iterator<eastl::move_iterator<eastl::vector<int>::iterator>> rimiIntVec(miIntVector); - static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(rimiIntVec)), eastl::reverse_iterator<eastl::vector<int>::iterator>>::value == true), "unwrap_iterator failure"); - - eastl::reverse_iterator<eastl::generic_iterator<int*>> rigiIntArray(giIntArray); - static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(rigiIntArray)), eastl::reverse_iterator<int*>>::value == true), "unwrap_iterator failure"); - - eastl::deque<int> intDeque(3); - eastl::deque<int>::iterator begin = intDeque.begin(); - eastl::generic_iterator<eastl::deque<int>::iterator> giWrappedBegin(begin); - static_assert((eastl::is_same<decltype(eastl::unwrap_iterator(giWrappedBegin)), eastl::deque<int>::iterator>::value == true), "unwrap_iterator failure"); - - eastl::deque<int>::iterator unwrappedBegin = eastl::unwrap_iterator(giWrappedBegin); - EATEST_VERIFY(begin == unwrappedBegin); - } - - { - // unwrap_generic_iterator - int intArray[2] = {0, 1}; - eastl::generic_iterator<int*> giIntArray(intArray); - int* pInt = eastl::unwrap_generic_iterator(giIntArray); - EATEST_VERIFY(*pInt == 0); - static_assert((eastl::is_same<decltype(eastl::unwrap_generic_iterator(giIntArray)), int*>::value == true), "unwrap_iterator failure"); - - eastl::move_iterator<int*> miIntArray(intArray); - static_assert((eastl::is_same<decltype(eastl::unwrap_generic_iterator(miIntArray)), eastl::move_iterator<int*>>::value == true), "unwrap_iterator failure"); - - eastl::vector<int> intVector(1, 1); - eastl::generic_iterator<eastl::vector<int>::iterator> giVectorInt(intVector.begin()); - eastl::vector<int>::iterator it = unwrap_generic_iterator(giVectorInt); - EATEST_VERIFY(*it == 1); - static_assert((eastl::is_same<decltype(eastl::unwrap_generic_iterator(giVectorInt)), eastl::vector<int>::iterator>::value == true), "unwrap_iterator failure"); - } - - { - // unwrap_move_iterator - int intArray[2] = {0, 1}; - eastl::move_iterator<int*> miIntArray(intArray); - int* pInt = eastl::unwrap_move_iterator(miIntArray); - EATEST_VERIFY(*pInt == 0); - static_assert((eastl::is_same<decltype(eastl::unwrap_move_iterator(miIntArray)), int*>::value == true), "unwrap_iterator failure"); - - eastl::generic_iterator<int*> giIntArray(intArray); - static_assert((eastl::is_same<decltype(eastl::unwrap_move_iterator(giIntArray)), eastl::generic_iterator<int*>>::value == true), "unwrap_iterator failure"); - - eastl::vector<int> intVector(1, 1); - eastl::move_iterator<eastl::vector<int>::iterator> miVectorInt(intVector.begin()); - eastl::vector<int>::iterator it = unwrap_move_iterator(miVectorInt); - EATEST_VERIFY(*it == 1); - static_assert((eastl::is_same<decltype(eastl::unwrap_move_iterator(miVectorInt)), eastl::vector<int>::iterator>::value == true), "unwrap_iterator failure"); - } - - { - // array cbegin - cend - int arr[3]{ 1, 2, 3 }; - auto b = eastl::cbegin(arr); - auto e = eastl::cend(arr); - EATEST_VERIFY(*b == 1); - - auto dist = eastl::distance(b,e); - EATEST_VERIFY(dist == 3); - } - - { - // Regression test that ensure N3844 is working correctly. - static_assert(!eastl::is_detected<detect_iterator_traits_reference, int>::value, "detecting iterator_traits<int> should SFINAE gracefully."); - } - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestList.cpp b/test/source/TestList.cpp deleted file mode 100644 index 001b79a..0000000 --- a/test/source/TestList.cpp +++ /dev/null @@ -1,1090 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EASTL/list.h> -#include <EASTL/sort.h> -#include <EASTL/fixed_allocator.h> - -using namespace eastl; - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::list<bool>; -template class eastl::list<int>; -template class eastl::list<Align64>; -template class eastl::list<TestObject>; -// template class eastl::list<eastl::unique_ptr<int>>; - - -int TestList() -{ - int nErrorCount = 0; - - // list(); - { - eastl::list<int> l; - VERIFY(l.size() == 0); - VERIFY(l.empty()); - VERIFY(l.validate()); - VERIFY(l.begin() == l.end()); - } - - // list(const allocator_type& allocator); - { - MallocAllocator::reset_all(); - MallocAllocator mallocator; - { - eastl::list<int, MallocAllocator> l(mallocator); - VERIFY(l.get_allocator() == mallocator); - l.push_front(42); - VERIFY(MallocAllocator::mAllocCountAll != 0); - } - VERIFY(MallocAllocator::mAllocCountAll == MallocAllocator::mFreeCountAll); - } - - // explicit list(size_type n, const allocator_type& allocator = EASTL_LIST_DEFAULT_ALLOCATOR); - { - const int test_size = 42; - eastl::list<int> l(test_size); - VERIFY(!l.empty()); - VERIFY(l.size() == test_size); - VERIFY(l.validate()); - - VERIFY(eastl::all_of(l.begin(), l.end(), [](int e) - { return e == 0; })); - } - - // list(size_type n, const value_type& value, const allocator_type& allocator = EASTL_LIST_DEFAULT_ALLOCATOR); - { - const int test_size = 42; - const int test_val = 435; - - eastl::list<int> l(42, test_val); - VERIFY(!l.empty()); - VERIFY(l.size() == test_size); - VERIFY(l.validate()); - - VERIFY(eastl::all_of(l.begin(), l.end(), [=](int e) - { return e == test_val; })); - } - - // list(const this_type& x); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> b(a); - VERIFY(a == b); - VERIFY(a.validate()); - VERIFY(a.size() == b.size()); - VERIFY(b.validate()); - } - - // list(const this_type& x, const allocator_type& allocator); - { - MallocAllocator mallocator; - eastl::list<int, MallocAllocator> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int, MallocAllocator> b(a, mallocator); - VERIFY(a == b); - VERIFY(a.validate()); - VERIFY(a.size() == b.size()); - VERIFY(b.validate()); - VERIFY(a.get_allocator() == b.get_allocator()); - } - - // list(this_type&& x); - // list(this_type&&, const allocator_type&); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - VERIFY(!a.empty()); - VERIFY(a.size() == 10); - VERIFY(a.validate()); - - eastl::list<int> b(eastl::move(a)); - VERIFY(a.empty()); - VERIFY(!b.empty()); - VERIFY(a.size() == 0); - VERIFY(b.size() == 10); - - VERIFY(a != b); - VERIFY(a.size() != b.size()); - VERIFY(a.validate()); - VERIFY(b.validate()); - } - - // list(std::initializer_list<value_type> ilist, const allocator_type& allocator = EASTL_LIST_DEFAULT_ALLOCATOR); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::for_each(a.begin(), a.end(), [&](int e) - { - static int inc = 0; - VERIFY(inc++ == e); - }); - } - - // list(InputIterator first, InputIterator last); - { - eastl::list<int> ref = {3, 4, 5, 6, 7}; - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto start = a.begin(); - eastl::advance(start, 3); - - auto end = start; - eastl::advance(end, 5); - - eastl::list<int> b(start, end); - - VERIFY(b == ref); - VERIFY(a.validate()); - VERIFY(b.validate()); - - VERIFY(a.size() == 10); - VERIFY(b.size() == 5); - - VERIFY(!b.empty()); - VERIFY(!a.empty()); - } - - // this_type& operator=(const this_type& x); - // this_type& operator=(std::initializer_list<value_type> ilist); - // this_type& operator=(this_type&& x); - { - const eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> b = a; - VERIFY(a.validate()); - VERIFY(b.validate()); - VERIFY(a.size() == 10); - VERIFY(b.size() == 10); - VERIFY(!a.empty()); - VERIFY(!b.empty()); - VERIFY(b == a); - - eastl::list<int> c = eastl::move(b); - VERIFY(b.empty()); - - VERIFY(c == a); - VERIFY(c.size() == 10); - VERIFY(c.validate()); - } - - // void swap(this_type& x); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> b = {}; - - VERIFY(a.validate()); - VERIFY(b.validate()); - VERIFY(!a.empty()); - VERIFY(b.empty()); - - b.swap(a); - - VERIFY(a.validate()); - VERIFY(b.validate()); - VERIFY(a.empty()); - VERIFY(!b.empty()); - } - - // void assign(size_type n, const value_type& value); - { - eastl::list<int> ref = {42, 42, 42, 42}; - eastl::list<int> a = {0, 1, 2, 3}; - a.assign(4, 42); - VERIFY(a == ref); - VERIFY(a.validate()); - VERIFY(!a.empty()); - VERIFY(a.size() == 4); - } - - // void assign(InputIterator first, InputIterator last); - { - eastl::list<int> ref = eastl::list<int>{3, 4, 5, 6, 7}; - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> b; - - auto start = a.begin(); - eastl::advance(start, 3); - - auto end = start; - eastl::advance(end, 5); - - b.assign(start, end); - - VERIFY(b == ref); - VERIFY(a.validate()); - VERIFY(b.validate()); - - VERIFY(a.size() == 10); - VERIFY(b.size() == 5); - - VERIFY(!b.empty()); - VERIFY(!a.empty()); - } - - // void assign(std::initializer_list<value_type> ilist); - { - eastl::list<int> ref = eastl::list<int>{3, 4, 5, 6, 7}; - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> b; - - auto start = a.begin(); - eastl::advance(start, 3); - - auto end = start; - eastl::advance(end, 5); - - b.assign(start, end); - - VERIFY(b == ref); - VERIFY(a.validate()); - VERIFY(b.validate()); - - VERIFY(a.size() == 10); - VERIFY(b.size() == 5); - - VERIFY(!b.empty()); - VERIFY(!a.empty()); - } - - // iterator begin() - // const_iterator begin() const - // const_iterator cbegin() const - // iterator end() - // const_iterator end() const - // const_iterator cend() const - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - { - static int inc = 0; - auto iter = a.begin(); - while(iter != a.end()) - { - VERIFY(*iter++ == inc++); - } - } - - { - static int inc = 0; - auto iter = a.cbegin(); - while(iter != a.cend()) - { - VERIFY(*iter++ == inc++); - } - } - } - - // reverse_iterator rbegin() - // const_reverse_iterator rbegin() const - // const_reverse_iterator crbegin() const - // reverse_iterator rend() - // const_reverse_iterator rend() const - // const_reverse_iterator crend() const - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - { - static int inc = 9; - auto iter = a.rbegin(); - while(iter != a.rend()) - { - VERIFY(*iter == inc--); - iter++; - } - } - - { - static int inc = 9; - auto iter = a.crbegin(); - while(iter != a.crend()) - { - VERIFY(*iter == inc--); - iter++; - } - } - } - - // bool empty() const - { - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - VERIFY(!a.empty()); - } - - { - eastl::list<int> a = {}; - VERIFY(a.empty()); - } - } - - // size_type size() const - { - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - VERIFY(a.size() == 10); - } - - { - eastl::list<int> a = {0, 1, 2, 3, 4}; - VERIFY(a.size() == 5); - } - - { - eastl::list<int> a = {0, 1}; - VERIFY(a.size() == 2); - } - - { - eastl::list<int> a = {}; - VERIFY(a.size() == 0); - } - } - - // void resize(size_type n, const value_type& value); - // void resize(size_type n); - { - { - eastl::list<int> a; - a.resize(10); - VERIFY(a.size() == 10); - VERIFY(!a.empty()); - VERIFY(eastl::all_of(a.begin(), a.end(), [](int i) - { return i == 0; })); - } - - { - eastl::list<int> a; - a.resize(10, 42); - VERIFY(a.size() == 10); - VERIFY(!a.empty()); - VERIFY(eastl::all_of(a.begin(), a.end(), [](int i) - { return i == 42; })); - } - } - - // reference front(); - // const_reference front() const; - { - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - VERIFY(a.front() == 0); - - a.front() = 42; - VERIFY(a.front() == 42); - } - - { - const eastl::list<int> a = {5, 6, 7, 8, 9}; - VERIFY(a.front() == 5); - } - - { - eastl::list<int> a = {9}; - VERIFY(a.front() == 9); - - a.front() = 42; - VERIFY(a.front() == 42); - } - } - - // reference back(); - // const_reference back() const; - { - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - VERIFY(a.back() == 9); - - a.back() = 42; - VERIFY(a.back() == 42); - } - - { - const eastl::list<int> a = {5, 6, 7, 8, 9}; - VERIFY(a.back() == 9); - } - - { - eastl::list<int> a = {9}; - VERIFY(a.back() == 9); - - a.back() = 42; - VERIFY(a.back() == 42); - } - } - - // void emplace_front(Args&&... args); - // void emplace_front(value_type&& value); - // void emplace_front(const value_type& value); - { - eastl::list<int> ref = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; - eastl::list<int> a; - - for(int i = 0; i < 10; i++) - a.emplace_front(i); - - VERIFY(a == ref); - } - - // template <typename... Args> - // void emplace_back(Args&&... args); - // void emplace_back(value_type&& value); - // void emplace_back(const value_type& value); - { - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a; - - for(int i = 0; i < 10; i++) - a.emplace_back(i); - - VERIFY(a == ref); - } - - { - struct A - { - A() : mValue(0) {} - A(int in) : mValue(in) {} - int mValue; - bool operator==(const A& other) const { return mValue == other.mValue; } - }; - - { - eastl::list<A> ref = {{1}, {2}, {3}}; - eastl::list<A> a; - - a.emplace_back(1); - a.emplace_back(2); - a.emplace_back(3); - - VERIFY(a == ref); - } - - { - eastl::list<A> ref = {{1}, {2}, {3}}; - eastl::list<A> a; - - a.emplace_back(A(1)); - a.emplace_back(A(2)); - a.emplace_back(A(3)); - - VERIFY(a == ref); - } - - - { - eastl::list<A> ref = {{1}, {2}, {3}}; - eastl::list<A> a; - - A a1(1); - A a2(2); - A a3(3); - - a.emplace_back(a1); - a.emplace_back(a2); - a.emplace_back(a3); - - VERIFY(a == ref); - } - } - } - - // void push_front(const value_type& value); - // void push_front(value_type&& x); - // reference push_front(); - { - { - eastl::list<int> ref = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; - eastl::list<int> a; - - for(int i = 0; i < 10; i++) - a.push_front(i); - - VERIFY(a == ref); - - } - - { - eastl::list<int> a; - auto& front_ref = a.push_front(); - front_ref = 42; - VERIFY(a.front() == 42); - } - } - - // void* push_front_uninitialized(); - { - eastl::list<int> a; - for (unsigned i = 0; i < 100; i++) - { - VERIFY(a.push_front_uninitialized() != nullptr); - VERIFY(a.size() == (i + 1)); - } - } - - // void push_back(const value_type& value); - // void push_back(value_type&& x); - { - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a; - - for(int i = 0; i < 10; i++) - a.push_back(i); - - VERIFY(a == ref); - } - - { - struct A { int mValue; }; - eastl::list<A> a; - a.push_back(A{42}); - VERIFY(a.back().mValue == 42); - } - } - - // reference push_back(); - { - eastl::list<int> a; - auto& back_ref = a.push_back(); - back_ref = 42; - VERIFY(a.back() == 42); - } - - // void* push_back_uninitialized(); - { - eastl::list<int> a; - for (unsigned int i = 0; i < 100; i++) - { - VERIFY(a.push_back_uninitialized() != nullptr); - VERIFY(a.size() == (i + 1)); - } - } - - // void pop_front(); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - for(unsigned i = 0; i < 10; i++) - { - VERIFY(unsigned(a.front()) == i); - a.pop_front(); - } - } - - // void pop_back(); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - for(unsigned i = 0; i < 10; i++) - { - VERIFY(unsigned(a.back()) == (9 - i)); - a.pop_back(); - } - } - - // iterator emplace(const_iterator position, Args&&... args); - // iterator emplace(const_iterator position, value_type&& value); - // iterator emplace(const_iterator position, const value_type& value); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 42, 5, 6, 7, 8, 9}; - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto insert_pos = a.begin(); - eastl::advance(insert_pos, 5); - - a.emplace(insert_pos, 42); - VERIFY(a == ref); - } - - // iterator insert(const_iterator position); - // iterator insert(const_iterator position, const value_type& value); - // iterator insert(const_iterator position, value_type&& x); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 42, 5, 6, 7, 8, 9}; - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto insert_pos = a.begin(); - eastl::advance(insert_pos, 5); - - a.insert(insert_pos, 42); - VERIFY(a == ref); - } - - // void insert(const_iterator position, size_type n, const value_type& value); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 42, 42, 42, 42, 5, 6, 7, 8, 9}; - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto insert_pos = a.begin(); - eastl::advance(insert_pos, 5); - - auto result = a.insert(insert_pos, 4, 42); - VERIFY(a == ref); - VERIFY(*result == 42); - VERIFY(*(--result) == 4); - } - - // void insert(const_iterator position, InputIterator first, InputIterator last); - { - eastl::list<int> to_insert = {42, 42, 42, 42}; - eastl::list<int> ref = {0, 1, 2, 3, 4, 42, 42, 42, 42, 5, 6, 7, 8, 9}; - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto insert_pos = a.begin(); - eastl::advance(insert_pos, 5); - - auto result = a.insert(insert_pos, to_insert.begin(), to_insert.end()); - VERIFY(a == ref); - VERIFY(*result == 42); - VERIFY(*(--result) == 4); - } - - // iterator insert(const_iterator position, std::initializer_list<value_type> ilist); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 42, 42, 42, 42, 5, 6, 7, 8, 9}; - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto insert_pos = a.begin(); - eastl::advance(insert_pos, 5); - - a.insert(insert_pos, {42, 42, 42, 42}); - VERIFY(a == ref); - } - - // iterator erase(const_iterator position); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a = {0, 1, 2, 3, 4, 42, 5, 6, 7, 8, 9}; - - auto erase_pos = a.begin(); - eastl::advance(erase_pos, 5); - - auto iter_after_removed = a.erase(erase_pos); - VERIFY(*iter_after_removed == 5); - VERIFY(a == ref); - } - - // iterator erase(const_iterator first, const_iterator last); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 42, 42, 42, 42, 5, 6, 7, 8, 9}; - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto erase_begin = a.begin(); - eastl::advance(erase_begin, 5); - - auto erase_end = erase_begin; - eastl::advance(erase_end, 4); - - a.erase(erase_begin, erase_end); - VERIFY(a == ref); - } - - // reverse_iterator erase(const_reverse_iterator position); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 42, 5, 6, 7, 8, 9}; - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto erase_rbegin = a.rbegin(); - eastl::advance(erase_rbegin, 5); - - auto iter_after_remove = a.erase(erase_rbegin); - VERIFY(*iter_after_remove == 4); - VERIFY(a == ref); - - } - - // reverse_iterator erase(const_reverse_iterator first, const_reverse_iterator last); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 42, 42, 42, 42, 5, 6, 7, 8, 9}; - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto erase_crbegin = a.crbegin(); - auto erase_crend = a.crbegin(); - eastl::advance(erase_crbegin, 4); - eastl::advance(erase_crend, 8); - - auto iter_after_removed = a.erase(erase_crbegin, erase_crend); - VERIFY(*iter_after_removed == 4); - VERIFY(a == ref); - } - - // void clear() - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - a.clear(); - VERIFY(a.empty()); - VERIFY(a.size() == 0); - } - - // void reset_lose_memory() - { - typedef eastl::list<int, fixed_allocator> IntList; - typedef IntList::node_type IntListNode; - const size_t kBufferCount = 10; - IntListNode buffer1[kBufferCount]; - IntList intList1; - const size_t kAlignOfIntListNode = EA_ALIGN_OF(IntListNode); - intList1.get_allocator().init(buffer1, sizeof(buffer1), sizeof(IntListNode), kAlignOfIntListNode); - - intList1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - VERIFY(!intList1.empty()); - VERIFY(intList1.size() == 10); - intList1.reset_lose_memory(); - VERIFY(intList1.empty()); - VERIFY(intList1.size() == 0); - } - - // void remove(const T& x); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> ref = {0, 1, 2, 3, 5, 6, 7, 8, 9}; - a.remove(4); - VERIFY(a == ref); - } - - // void remove_if(Predicate); - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> ref = {0, 1, 2, 3, 5, 6, 7, 8, 9}; - a.remove_if([](int e) { return e == 4; }); - VERIFY(a == ref); - } - - // void reverse() - { - eastl::list<int> a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> ref = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; - a.reverse(); - VERIFY(a == ref); - } - - // void splice(const_iterator position, this_type& x); - { - const eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a1 = {0, 1, 2, 3, 4}; - eastl::list<int> a2 = {5, 6, 7, 8, 9}; - - eastl::list<int> a; - a.splice(a.begin(), a2); - a.splice(a.begin(), a1); - - VERIFY(a == ref); - VERIFY(a1.empty()); - VERIFY(a2.empty()); - } - - // void splice(const_iterator position, this_type& x, const_iterator i); - { - const eastl::list<int> ref = {0, 5}; - eastl::list<int> a1 = {-1, -1, 0}; - eastl::list<int> a2 = {-1, -1, 5}; - - auto a1_begin = a1.begin(); - auto a2_begin = a2.begin(); - - eastl::advance(a1_begin, 2); - eastl::advance(a2_begin, 2); - - eastl::list<int> a; - a.splice(a.begin(), a2, a2_begin); - a.splice(a.begin(), a1, a1_begin); - - VERIFY(a == ref); - VERIFY(!a1.empty()); - VERIFY(!a2.empty()); - } - - // void splice(const_iterator position, this_type& x, const_iterator first, const_iterator last); - { - const eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a1 = {-1, -1, 0, 1, 2, 3, 4, -1, -1}; - eastl::list<int> a2 = {-1, -1, 5, 6, 7, 8, 9, -1, -1}; - - auto a1_begin = a1.begin(); - auto a2_begin = a2.begin(); - auto a1_end = a1.end(); - auto a2_end = a2.end(); - - eastl::advance(a1_begin, 2); - eastl::advance(a2_begin, 2); - eastl::advance(a1_end, -2); - eastl::advance(a2_end, -2); - - eastl::list<int> a; - a.splice(a.begin(), a2, a2_begin, a2_end); - a.splice(a.begin(), a1, a1_begin, a1_end); - - const eastl::list<int> rref = {-1, -1, -1, -1}; // post splice reference list - VERIFY(a == ref); - VERIFY(a1 == rref); - VERIFY(a2 == rref); - } - - // void splice(const_iterator position, this_type&& x); - { - const eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a1 = {0, 1, 2, 3, 4}; - eastl::list<int> a2 = {5, 6, 7, 8, 9}; - - eastl::list<int> a; - a.splice(a.begin(), eastl::move(a2)); - a.splice(a.begin(), eastl::move(a1)); - - VERIFY(a == ref); - VERIFY(a1.empty()); - VERIFY(a2.empty()); - } - - // void splice(const_iterator position, this_type&& x, const_iterator i); - { - const eastl::list<int> ref = {0, 5}; - eastl::list<int> a1 = {-1, -1, 0}; - eastl::list<int> a2 = {-1, -1, 5}; - - auto a1_begin = a1.begin(); - auto a2_begin = a2.begin(); - - eastl::advance(a1_begin, 2); - eastl::advance(a2_begin, 2); - - eastl::list<int> a; - a.splice(a.begin(), eastl::move(a2), a2_begin); - a.splice(a.begin(), eastl::move(a1), a1_begin); - - VERIFY(a == ref); - VERIFY(!a1.empty()); - VERIFY(!a2.empty()); - } - - // void splice(const_iterator position, this_type&& x, const_iterator first, const_iterator last); - { - const eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a1 = {-1, -1, 0, 1, 2, 3, 4, -1, -1}; - eastl::list<int> a2 = {-1, -1, 5, 6, 7, 8, 9, -1, -1}; - - auto a1_begin = a1.begin(); - auto a2_begin = a2.begin(); - auto a1_end = a1.end(); - auto a2_end = a2.end(); - - eastl::advance(a1_begin, 2); - eastl::advance(a2_begin, 2); - eastl::advance(a1_end, -2); - eastl::advance(a2_end, -2); - - eastl::list<int> a; - a.splice(a.begin(), eastl::move(a2), a2_begin, a2_end); - a.splice(a.begin(), eastl::move(a1), a1_begin, a1_end); - - const eastl::list<int> rref = {-1, -1, -1, -1}; // post splice reference list - VERIFY(a == ref); - VERIFY(a1 == rref); - VERIFY(a2 == rref); - } - - - // void merge(this_type& x); - // void merge(this_type&& x); - // void merge(this_type& x, Compare compare); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a1 = {0, 1, 2, 3, 4}; - eastl::list<int> a2 = {5, 6, 7, 8, 9}; - a1.merge(a2); - VERIFY(a1 == ref); - } - - // void merge(this_type&& x, Compare compare); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a1 = {0, 1, 2, 3, 4}; - eastl::list<int> a2 = {5, 6, 7, 8, 9}; - a1.merge(a2, [](int lhs, int rhs) { return lhs < rhs; }); - VERIFY(a1 == ref); - } - - // void unique(); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9}; - a.unique(); - VERIFY(a == ref); - } - - // void unique(BinaryPredicate); - { - static bool bBreakComparison; - struct A - { - int mValue; - bool operator==(const A& other) const { return bBreakComparison ? false : mValue == other.mValue; } - }; - - eastl::list<A> ref = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}}; - eastl::list<A> a = {{0}, {0}, {0}, {0}, {0}, {0}, {1}, {2}, {2}, {2}, {2}, {3}, {4}, {5}, - {5}, {5}, {5}, {5}, {6}, {7}, {7}, {7}, {7}, {8}, {9}, {9}, {9}}; - - bBreakComparison = true; - a.unique(); // noop because broken comparison operator - VERIFY(a != ref); - - a.unique([](const A& lhs, const A& rhs) { return lhs.mValue == rhs.mValue; }); - - bBreakComparison = false; - VERIFY(a == ref); - } - - // void sort(); - { - eastl::list<int> ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> a = {9, 4, 5, 3, 1, 0, 6, 2, 7, 8}; - - a.sort(); - VERIFY(a == ref); - } - - // void sort(Compare compare); - { - struct A - { - int mValue; - bool operator==(const A& other) const { return mValue == other.mValue; } - }; - - eastl::list<A> ref = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}}; - eastl::list<A> a = {{1}, {0}, {2}, {9}, {4}, {5}, {6}, {7}, {3}, {8}}; - - a.sort([](const A& lhs, const A& rhs) { return lhs.mValue < rhs.mValue; }); - VERIFY(a == ref); - } - - { // Test empty base-class optimization - struct UnemptyDummyAllocator : eastl::dummy_allocator - { - int foo; - }; - - typedef eastl::list<int, eastl::dummy_allocator> list1; - typedef eastl::list<int, UnemptyDummyAllocator> list2; - - EATEST_VERIFY(sizeof(list1) < sizeof(list2)); - } - - { // Test erase / erase_if - { - eastl::list<int> l = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto numErased = eastl::erase(l, 3); - VERIFY(numErased == 1); - numErased = eastl::erase(l, 5); - VERIFY(numErased == 1); - numErased = eastl::erase(l, 7); - VERIFY(numErased == 1); - - VERIFY((l == eastl::list<int>{1, 2, 4, 6, 8, 9})); - } - - { - eastl::list<int> l = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - auto numErased = eastl::erase_if(l, [](auto i) { return i % 2 == 0; }); - VERIFY((l == eastl::list<int>{1, 3, 5, 7, 9})); - VERIFY(numErased == 4); - } - } - - { // Test global operators - { - eastl::list<int> list1 = {0, 1, 2, 3, 4, 5}; - eastl::list<int> list2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> list3 = {5, 6, 7, 8}; - - VERIFY(list1 == list1); - VERIFY(!(list1 != list1)); - - VERIFY(list1 != list2); - VERIFY(list2 != list3); - VERIFY(list1 != list3); - - VERIFY(list1 < list2); - VERIFY(list1 <= list2); - - VERIFY(list2 > list1); - VERIFY(list2 >= list1); - - VERIFY(list3 > list1); - VERIFY(list3 > list2); - } - - // three way comparison operator -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - eastl::list<int> list1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - eastl::list<int> list2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - // Verify equality between list1 and list2 - VERIFY((list1 <=> list2) == 0); - VERIFY(!((list1 <=> list2) != 0)); - VERIFY((list1 <=> list2) <= 0); - VERIFY((list1 <=> list2) >= 0); - VERIFY(!((list1 <=> list2) < 0)); - VERIFY(!((list1 <=> list2) > 0)); - - list1.push_back(100); // Make list1 less than list2. - list2.push_back(101); - - // Verify list1 < list2 - VERIFY(!((list1 <=> list2) == 0)); - VERIFY((list1 <=> list2) != 0); - VERIFY((list1 <=> list2) <= 0); - VERIFY(!((list1 <=> list2) >= 0)); - VERIFY(((list1 <=> list2) < 0)); - VERIFY(!((list1 <=> list2) > 0)); - - for (int i = 0; i < 3; i++) // Make the length of list2 less than list1 - list2.pop_back(); - - // Verify list2.size() < list1.size() and list2 is a subset of list1 - VERIFY(!((list1 <=> list2) == 0)); - VERIFY((list1 <=> list2) != 0); - VERIFY((list1 <=> list2) >= 0); - VERIFY(!((list1 <=> list2) <= 0)); - VERIFY(((list1 <=> list2) > 0)); - VERIFY(!((list1 <=> list2) < 0)); - } - - { - eastl::list<int> list1 = {1, 2, 3, 4, 5, 6, 7}; - eastl::list<int> list2 = {7, 6, 5, 4, 3, 2, 1}; - eastl::list<int> list3 = {1, 2, 3, 4}; - - struct weak_ordering_list - { - eastl::list<int> list; - inline std::weak_ordering operator<=>(const weak_ordering_list& b) const { return list <=> b.list; } - }; - - VERIFY(synth_three_way{}(weak_ordering_list{list1}, weak_ordering_list{list2}) == std::weak_ordering::less); - VERIFY(synth_three_way{}(weak_ordering_list{list3}, weak_ordering_list{list1}) == std::weak_ordering::less); - VERIFY(synth_three_way{}(weak_ordering_list{list2}, weak_ordering_list{list1}) == std::weak_ordering::greater); - VERIFY(synth_three_way{}(weak_ordering_list{list2}, weak_ordering_list{list3}) == std::weak_ordering::greater); - VERIFY(synth_three_way{}(weak_ordering_list{list1}, weak_ordering_list{list1}) == std::weak_ordering::equivalent); - - struct strong_ordering_list - { - eastl::list<int> list; - inline std::strong_ordering operator<=>(const strong_ordering_list& b) const { return list <=> b.list; } - }; - - VERIFY(synth_three_way{}(strong_ordering_list{list1}, strong_ordering_list{list2}) == std::strong_ordering::less); - VERIFY(synth_three_way{}(strong_ordering_list{list3}, strong_ordering_list{list1}) == std::strong_ordering::less); - VERIFY(synth_three_way{}(strong_ordering_list{list2}, strong_ordering_list{list1}) == std::strong_ordering::greater); - VERIFY(synth_three_way{}(strong_ordering_list{list2}, strong_ordering_list{list3}) == std::strong_ordering::greater); - VERIFY(synth_three_way{}(strong_ordering_list{list1}, strong_ordering_list{list1}) == std::strong_ordering::equal); - } -#endif - } - return nErrorCount; -} - - diff --git a/test/source/TestListMap.cpp b/test/source/TestListMap.cpp deleted file mode 100644 index 3d48133..0000000 --- a/test/source/TestListMap.cpp +++ /dev/null @@ -1,222 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/utility.h> -#include <EASTL/bonus/list_map.h> - - -#ifdef _MSC_VER - #pragma warning(push, 0) -#endif - -#include <stdio.h> - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - - -// We would like to use the generic EASTLTest VerifySequence function, but it's not currently ready to deal -// with non-POD types. That can probably be solved, but in the meantime we implement a custom function here. -template <typename T1, typename T2> -bool VerifyListMapSequence(const char* pName, - eastl::list_map<T1, T2>& listMap, - T1 t1End, T2, - T1 t10 = 0, T2 t20 = 0, - T1 t11 = 0, T2 t21 = 0, - T1 t12 = 0, T2 t22 = 0, - T1 t13 = 0, T2 t23 = 0, - T1 t14 = 0, T2 t24 = 0, - T1 t15 = 0, T2 t25 = 0) -{ - typename eastl::list_map<T1, T2>::iterator it = listMap.begin(); - - if(t10 == t1End) - return (it == listMap.end()); - if(it->first != t10 || it->second != t20) - { EASTLTest_Printf("[%s] Mismatch at index %d\n", pName, 0); return false; } - ++it; - - if(t11 == t1End) - return (it == listMap.end()); - if(it->first != t11 || it->second != t21) - { EASTLTest_Printf("[%s] Mismatch at index %d\n", pName, 1); return false; } - ++it; - - if(t12 == t1End) - return (it == listMap.end()); - if(it->first != t12 || it->second != t22) - { EASTLTest_Printf("[%s] Mismatch at index %d\n", pName, 2); return false; } - ++it; - - if(t13 == t1End) - return (it == listMap.end()); - if(it->first != t13 || it->second != t23) - { EASTLTest_Printf("[%s] Mismatch at index %d\n", pName, 3); return false; } - ++it; - - if(t14 == t1End) - return (it == listMap.end()); - if(it->first != t14 || it->second != t24) - { EASTLTest_Printf("[%s] Mismatch at index %d\n", pName, 4); return false; } - ++it; - - if(t15 == t1End) - return (it == listMap.end()); - if(it->first != t15 || it->second != t25) - { EASTLTest_Printf("[%s] Mismatch at index %d\n", pName, 5); return false; } - ++it; - - return true; -} - - -int TestListMap() -{ - int nErrorCount = 0; - - { - typedef eastl::list_map<uint32_t, uint64_t> TestMapType; - typedef eastl::pair<uint32_t, uint64_t> ValueType; // We currently can't use TestMapType::value_type because its 'first' is const. - - TestMapType testMap; - TestMapType::iterator iter; - TestMapType::const_iterator c_iter; - TestMapType::reverse_iterator rIter; - TestMapType::const_reverse_iterator c_rIter; - TestMapType::iterator tempIter; - - EATEST_VERIFY(testMap.empty()); - EATEST_VERIFY(testMap.validate()); - - testMap.push_front(ValueType(3, 1003)); - EATEST_VERIFY(testMap.validate()); - - testMap.push_back(ValueType(4, 1004)); - EATEST_VERIFY(testMap.validate()); - - testMap.push_back(ValueType(2, 1002)); - EATEST_VERIFY(testMap.validate()); - - testMap.push_front(ValueType(6, 1006)); - EATEST_VERIFY(testMap.validate()); - - EATEST_VERIFY(!testMap.empty()); - EATEST_VERIFY(testMap.size() == 4); - - EATEST_VERIFY(testMap.find(3) != testMap.end()); - EATEST_VERIFY(testMap.find(5) == testMap.end()); - EATEST_VERIFY((VerifyListMapSequence<uint32_t, uint64_t>("list_map::push_back", testMap, UINT32_MAX, 0, 6, 1006, 3, 1003, 4, 1004, 2, 1002, UINT32_MAX, 0))); - - iter = testMap.find(3); - EATEST_VERIFY((iter->first == 3) && ((++iter)->first == 4) && ((++iter)->first == 2)); - - rIter = testMap.rbegin(); - EATEST_VERIFY((rIter->first == 2) && ((++rIter)->first == 4) && ((++rIter)->first == 3) && ((++rIter)->first == 6)); - - TestMapType::const_reference rFront = testMap.front(); - EATEST_VERIFY(rFront.first == 6); - - TestMapType::reference rBack = testMap.back(); - EATEST_VERIFY(rBack.first == 2); - - testMap.clear(); - EATEST_VERIFY(testMap.empty()); - EATEST_VERIFY(testMap.validate()); - - iter = testMap.begin(); - EATEST_VERIFY(iter == testMap.end()); - - testMap.push_back(ValueType(10, 1010)); - EATEST_VERIFY(testMap.validate()); - - testMap.push_front(ValueType(8, 1008)); - EATEST_VERIFY(testMap.validate()); - - testMap.push_back(7, 1007); - EATEST_VERIFY(testMap.validate()); - - testMap.push_front(9, 1009); - EATEST_VERIFY(testMap.validate()); - - testMap.push_back(11, 1011LL); - EATEST_VERIFY(testMap.validate()); - - EATEST_VERIFY((VerifyListMapSequence<uint32_t, uint64_t>("list_map::push_back", testMap, UINT32_MAX, 0, 9, 1009, 8, 1008, 10, 1010, 7, 1007, 11, 1011, UINT32_MAX, 0))); - - testMap.pop_front(); - EATEST_VERIFY(testMap.validate()); - EATEST_VERIFY((VerifyListMapSequence<uint32_t, uint64_t>("list_map::push_back", testMap, UINT32_MAX, 0, 8, 1008, 10, 1010, 7, 1007, 11, 1011, UINT32_MAX, 0))); - - rIter = testMap.rbegin(); - EATEST_VERIFY((rIter->first == 11 && ((++rIter)->first == 7) && ((++rIter)->first == 10) && ((++rIter)->first == 8))); - - testMap.pop_back(); - EATEST_VERIFY(testMap.validate()); - EATEST_VERIFY((VerifyListMapSequence<uint32_t, uint64_t>("list_map::push_back", testMap, UINT32_MAX, 0, 8, 1008, 10, 1010, 7, 1007, UINT32_MAX, 0))); - - rIter = testMap.rbegin(); - EATEST_VERIFY(((rIter)->first == 7) && ((++rIter)->first == 10) && ((++rIter)->first == 8)); - - tempIter = testMap.find(10); - EATEST_VERIFY(tempIter != testMap.end()); - - testMap.erase(10); - EATEST_VERIFY(testMap.validate()); - EATEST_VERIFY((VerifyListMapSequence<uint32_t, uint64_t>("list_map::push_back", testMap, UINT32_MAX, 0, 8, 1008, 7, 1007, UINT32_MAX, 0))); - - EATEST_VERIFY(testMap.validate_iterator(testMap.find(8)) == (eastl::isf_valid | eastl::isf_current | eastl::isf_can_dereference)); - EATEST_VERIFY(testMap.validate_iterator(testMap.find(30)) == (eastl::isf_valid | eastl::isf_current)); - EATEST_VERIFY(testMap.validate_iterator(tempIter) == eastl::isf_none); - EATEST_VERIFY(testMap.validate()); - - testMap.erase(20); // erasing an index not in use should still be safe - EATEST_VERIFY(testMap.validate()); - EATEST_VERIFY((VerifyListMapSequence<uint32_t, uint64_t>("list_map::push_back", testMap, UINT32_MAX, 0, 8, 1008, 7, 1007, UINT32_MAX, 0))); - - EATEST_VERIFY(testMap.count(7) == 1); - EATEST_VERIFY(testMap.count(10) == 0); - EATEST_VERIFY(testMap.validate()); - - testMap.erase(testMap.find(8)); - EATEST_VERIFY(testMap.validate()); - EATEST_VERIFY((VerifyListMapSequence<uint32_t, uint64_t>("list_map::push_back", testMap, UINT32_MAX, 0, 7, 1007, UINT32_MAX, 0))); - - testMap.erase(testMap.rbegin()); - EATEST_VERIFY(testMap.empty()); - EATEST_VERIFY(testMap.validate()); - } - - { - typedef eastl::list_map<eastl::string, uint32_t> TestStringMapType; - TestStringMapType testStringMap; - TestStringMapType::iterator strIter; - - testStringMap.push_back(eastl::string("hello"), 750); - EATEST_VERIFY(testStringMap.size() == 1); - - strIter = testStringMap.find_as("hello", eastl::less_2<eastl::string, const char*>()); - EATEST_VERIFY(strIter != testStringMap.end()); - EATEST_VERIFY(strIter->first == "hello"); - EATEST_VERIFY(strIter->second == 750); - - strIter = testStringMap.find_as("fake_string", eastl::less_2<eastl::string, const char*>()); - EATEST_VERIFY(strIter == testStringMap.end()); - EATEST_VERIFY(testStringMap.validate()); - } - - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestLruCache.cpp b/test/source/TestLruCache.cpp deleted file mode 100644 index e659218..0000000 --- a/test/source/TestLruCache.cpp +++ /dev/null @@ -1,340 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EASTL/bonus/lru_cache.h> -#include <EASTL/unique_ptr.h> - -namespace TestLruCacheInternal -{ - struct Foo - { - static int count; - - Foo() - : a(count++) - , b(count++) - { } - - Foo(int x, int y) : a(x), b(y) {} - - int a; - int b; - - bool operator==(const Foo &other) - { - return this->a == other.a && this->b == other.b; - } - }; - - int Foo::count = 0; - - class FooCreator - { - public: - FooCreator() : mFooCreatedCount(0) {} - - Foo *Create() - { - mFooCreatedCount++; - return new Foo(); - } - - void Destroy(Foo *f) - { - delete f; - mFooCreatedCount--; - } - - int mFooCreatedCount; - }; -} - - -int TestLruCache() -{ - int nErrorCount = 0; - - // Test simple situation - { - using namespace TestLruCacheInternal; - - eastl::lru_cache<int, Foo> lruCache(3); - - // Empty state - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.size() == 0); - EATEST_VERIFY(lruCache.empty() == true); - EATEST_VERIFY(lruCache.capacity() == 3); - EATEST_VERIFY(lruCache.at(1).has_value() == false); - - // Auto create with get call - EATEST_VERIFY(lruCache[0].a == 0); - EATEST_VERIFY(lruCache[0].b == 1); - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.contains(0) == true); - EATEST_VERIFY(lruCache.size() == 1); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - - // Fill structure up to 2 more entries to fill out, also test at() - lruCache.insert(1, Foo(2, 3)); - EATEST_VERIFY(lruCache.at(1).value().a == 2); - EATEST_VERIFY(lruCache.at(1).value().b == 3); - EATEST_VERIFY(lruCache.contains(0) == true); - EATEST_VERIFY(lruCache.contains(1) == true); - EATEST_VERIFY(lruCache.contains(2) == false); - EATEST_VERIFY(lruCache.contains(3) == false); - EATEST_VERIFY(lruCache.size() == 2); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - - lruCache.insert(2, Foo(4, 5)); - EATEST_VERIFY(lruCache[2].a == 4); - EATEST_VERIFY(lruCache[2].b == 5); - EATEST_VERIFY(lruCache.contains(0) == true); - EATEST_VERIFY(lruCache.contains(1) == true); - EATEST_VERIFY(lruCache.contains(2) == true); - EATEST_VERIFY(lruCache.contains(3) == false); - EATEST_VERIFY(lruCache.size() == 3); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - - // Add another entry, at this point 0 is the oldest, so it should be pulled - lruCache.insert(3, Foo(6, 7)); - EATEST_VERIFY(lruCache[3].a == 6); - EATEST_VERIFY(lruCache[3].b == 7); - EATEST_VERIFY(lruCache.contains(0) == false); - EATEST_VERIFY(lruCache.contains(1) == true); - EATEST_VERIFY(lruCache.contains(2) == true); - EATEST_VERIFY(lruCache.contains(3) == true); - EATEST_VERIFY(lruCache.size() == 3); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - - // Touch the now oldest 1 key - EATEST_VERIFY(lruCache.touch(1) == true); - - // Add another entry, this will be #4 but since 1 was touched, 2 is now the oldest - lruCache.insert(4, Foo(8, 9)); - EATEST_VERIFY(lruCache[4].a == 8); - EATEST_VERIFY(lruCache[4].b == 9); - EATEST_VERIFY(lruCache.contains(0) == false); - EATEST_VERIFY(lruCache.contains(1) == true); - EATEST_VERIFY(lruCache.contains(2) == false); - EATEST_VERIFY(lruCache.contains(3) == true); - EATEST_VERIFY(lruCache.contains(4) == true); - EATEST_VERIFY(lruCache.size() == 3); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - - // Test resize down - EATEST_VERIFY(lruCache.touch(3) == true); // Let's make some key in the middle the most recent - lruCache.resize(1); // Resize down to 1 entry in the cache - EATEST_VERIFY(lruCache.contains(0) == false); - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.contains(2) == false); - EATEST_VERIFY(lruCache.contains(3) == true); - EATEST_VERIFY(lruCache.contains(4) == false); - EATEST_VERIFY(lruCache.size() == 1); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 1); - - // Let's resize up to a size of 5 now - lruCache.resize(5); - EATEST_VERIFY(lruCache.contains(0) == false); - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.contains(2) == false); - EATEST_VERIFY(lruCache.contains(3) == true); - EATEST_VERIFY(lruCache.contains(4) == false); - EATEST_VERIFY(lruCache.size() == 1); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 5); - - // Let's try updating - lruCache.assign(3, Foo(0, 0)); - EATEST_VERIFY(lruCache[3] == Foo(0, 0)); - EATEST_VERIFY(lruCache.contains(0) == false); - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.contains(2) == false); - EATEST_VERIFY(lruCache.contains(3) == true); - EATEST_VERIFY(lruCache.contains(4) == false); - EATEST_VERIFY(lruCache.size() == 1); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 5); - - // add or update existing - lruCache.insert_or_assign(3, Foo(1, 1)); - EATEST_VERIFY(lruCache[3] == Foo(1, 1)); - EATEST_VERIFY(lruCache.contains(0) == false); - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.contains(2) == false); - EATEST_VERIFY(lruCache.contains(3) == true); - EATEST_VERIFY(lruCache.contains(4) == false); - EATEST_VERIFY(lruCache.size() == 1); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 5); - - // Add or update a new entry - lruCache.insert_or_assign(25, Foo(2, 2)); - EATEST_VERIFY(lruCache[3] == Foo(1, 1)); - EATEST_VERIFY(lruCache[25] == Foo(2, 2)); - EATEST_VERIFY(lruCache.contains(0) == false); - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.contains(2) == false); - EATEST_VERIFY(lruCache.contains(3) == true); - EATEST_VERIFY(lruCache.contains(4) == false); - EATEST_VERIFY(lruCache.contains(25) == true); - EATEST_VERIFY(lruCache.size() == 2); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 5); - - // clear everything - lruCache.clear(); - EATEST_VERIFY(lruCache.size() == 0); - EATEST_VERIFY(lruCache.empty() == true); - EATEST_VERIFY(lruCache.capacity() == 5); - EATEST_VERIFY(lruCache.contains(3) == false); - - // test unilateral reset - lruCache[1] = Foo(1, 2); - lruCache.reset_lose_memory(); - EATEST_VERIFY(lruCache.size() == 0); - } - - // Test more advanced creation / deletion via callbacks - { - using namespace TestLruCacheInternal; - - FooCreator fooCreator; - - auto createCallback = [&fooCreator](int) { return fooCreator.Create(); }; - auto deleteCallback = [&fooCreator](Foo *f) { fooCreator.Destroy(f); }; - - eastl::lru_cache<int, Foo*> lruCache(3, EASTLAllocatorType("eastl lru_cache"), createCallback, deleteCallback); - - lruCache[1]; - EATEST_VERIFY(fooCreator.mFooCreatedCount == 1); - EATEST_VERIFY(lruCache.size() == 1); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - EATEST_VERIFY(lruCache.contains(1) == true); - EATEST_VERIFY(lruCache.contains(2) == false); - - lruCache[2]; - EATEST_VERIFY(fooCreator.mFooCreatedCount == 2); - EATEST_VERIFY(lruCache.size() == 2); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - EATEST_VERIFY(lruCache.contains(1) == true); - EATEST_VERIFY(lruCache.contains(2) == true); - - // Update 2, which should delete the existing entry - { - auto f = fooCreator.Create(); - EATEST_VERIFY(fooCreator.mFooCreatedCount == 3); - f->a = 20; - f->b = 21; - lruCache.assign(2, f); - EATEST_VERIFY(fooCreator.mFooCreatedCount == 2); - EATEST_VERIFY(lruCache.size() == 2); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - EATEST_VERIFY(lruCache.contains(1) == true); - EATEST_VERIFY(lruCache.contains(2) == true); - EATEST_VERIFY(lruCache[2]->a == 20); - EATEST_VERIFY(lruCache[2]->b == 21); - } - - lruCache.erase(2); - EATEST_VERIFY(fooCreator.mFooCreatedCount == 1); - EATEST_VERIFY(lruCache.size() == 1); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - EATEST_VERIFY(lruCache.contains(1) == true); - EATEST_VERIFY(lruCache.contains(2) == false); - - lruCache.erase(1); - EATEST_VERIFY(fooCreator.mFooCreatedCount == 0); - EATEST_VERIFY(lruCache.size() == 0); - EATEST_VERIFY(lruCache.empty() == true); - EATEST_VERIFY(lruCache.capacity() == 3); - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.contains(2) == false); - - // Test insert_or_assign - { - auto f = fooCreator.Create(); - f->a = 22; - f->b = 30; - EATEST_VERIFY(fooCreator.mFooCreatedCount == 1); - - lruCache.insert_or_assign(7, f); - EATEST_VERIFY(lruCache.size() == 1); - EATEST_VERIFY(lruCache.empty() == false); - EATEST_VERIFY(lruCache.capacity() == 3); - EATEST_VERIFY(lruCache.contains(1) == false); - EATEST_VERIFY(lruCache.contains(2) == false); - EATEST_VERIFY(lruCache.contains(7) == true); - EATEST_VERIFY(lruCache.erase(7) == true); - EATEST_VERIFY(fooCreator.mFooCreatedCount == 0); - } - } - - // Test iteration - { - eastl::lru_cache<int, int> lc(5); - lc.insert_or_assign(0,10); - lc.insert_or_assign(1,11); - lc.insert_or_assign(2,12); - lc.insert_or_assign(3,13); - lc.insert_or_assign(4,14); - - { // test manual for-loop - int i = 0; - for (auto b = lc.begin(), e = lc.end(); b != e; b++) - { - auto &p = *b; - VERIFY(i == p.first); - VERIFY(i + 10 == p.second.first); - i++; - } - } - - { // test pairs - int i = 0; - for(auto& p : lc) - { - VERIFY(i == p.first); - VERIFY(i + 10 == p.second.first); - i++; - } - } - - { // test structured bindings - int i = 0; - for(auto& [key, value] : lc) - { - VERIFY(i == key); - VERIFY(i + 10 == value.first); - i++; - } - } - } - - // test initializer_list - { - eastl::lru_cache<int, int> lc = {{0, 10}, {1, 11}, {2, 12}, {3, 13}, {4, 14}, {5, 15}}; - - int i = 0; - for(auto& p : lc) - { - VERIFY(i == p.first); - VERIFY(i + 10 == p.second.first); - i++; - } - } - - return nErrorCount; -} diff --git a/test/source/TestMap.cpp b/test/source/TestMap.cpp deleted file mode 100644 index 0df8c88..0000000 --- a/test/source/TestMap.cpp +++ /dev/null @@ -1,305 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "TestMap.h" -#include "EASTLTest.h" -#include <EASTL/map.h> -#include <EASTL/string.h> -#include <EASTL/vector.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <map> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::map<int, int>; -template class eastl::multimap<int, int>; -template class eastl::map<TestObject, TestObject>; -template class eastl::multimap<TestObject, TestObject>; - - -/////////////////////////////////////////////////////////////////////////////// -// typedefs -// -typedef eastl::map<int, int> VM1; -typedef eastl::map<TestObject, TestObject> VM4; -typedef eastl::multimap<int, int> VMM1; -typedef eastl::multimap<TestObject, TestObject> VMM4; - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - typedef std::map<int, int> VM3; - typedef std::map<TestObject, TestObject> VM6; - typedef std::multimap<int, int> VMM3; - typedef std::multimap<TestObject, TestObject> VMM6; -#endif - -/////////////////////////////////////////////////////////////////////////////// - - - -int TestMap() -{ - int nErrorCount = 0; - - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - { // Test construction - nErrorCount += TestMapConstruction<VM1, VM3, false>(); - nErrorCount += TestMapConstruction<VM4, VM6, false>(); - - nErrorCount += TestMapConstruction<VMM1, VMM3, true>(); - nErrorCount += TestMapConstruction<VMM4, VMM6, true>(); - } - - - { // Test mutating functionality. - nErrorCount += TestMapMutation<VM1, VM3, false>(); - nErrorCount += TestMapMutation<VM4, VM6, false>(); - - nErrorCount += TestMapMutation<VMM1, VMM3, true>(); - nErrorCount += TestMapMutation<VMM4, VMM6, true>(); - } - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - - { // Test searching functionality. - nErrorCount += TestMapSearch<VM1, false>(); - nErrorCount += TestMapSearch<VM4, false>(); - - nErrorCount += TestMapSearch<VMM1, true>(); - nErrorCount += TestMapSearch<VMM4, true>(); - } - - - { - // C++11 emplace and related functionality - nErrorCount += TestMapCpp11<eastl::map<int, TestObject>>(); - nErrorCount += TestMultimapCpp11<eastl::multimap<int, TestObject>>(); - nErrorCount += TestMapCpp11NonCopyable<eastl::map<int, NonCopyable>>(); - } - - { - // C++17 try_emplace and related functionality - nErrorCount += TestMapCpp17<eastl::map<int, TestObject>>(); - } - - - { // Misc tests - - // const key_compare& key_comp() const; - // key_compare& key_comp(); - VM1 vm; - const VM1 vmc; - - const VM1::key_compare& kc = vmc.key_comp(); - vm.key_comp() = kc; - } - - - // Regressions against user bug reports. - { - // User reports that the following doesn't compile on GCC 4.1.1 due to unrecognized lower_bound. - eastl::map<int, int> m; - m[1] = 1; - EATEST_VERIFY(m.size() == 1); - m.erase(1); - EATEST_VERIFY(m.empty()); - } - - { - // User reports that EASTL_VALIDATE_COMPARE_ENABLED / EASTL_COMPARE_VALIDATE isn't compiling for this case. - eastl::map<eastl::u8string, int> m; - m.find_as(EA_CHAR8("some string"), eastl::equal_to_2<eastl::u8string, const char8_t*>()); - } - - { - eastl::map<int*, int> m; - int* ip = (int*)(uintptr_t)0xDEADC0DE; - - m[ip] = 0; - - auto it = m.find_as(ip, eastl::less_2<int*, int*>{}); - EATEST_VERIFY(it != m.end()); - - it = m.find_as((int*)(uintptr_t)0xDEADC0DE, eastl::less_2<int*, int*>{}); - EATEST_VERIFY(it != m.end()); - } - - { - // User reports that vector<map<enum,enum>> is crashing after the recent changes to add rvalue move and emplace support to rbtree. - typedef eastl::map<int, int> IntIntMap; - typedef eastl::vector<IntIntMap> IntIntMapArray; - - IntIntMapArray v; - v.push_back(IntIntMap()); // This was calling the rbtree move constructor, which had a bug. - v[0][16] = 0; // The rbtree was in a bad internal state and so this line resulted in a crash. - EATEST_VERIFY(v[0].validate()); - EATEST_VERIFY(v.validate()); - } - - { - typedef eastl::map<int, int> IntIntMap; - IntIntMap map1; - map1[1] = 1; - map1[3] = 3; - - #if EASTL_EXCEPTIONS_ENABLED - EATEST_VERIFY_THROW(map1.at(0)); - EATEST_VERIFY_THROW(map1.at(2)); - EATEST_VERIFY_THROW(map1.at(4)); - #endif - map1[0] = 1; - #if EASTL_EXCEPTIONS_ENABLED - EATEST_VERIFY_NOTHROW(map1.at(0)); - EATEST_VERIFY_NOTHROW(map1.at(1)); - EATEST_VERIFY_NOTHROW(map1.at(3)); - #endif - EATEST_VERIFY(map1.at(0) == 1); - EATEST_VERIFY(map1.at(1) == 1); - EATEST_VERIFY(map1.at(3) == 3); - - const IntIntMap map2; - const IntIntMap map3(map1); - - #if EASTL_EXCEPTIONS_ENABLED - EATEST_VERIFY_THROW(map2.at(0)); - EATEST_VERIFY_NOTHROW(map3.at(0)); - #endif - EATEST_VERIFY(map3.at(0) == 1); - } - - // User regression test - { - #if !EASTL_RBTREE_LEGACY_SWAP_BEHAVIOUR_REQUIRES_COPY_CTOR - typedef eastl::map<int, MoveOnlyTypeDefaultCtor> IntMOMap; - - IntMOMap m1, m2; - m2[0] = MoveOnlyTypeDefaultCtor(0); - m2[1] = MoveOnlyTypeDefaultCtor(1); - - EATEST_VERIFY( m1.empty()); - EATEST_VERIFY(!m2.empty()); - - m1.swap(m2); - - EATEST_VERIFY(!m1.empty()); - EATEST_VERIFY( m2.empty()); - #endif - } - -// todo: create a test case for this. -// { -// // User reports that an incorrectly wrapped pair key used to insert into an eastl map compiles when it should fire a compiler error about unconvertible types. -// typedef eastl::pair<eastl::string, eastl::string> PairStringKey; -// typedef eastl::map<PairStringKey, eastl::string> PairStringMap; -// -// PairStringMap p1, p2; -// -// p1.insert(PairStringMap::value_type(PairStringKey("key1", "key2"), "data")).first->second = "other_data"; -// -// PairStringKey key("key1", "key2"); -// PairStringMap::value_type insert_me(key, "data"); -// p2.insert(insert_me).first->second = "other_data"; -// -// for(auto& e : p1) -// printf("%s,%s = %s\n", e.first.first.c_str(), e.first.second.c_str(), e.second.c_str()); -// -// for(auto& e : p2) -// printf("%s,%s = %s\n", e.first.first.c_str(), e.first.second.c_str(), e.second.c_str()); -// -// EATEST_VERIFY(p1 == p2); -// } - - { // Test empty base-class optimization - struct UnemptyLess : eastl::less<int> - { - int foo; - }; - - typedef eastl::map<int, int, eastl::less<int>> VM1; - typedef eastl::map<int, int, UnemptyLess> VM2; - - EATEST_VERIFY(sizeof(VM1) < sizeof(VM2)); - } - - { // Test erase_if - eastl::map<int, int> m = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}}; - auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; }); - VERIFY((m == eastl::map<int, int>{{1, 1},{3, 3}})); - VERIFY(numErased == 3); - } - - { // Test erase_if - eastl::multimap<int, int> m = {{0, 0}, {0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}}; - auto numErased = eastl::erase_if(m, [](auto p) { return p.first % 2 == 0; }); - VERIFY((m == eastl::multimap<int, int>{{1, 1}, {1, 1}, {3, 3}}));; - VERIFY(numErased == 7); - } - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { // Test map <=> - eastl::map<int, int> m1 = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}}; - eastl::map<int, int> m2 = {{4, 4}, {3, 3}, {2, 2}, {1, 1}, {0, 0}}; - eastl::map<int, int> m3 = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}}; - eastl::map<int, int> m4 = {{1, 0}, {3, 2}, {5, 4}, {7, 6}, {9, 8}}; - eastl::map<int, int> m5 = {{0, 1}, {2, 3}, {4, 5}}; - - VERIFY(m1 == m2); - VERIFY(m1 != m3); - VERIFY(m3 != m4); - VERIFY(m3 < m4); - VERIFY(m5 < m4); - VERIFY(m5 < m3); - - - VERIFY((m1 <=> m2) == 0); - VERIFY((m1 <=> m3) != 0); - VERIFY((m3 <=> m4) != 0); - VERIFY((m3 <=> m4) < 0); - VERIFY((m5 <=> m4) < 0); - VERIFY((m5 <=> m3) < 0); - } - - { // Test multimap <=> - eastl::multimap<int, int> m1 = {{0, 0}, {0, 0}, {1, 1}, {1, 1}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {4, 4}, {4, 4}}; - eastl::multimap<int, int> m2 = {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {3, 3}, {2, 2}, {1, 1}, {0, 0}}; - eastl::multimap<int, int> m3 = {{0, 1}, {2, 3}, {4, 5}, {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}}; - eastl::multimap<int, int> m4 = {{1, 0}, {3, 2}, {5, 4}, {1, 0}, {3, 2}, {5, 4}, {7, 6}, {9, 8}}; - eastl::multimap<int, int> m5 = {{10, 11}, {10, 11}}; - - VERIFY(m1 == m2); - VERIFY(m1 != m3); - VERIFY(m3 != m4); - VERIFY(m3 < m4); - VERIFY(m5 > m4); - VERIFY(m5 > m3); - - VERIFY((m1 <=> m2) == 0); - VERIFY((m1 <=> m3) != 0); - VERIFY((m3 <=> m4) != 0); - VERIFY((m3 <=> m4) < 0); - VERIFY((m5 <=> m4) > 0); - VERIFY((m5 <=> m3) > 0); - } -#endif - - return nErrorCount; -} - - - - - - - - - - - diff --git a/test/source/TestMap.h b/test/source/TestMap.h deleted file mode 100644 index 8d480cf..0000000 --- a/test/source/TestMap.h +++ /dev/null @@ -1,1418 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/vector.h> -#include <EASTL/algorithm.h> -#include <EASTL/type_traits.h> -#include <EASTL/scoped_ptr.h> -#include <EASTL/random.h> -#include <EASTL/tuple.h> - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - EA_DISABLE_ALL_VC_WARNINGS() - #include <algorithm> - EA_RESTORE_ALL_VC_WARNINGS() -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// TestMapConstruction -// -// This test compares eastl::map/multimap to std::map/multimap. It could possibly -// work for comparing eastl::hash_map to C++11 std::unordered_map, but we would -// rather move towards making this test be independent of any std comparisons. -// -// Requires a container that can hold at least 1000 items. -// -template <typename T1, typename T2, bool bMultimap> -int TestMapConstruction() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { - // We use new because fixed-size versions these objects might be too big for declaration on a stack. - eastl::scoped_ptr<T1> pt1A(new T1); - eastl::scoped_ptr<T2> pt2A(new T2); - T1& t1A = *pt1A; - T2& t2A = *pt2A; - nErrorCount += CompareContainers(t1A, t2A, "Map ctor", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - EATEST_VERIFY(t1A.validate()); - - - eastl::scoped_ptr<T1> pt1B(new T1); - eastl::scoped_ptr<T2> pt2B(new T2); - T1& t1B = *pt1B; - T2& t2B = *pt2B; - nErrorCount += CompareContainers(t1B, t2B, "Map ctor", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - eastl::scoped_ptr<T1> pt1C(new T1); - eastl::scoped_ptr<T2> pt2C(new T2); - T1& t1C = *pt1C; - T2& t2C = *pt2C; - for(int i = 0; i < 1000; i++) - { - t1C.insert(typename T1::value_type(typename T1::key_type(i), typename T1::mapped_type(i))); - t2C.insert(typename T2::value_type(typename T2::key_type(i), typename T2::mapped_type(i))); - EATEST_VERIFY(t1C.validate()); - nErrorCount += CompareContainers(t1C, t2C, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - } - - - eastl::scoped_ptr<T1> pt1D(new T1); - eastl::scoped_ptr<T2> pt2D(new T2); - T1& t1D = *pt1D; - T2& t2D = *pt2D; - nErrorCount += CompareContainers(t1D, t2D, "Map ctor", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - eastl::scoped_ptr<T1> pt1E(new T1(t1C)); - eastl::scoped_ptr<T2> pt2E(new T2(t2C)); - T1& t1E = *pt1E; - T2& t2E = *pt2E; - EATEST_VERIFY(t1E.validate()); - nErrorCount += CompareContainers(t1E, t2E, "Map ctor", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - eastl::scoped_ptr<T1> pt1F(new T1(t1C.begin(), t1C.end())); - eastl::scoped_ptr<T2> pt2F(new T2(t2C.begin(), t2C.end())); - T1& t1F = *pt1F; - T2& t2F = *pt2F; - EATEST_VERIFY(t1F.validate()); - nErrorCount += CompareContainers(t1F, t2F, "Map ctor", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // operator=(const map&) - t1E = t1D; - t2E = t2D; - nErrorCount += CompareContainers(t1D, t2D, "Map operator=", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - nErrorCount += CompareContainers(t1E, t2E, "Map operator=", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // operator=(map&&) - // We test just the EASTL container here. - eastl::scoped_ptr<T1> pT1P(new T1); - eastl::scoped_ptr<T1> pT1Q(new T1); - T1& t1P = *pT1P; - T1& t1Q = *pT1Q; - - typename T1::key_type k10(0); - typename T1::key_type k11(1); - typename T1::key_type k12(2); - typename T1::key_type k13(3); - typename T1::key_type k14(4); - typename T1::key_type k15(5); - - typename T1::value_type v10(k10, typename T1::mapped_type(0)); - typename T1::value_type v11(k11, typename T1::mapped_type(1)); - typename T1::value_type v12(k12, typename T1::mapped_type(2)); - typename T1::value_type v13(k13, typename T1::mapped_type(3)); - typename T1::value_type v14(k14, typename T1::mapped_type(4)); - typename T1::value_type v15(k15, typename T1::mapped_type(5)); - - t1P.insert(v10); - t1P.insert(v11); - t1P.insert(v12); - - t1Q.insert(v13); - t1Q.insert(v14); - t1Q.insert(v15); - - t1Q = eastl::move(t1P); // We are effectively requesting to swap t1A with t1B. - //EATEST_VERIFY((t1P.size() == 3) && (t1P.find(k13) != t1P.end()) && (t1P.find(k14) != t1P.end()) && (t1P.find(k15) != t1P.end())); // Currently operator=(this_type&& x) clears x instead of swapping with it. - EATEST_VERIFY((t1Q.size() == 3) && (t1Q.find(k10) != t1Q.end()) && (t1Q.find(k11) != t1Q.end()) && (t1Q.find(k12) != t1Q.end())); - - - // swap - t1E.swap(t1D); - t2E.swap(t2D); - EATEST_VERIFY(t1D.validate()); - EATEST_VERIFY(t1E.validate()); - nErrorCount += CompareContainers(t1D, t2D, "Map swap", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - nErrorCount += CompareContainers(t1E, t2E, "Map swap", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // clear - t1A.clear(); - t2A.clear(); - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map clear", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - t1B.clear(); - t2B.clear(); - EATEST_VERIFY(t1B.validate()); - nErrorCount += CompareContainers(t1B, t2B, "Map clear", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // global operators (==, !=, <, etc.) - t1A.clear(); - t1B.clear(); - // Make t1A equal to t1B - t1A.insert(typename T1::value_type(typename T1::key_type(0), typename T1::mapped_type(0))); - t1A.insert(typename T1::value_type(typename T1::key_type(1), typename T1::mapped_type(1))); - t1A.insert(typename T1::value_type(typename T1::key_type(2), typename T1::mapped_type(2))); - - t1B.insert(typename T1::value_type(typename T1::key_type(0), typename T1::mapped_type(0))); - t1B.insert(typename T1::value_type(typename T1::key_type(1), typename T1::mapped_type(1))); - t1B.insert(typename T1::value_type(typename T1::key_type(2), typename T1::mapped_type(2))); - - EATEST_VERIFY( (t1A == t1B)); - EATEST_VERIFY(!(t1A != t1B)); - EATEST_VERIFY( (t1A <= t1B)); - EATEST_VERIFY( (t1A >= t1B)); - EATEST_VERIFY(!(t1A < t1B)); - EATEST_VERIFY(!(t1A > t1B)); - // Make t1A less than t1B - t1A.insert(typename T1::value_type(typename T1::key_type(3), typename T1::mapped_type(3))); - t1B.insert(typename T1::value_type(typename T1::key_type(4), typename T1::mapped_type(4))); - - EATEST_VERIFY(!(t1A == t1B)); - EATEST_VERIFY( (t1A != t1B)); - EATEST_VERIFY( (t1A <= t1B)); - EATEST_VERIFY(!(t1A >= t1B)); - EATEST_VERIFY( (t1A < t1B)); - EATEST_VERIFY(!(t1A > t1B)); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} - - - - -/////////////////////////////////////////////////////////////////////////////// -// TestMapMutation -// -// Requires a container that can hold at least 1000 items. -// -template <typename T1, typename T2, bool bMultimap> -int TestMapMutation() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { - eastl::scoped_ptr<T1> pt1A(new T1); // We use a pointers instead of concrete object because it's size may be huge. - eastl::scoped_ptr<T2> pt2A(new T2); - T1& t1A = *pt1A; - T2& t2A = *pt2A; - int i, iEnd, p; - - // Set up an array of values to randomize / permute. - eastl::vector<typename T1::key_type> valueArrayInsert; - - if(gEASTL_TestLevel >= kEASTL_TestLevelLow) - { - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - - valueArrayInsert.clear(); - - for(i = 0; i < 1000; i++) - { - valueArrayInsert.push_back(typename T1::key_type(i)); - - // Occasionally attempt to duplicate an element, both for map and multimap. - if(((i + 1) < 1000) && (rng.RandLimit(4) == 0)) - { - valueArrayInsert.push_back(typename T1::key_type(i)); - i++; - } - } - - for(p = 0; p < gEASTL_TestLevel * 100; p++) // For each permutation... - { - eastl::random_shuffle(valueArrayInsert.begin(), valueArrayInsert.end(), rng); - - // insert - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::key_type& k = valueArrayInsert[i]; - - t1A.insert(typename T1::value_type(k, k)); // We expect that both arguments are the same. - t2A.insert(typename T2::value_type(k, k)); - - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - } - - - // reverse iteration - typename T1::reverse_iterator r1 = t1A.rbegin(); - typename T2::reverse_iterator r2 = t2A.rbegin(); - - while(r1 != t1A.rend()) - { - typename T1::key_type k1 = (*r1).first; - typename T2::key_type k2 = (*r2).first; - EATEST_VERIFY(k1 == k2); - } - - - // erase - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::key_type& k = valueArrayInsert[i]; - - typename T1::size_type n1 = t1A.erase(k); - typename T2::size_type n2 = t2A.erase(k); - - EATEST_VERIFY(n1 == n2); - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map erase", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - } - - EATEST_VERIFY((TestObject::sTOCount == 0) || (TestObject::sTOCount == (int64_t)valueArrayInsert.size())); // This test will only have meaning when T1 contains TestObject. - } - } - - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - // Possibly do extended testing. - if(gEASTL_TestLevel > 6) - { - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - valueArrayInsert.clear(); - - for(i = 0; i < 9; i++) // Much more than this count would take too long to test all permutations. - valueArrayInsert.push_back(typename T1::key_type(i)); - - // Insert these values into the map in every existing permutation. - for(p = 0; std::next_permutation(valueArrayInsert.begin(), valueArrayInsert.end()); p++) // For each permutation... - { - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::key_type& k = valueArrayInsert[i]; - - t1A.insert(typename T1::value_type(k, k)); // We expect that both arguments are the same. - t2A.insert(typename T2::value_type(k, k)); - - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - } - - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::key_type& k = valueArrayInsert[i]; - - t1A.erase(k); - t2A.erase(k); - - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map erase", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - } - - EATEST_VERIFY((TestObject::sTOCount == 0) || (TestObject::sTOCount == (int64_t)valueArrayInsert.size())); // This test will only have meaning when T1 contains TestObject. - - } - - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - } - } - - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - { // Other insert and erase operations - - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - eastl::scoped_ptr<T1> pt1A(new T1); // We use a pointers instead of concrete object because it's size may be huge. - eastl::scoped_ptr<T2> pt2A(new T2); - T1& t1A = *pt1A; - T2& t2A = *pt2A; - int i; - - // Set up an array of values to randomize / permute. - eastl::vector<eastl::pair<typename T1::key_type, typename T1::mapped_type> > valueArrayInsert1; - eastl::vector< std::pair<typename T2::key_type, typename T2::mapped_type> > valueArrayInsert2; - - EA::UnitTest::Rand rng(EA::UnitTest::GetRandSeed()); - - for(i = 0; i < 100; i++) - { - valueArrayInsert1.push_back(typename T1::value_type(typename T1::key_type(i), typename T1::mapped_type(i))); - valueArrayInsert2.push_back(typename T2::value_type(typename T2::key_type(i), typename T2::mapped_type(i))); - - if(rng.RandLimit(3) == 0) - { - valueArrayInsert1.push_back(typename T1::value_type(typename T1::key_type(i), typename T1::mapped_type(i))); - valueArrayInsert2.push_back(typename T2::value_type(typename T2::key_type(i), typename T2::mapped_type(i))); - } - } - - - // insert(InputIterator first, InputIterator last) - t1A.insert(valueArrayInsert1.begin(), valueArrayInsert1.end()); - t2A.insert(valueArrayInsert2.begin(), valueArrayInsert2.end()); - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // insert_return_type insert(const Key& key); - t1A.insert(typename T1::key_type(8888)); - t2A.insert(typename T2::value_type(typename T2::key_type(8888), typename T2::mapped_type(0))); - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // iterator insert(iterator position, const value_type& value); - // - // If bMultimap == true, then the insertions below should fail due to the - // item being present. But they should return the correct iterator value. - typename T1::iterator it1 = t1A.insert(t1A.find(typename T1::key_type(2)), typename T1::value_type(typename T1::key_type(1), typename T1::mapped_type(1))); - typename T2::iterator it2 = t2A.insert(t2A.find(typename T2::key_type(2)), typename T2::value_type(typename T2::key_type(1), typename T2::mapped_type(1))); - EATEST_VERIFY(t1A.validate()); - EATEST_VERIFY(it1->first == typename T1::key_type(1)); - EATEST_VERIFY(it2->first == typename T2::key_type(1)); - nErrorCount += CompareContainers(t1A, t2A, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - it1 = t1A.insert(t1A.end(), typename T1::value_type(typename T1::key_type(5), typename T1::mapped_type(5))); - it2 = t2A.insert(t2A.end(), typename T2::value_type(typename T2::key_type(5), typename T2::mapped_type(5))); - EATEST_VERIFY(t1A.validate()); - EATEST_VERIFY(it1->first == typename T1::key_type(5)); - EATEST_VERIFY(it2->first == typename T2::key_type(5)); - nErrorCount += CompareContainers(t1A, t2A, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - // Now we remove these items so that the insertions above can succeed. - t1A.erase(t1A.find(typename T1::key_type(1))); - t2A.erase(t2A.find(typename T2::key_type(1))); - it1 = t1A.insert(t1A.find(typename T1::key_type(2)), typename T1::value_type(typename T1::key_type(1), typename T1::mapped_type(1))); - it2 = t2A.insert(t2A.find(typename T2::key_type(2)), typename T2::value_type(typename T2::key_type(1), typename T2::mapped_type(1))); - EATEST_VERIFY(t1A.validate()); - EATEST_VERIFY(it1->first == typename T1::key_type(1)); - EATEST_VERIFY(it2->first == typename T2::key_type(1)); - nErrorCount += CompareContainers(t1A, t2A, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - t1A.erase(t1A.find(typename T1::key_type(5))); - t2A.erase(t2A.find(typename T2::key_type(5))); - it1 = t1A.insert(t1A.end(), typename T1::value_type(typename T1::key_type(5), typename T1::mapped_type(5))); - it2 = t2A.insert(t2A.end(), typename T2::value_type(typename T2::key_type(5), typename T2::mapped_type(5))); - EATEST_VERIFY(t1A.validate()); - EATEST_VERIFY(it1->first == typename T1::key_type(5)); - EATEST_VERIFY(it2->first == typename T2::key_type(5)); - nErrorCount += CompareContainers(t1A, t2A, "Map insert", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // iterator erase(iterator first, iterator last); - typename T1::iterator it11 = t1A.find(typename T1::key_type(17)); - typename T1::iterator it12 = t1A.find(typename T2::key_type(37)); - t1A.erase(it11, it12); - - typename T2::iterator it21 = t2A.find(typename T1::key_type(17)); - typename T2::iterator it22 = t2A.find(typename T2::key_type(37)); - t2A.erase(it21, it22); - - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map erase(first, last)", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // iterator erase(iterator position); - t1A.erase(t1A.find(typename T1::key_type(60))); - t2A.erase(t2A.find(typename T1::key_type(60))); - EATEST_VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Map erase(first, last)", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - - // Disabled because this function isn't exposed outside the rbtree yet. - // void erase(const key_type* first, const key_type* last); - //typename T1::key_type keyArray1[3] = { typename T1::key_type(70), typename T1::key_type(71), typename T1::key_type(72) }; - //typename T2::key_type keyArray2[3] = { typename T2::key_type(70), typename T2::key_type(71), typename T2::key_type(72) }; - //t1A.erase(keyArray1 + 0, keyArray1 + 3); - //t2A.erase(keyArray2 + 0, keyArray2 + 3); - //EATEST_VERIFY(t1A.validate()); - //nErrorCount += CompareContainers(t1A, t2A, "Map erase(first, last)", eastl::use_first<typename T1::value_type>(), eastl::use_first<typename T2::value_type>()); - - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - } - - { - // map(std::initializer_list<value_type> ilist, const Compare& compare = Compare(), const allocator_type& allocator = EASTL_MAP_DEFAULT_ALLOCATOR); - // this_type& operator=(std::initializer_list<T> ilist); - // void insert(std::initializer_list<value_type> ilist); - - // VS2013 has a known issue when dealing with std::initializer_lists - // https://connect.microsoft.com/VisualStudio/feedback/details/792355/compiler-confused-about-whether-to-use-a-initializer-list-assignment-operator - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) && !(defined(_MSC_VER) && _MSC_VER == 1800) - T1 myMap = { {typename T1::key_type(10),typename T1::mapped_type(0)}, {typename T1::key_type(11),typename T1::mapped_type(1)} }; - EATEST_VERIFY(myMap.size() == 2); - EATEST_VERIFY(myMap.begin()->first == typename T1::key_type(10)); - typename T1::iterator it = myMap.rbegin().base(); - EATEST_VERIFY((--it)->first == typename T1::key_type(11)); - - myMap = { {typename T1::key_type(20),typename T1::mapped_type(0)}, {typename T1::key_type(21),typename T1::mapped_type(1)} }; - EATEST_VERIFY(myMap.size() == 2); - EATEST_VERIFY(myMap.begin()->first == typename T1::key_type(20)); - it = myMap.rbegin().base(); - EATEST_VERIFY((--it)->first == typename T1::key_type(21)); - - myMap.insert({ {typename T1::key_type(40),typename T1::mapped_type(0)}, {typename T1::key_type(41),typename T1::mapped_type(1)} }); - EATEST_VERIFY(myMap.size() == 4); - it = myMap.rbegin().base(); - EATEST_VERIFY((--it)->first == typename T1::key_type(41)); - #endif - } - - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} - - - - -template <typename T1> -int TestMapSpecific(T1& t1A, eastl::false_type) // false_type means this is a map and not a multimap. -{ - int nErrorCount = 0; - - // operator[] (map only) - typename T1::mapped_type m = t1A[typename T1::key_type(0)]; - EATEST_VERIFY(m == typename T1::mapped_type(0)); - - m = t1A[typename T1::key_type(999)]; - EATEST_VERIFY(m == typename T1::mapped_type(999)); - - m = t1A[typename T1::key_type(10000000)]; // Test the creation of an element that isn't present. - EATEST_VERIFY(m == typename T1::mapped_type(0)); // Test for 0 because the default ctor for our test objects assigns 0 to the object. - - return nErrorCount; -} - - -template <typename T1> -int TestMapSpecific(T1& t1A, eastl::true_type) // true_type means this is a multimap and not a map. -{ - int nErrorCount = 0; - - // equal_range_small (multimap only) - eastl::pair<typename T1::iterator, typename T1::iterator> er = t1A.equal_range_small(typename T1::key_type(499)); - EATEST_VERIFY(er.first->first == typename T1::key_type(499)); - EATEST_VERIFY(er.second->first == typename T1::key_type(501)); - - er = t1A.equal_range_small(typename T1::key_type(-1)); - EATEST_VERIFY(er.first == er.second); - EATEST_VERIFY(er.first == t1A.begin()); - - return nErrorCount; -} - - -// Just for the purposes of the map::find_as test below, we declare the following. -// The map::find_as function searches a container of X for a type Y, where the user -// defines the equality of X to Y. The purpose of TMapComparable is to be a generic type Y -// that can be used for any X. We need to make this generic because the whole TestMapSearch -// function below is templated on type T1 and so we don't know what T1 is ahead of time. - -template <typename T> -struct TMapComparable -{ - T b; - - TMapComparable() : b() { } - TMapComparable(const T& a) : b(a){ } - const TMapComparable& operator=(const T& a) { b = a; return *this; } - const TMapComparable& operator=(const TMapComparable& x) { b = x.b; return *this; } - operator const T&() const { return b; } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// TestMapSearch -// -// This function is designed to work with map, fixed_map (and not hash containers). -// Requires a container that can hold at least 1000 items. -// -template <typename T1, bool bMultimap> -int TestMapSearch() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { // Test find, lower_bound, upper_bound, etc.. - eastl::scoped_ptr<T1> pt1A(new T1); // We use a pointers instead of concrete object because it's size may be huge. - T1& t1A = *pt1A; - int i, iEnd; - typename T1::iterator it; - - // Set up an array of values to randomize / permute. - eastl::vector<typename T1::key_type> valueArrayInsert; - - for(i = 0; i < 1000; i++) - valueArrayInsert.push_back(typename T1::key_type(i)); - - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - eastl::random_shuffle(valueArrayInsert.begin(), valueArrayInsert.end(), rng); - - - // insert - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::key_type k(i); - t1A.insert(typename T1::value_type(k, k)); - - it = t1A.find(k); - EATEST_VERIFY(it != t1A.end()); - } - - - // find - for(i = 0; i < 1000; i++) - { - typename T1::key_type k(i); - it = t1A.find(k); - - EATEST_VERIFY(it != t1A.end()); - EATEST_VERIFY(it->first == k); - EATEST_VERIFY(it->second == k); - } - - it = t1A.find(typename T1::key_type(-1)); - EATEST_VERIFY(it == t1A.end()); - - it = t1A.find(typename T1::key_type(1001)); - EATEST_VERIFY(it == t1A.end()); - - - // find_as - typedef TMapComparable<typename T1::key_type> TC; - - // Normally we use find_as to find via a different type, but we can test it here like this. - for(i = 0; i < 1000; i++) - { - TC k = typename T1::key_type(i); - it = t1A.find_as(k, eastl::less_2<typename T1::key_type, TC>()); - - EATEST_VERIFY(it != t1A.end()); - EATEST_VERIFY(it->first == k); - EATEST_VERIFY(it->second == k); - } - - it = t1A.find_as(TC(typename T1::key_type(-1)), eastl::less_2<typename T1::key_type, TC>()); - EATEST_VERIFY(it == t1A.end()); - - it = t1A.find_as(TC(typename T1::key_type(1001)), eastl::less_2<typename T1::key_type, TC>()); - EATEST_VERIFY(it == t1A.end()); - - - // lower_bound - it = t1A.lower_bound(typename T1::key_type(0)); - EATEST_VERIFY(it == t1A.begin()); - - it = t1A.lower_bound(typename T1::key_type(-1)); - EATEST_VERIFY(it == t1A.begin()); - - it = t1A.lower_bound(typename T1::key_type(1001)); - EATEST_VERIFY(it == t1A.end()); - - t1A.erase(typename T1::key_type(500)); - it = t1A.lower_bound(typename T1::key_type(500)); - EATEST_VERIFY(it->first == typename T1::key_type(501)); - - - // upper_bound - it = t1A.upper_bound(typename T1::key_type(-1)); - EATEST_VERIFY(it == t1A.begin()); - - it = t1A.upper_bound(typename T1::key_type(499)); - EATEST_VERIFY(it->first == typename T1::key_type(501)); - - it = t1A.upper_bound(typename T1::key_type(-1)); - EATEST_VERIFY(it->first == typename T1::key_type(0)); - - it = t1A.upper_bound(typename T1::key_type(1000)); - EATEST_VERIFY(it == t1A.end()); - - - // count - typename T1::size_type n = t1A.count(typename T1::key_type(-1)); - EATEST_VERIFY(n == 0); - - n = t1A.count(typename T1::key_type(0)); - EATEST_VERIFY(n == 1); - - n = t1A.count(typename T1::key_type(500)); // We removed 500 above. - EATEST_VERIFY(n == 0); - - n = t1A.count(typename T1::key_type(1001)); - EATEST_VERIFY(n == 0); - - - // equal_range - eastl::pair<typename T1::iterator, typename T1::iterator> er = t1A.equal_range(typename T1::key_type(200)); - EATEST_VERIFY(er.first->first == typename T1::key_type(200)); - EATEST_VERIFY(er.first->second == typename T1::key_type(200)); - - er = t1A.equal_range(typename T1::key_type(499)); - EATEST_VERIFY(er.first->first == typename T1::key_type(499)); - EATEST_VERIFY(er.second->first == typename T1::key_type(501)); - - er = t1A.equal_range(typename T1::key_type(-1)); - EATEST_VERIFY(er.first == er.second); - EATEST_VERIFY(er.first == t1A.begin()); - - - // Some tests need to be differently between map and multimap. - nErrorCount += TestMapSpecific(t1A, eastl::integral_constant<bool, bMultimap>()); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestMapCpp11 -// -// This function is designed to work with map, fixed_map, hash_map, fixed_hash_map. -// -template <typename T1> -int TestMapCpp11() -{ - int nErrorCount = 0; - - // template <class... Args> - // insert_return_type emplace(Args&&... args); - // - // template <class... Args> - // iterator emplace_hint(const_iterator position, Args&&... args); - // - // insert_return_type insert(value_type&& value); - // iterator insert(const_iterator position, value_type&& value); - // void insert(std::initializer_list<value_type> ilist); - TestObject::Reset(); - - typedef T1 TOMap; - typedef typename TOMap::value_type value_type; - typename TOMap::insert_return_type toMapInsertResult; - typename TOMap::iterator toMapIterator; - - TOMap toMap; - TestObject to0(0); - TestObject to1(1); - - toMapInsertResult = toMap.emplace(value_type(0, to0)); - EATEST_VERIFY(toMapInsertResult.second == true); - //EATEST_VERIFY((TestObject::sTOCopyCtorCount == 2) && (TestObject::sTOMoveCtorCount == 1)); // Disabled until we can guarantee its behavior and deal with how it's different between compilers of differing C++11 support. - - toMapInsertResult = toMap.emplace(value_type(1, eastl::move(to1))); - EATEST_VERIFY(toMapInsertResult.second == true); - - // insert_return_type t1A.emplace(value_type&& value); - TestObject to4(4); - value_type value40(4, to4); - EATEST_VERIFY(toMap.find(4) == toMap.end()); - EATEST_VERIFY(value40.second.mX == 4); // It should change to 0 below during the move swap. - toMapInsertResult = toMap.emplace(eastl::move(value40)); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(4) != toMap.end()); - EATEST_VERIFY(value40.second.mX == 0); - - value_type value41(4, TestObject(41)); - toMapInsertResult = toMap.emplace(eastl::move(value41)); - EATEST_VERIFY(toMapInsertResult.second == false); - EATEST_VERIFY(toMapInsertResult.first->second.mX == 4); - EATEST_VERIFY(toMap.find(4) != toMap.end()); - - // iterator t1A.emplace_hint(const_iterator position, value_type&& value); - TestObject to5(5); - value_type value50(5, to5); - EATEST_VERIFY(toMap.find(5) == toMap.end()); - toMapInsertResult = toMap.emplace(eastl::move(value50)); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(5) != toMap.end()); - - value_type value51(5, TestObject(51)); - toMapIterator = toMap.emplace_hint(toMapInsertResult.first, eastl::move(value51)); - EATEST_VERIFY(toMapIterator->first == 5); - EATEST_VERIFY(toMapIterator->second.mX == 5); - EATEST_VERIFY(toMap.find(5) != toMap.end()); - - TestObject to6(6); - value_type value6(6, to6); - EATEST_VERIFY(toMap.find(6) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), eastl::move(value6)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 6); - EATEST_VERIFY(toMap.find(6) != toMap.end()); - - TestObject to2(2); - EATEST_VERIFY(toMap.find(2) == toMap.end()); - toMapInsertResult = toMap.emplace(value_type(2, to2)); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(2) != toMap.end()); - toMapInsertResult = toMap.emplace(value_type(2, to2)); - EATEST_VERIFY(toMapInsertResult.second == false); - EATEST_VERIFY(toMap.find(2) != toMap.end()); - - // iterator t1A.emplace_hint(const_iterator position, const value_type& value); - TestObject to7(7); - value_type value70(7, to7); - EATEST_VERIFY(toMap.find(7) == toMap.end()); - toMapInsertResult = toMap.emplace(value70); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(7) != toMap.end()); - - value_type value71(7, TestObject(71)); - toMapIterator = toMap.emplace_hint(toMapInsertResult.first, value71); - EATEST_VERIFY(toMapIterator->first == 7); - EATEST_VERIFY(toMapIterator->second.mX == 7); - EATEST_VERIFY(toMap.find(7) != toMap.end()); - - TestObject to8(8); - value_type value8(8, to8); - EATEST_VERIFY(toMap.find(8) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), value8); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 8); - EATEST_VERIFY(toMap.find(8) != toMap.end()); - - // insert_return_type t1A.insert(value_type&& value); - TestObject to3(3); - EATEST_VERIFY(toMap.find(3) == toMap.end()); - toMapInsertResult = toMap.insert(value_type(3, to3)); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(3) != toMap.end()); - toMapInsertResult = toMap.insert(value_type(3, to3)); - EATEST_VERIFY(toMapInsertResult.second == false); - EATEST_VERIFY(toMap.find(3) != toMap.end()); - - - // iterator t1A.insert(const_iterator position, value_type&& value); - TestObject to9(9); - value_type value90(9, to9); - EATEST_VERIFY(toMap.find(9) == toMap.end()); - toMapInsertResult = toMap.emplace(eastl::move(value90)); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(9) != toMap.end()); - - value_type value91(9, TestObject(91)); - toMapIterator = toMap.insert(toMapInsertResult.first, eastl::move(value91)); - EATEST_VERIFY(toMapIterator->first == 9); - EATEST_VERIFY(toMapIterator->second.mX == 9); - EATEST_VERIFY(toMap.find(9) != toMap.end()); - - TestObject to10(10); - value_type value10(10, to10); - EATEST_VERIFY(toMap.find(10) == toMap.end()); - toMapIterator = toMap.insert(toMap.begin(), eastl::move(value10)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 10); - EATEST_VERIFY(toMap.find(10) != toMap.end()); - - // insert_return_type t1A.emplace(Args&&... args); - TestObject to11(11); - EATEST_VERIFY(toMap.find(11) == toMap.end()); - toMapInsertResult = toMap.emplace(11, to11); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMapInsertResult.first->first == 11); - EATEST_VERIFY(toMap.find(11) != toMap.end()); - - TestObject to111(111); - toMapInsertResult = toMap.emplace(11, to111); - EATEST_VERIFY(toMapInsertResult.second == false); - EATEST_VERIFY(toMapInsertResult.first->first == 11); - EATEST_VERIFY(toMapInsertResult.first->second.mX == 11); - EATEST_VERIFY(toMap.find(11) != toMap.end()); - - TestObject to12(12); - EATEST_VERIFY(toMap.find(12) == toMap.end()); - toMapInsertResult = toMap.emplace(12, eastl::move(to12)); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMapInsertResult.first->first == 12); - EATEST_VERIFY(toMap.find(12) != toMap.end()); - - TestObject to121(121); - toMapInsertResult = toMap.emplace(12, eastl::move(to121)); - EATEST_VERIFY(toMapInsertResult.second == false); - EATEST_VERIFY(toMapInsertResult.first->first == 12); - EATEST_VERIFY(toMapInsertResult.first->second.mX == 12); - EATEST_VERIFY(toMap.find(12) != toMap.end()); - - EATEST_VERIFY(toMap.find(13) == toMap.end()); - toMapInsertResult = toMap.emplace(eastl::piecewise_construct, eastl::make_tuple(13), eastl::make_tuple(1, 2, 10)); // 1 + 2 + 10 = 13 - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMapInsertResult.first->first == 13); - EATEST_VERIFY(toMap.find(13) != toMap.end()); - - toMapInsertResult = toMap.emplace(eastl::piecewise_construct, eastl::make_tuple(13), eastl::make_tuple(1, 30, 100)); // 1 + 30 + 100 = 131 - EATEST_VERIFY(toMapInsertResult.second == false); - EATEST_VERIFY(toMapInsertResult.first->first == 13); - EATEST_VERIFY(toMapInsertResult.first->second.mX == 13); - EATEST_VERIFY(toMap.find(13) != toMap.end()); - - // iterator t1A.emplace_hint(const_iterator position, Args&&... args); - TestObject to14(14); - EATEST_VERIFY(toMap.find(14) == toMap.end()); - toMapInsertResult = toMap.emplace(14, to14); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(14) != toMap.end()); - - TestObject to141(141); - toMapIterator = toMap.emplace_hint(toMapInsertResult.first, 14, to141); - EATEST_VERIFY(toMapIterator->first == 14); - EATEST_VERIFY(toMapIterator->second.mX == 14); - EATEST_VERIFY(toMap.find(14) != toMap.end()); - - TestObject to15(15); - EATEST_VERIFY(toMap.find(15) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), 15, to15); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 15); - EATEST_VERIFY(toMap.find(15) != toMap.end()); - - TestObject to16(16); - EATEST_VERIFY(toMap.find(16) == toMap.end()); - toMapInsertResult = toMap.emplace(16, eastl::move(to16)); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(16) != toMap.end()); - - TestObject to161(161); - toMapIterator = toMap.emplace_hint(toMapInsertResult.first, 16, eastl::move(to161)); - EATEST_VERIFY(toMapIterator->first == 16); - EATEST_VERIFY(toMapIterator->second.mX == 16); - EATEST_VERIFY(toMap.find(16) != toMap.end()); - - TestObject to17(17); - EATEST_VERIFY(toMap.find(17) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), 17, eastl::move(to17)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 17); - EATEST_VERIFY(toMap.find(17) != toMap.end()); - - EATEST_VERIFY(toMap.find(18) == toMap.end()); - toMapInsertResult = toMap.emplace(eastl::piecewise_construct, eastl::make_tuple(18), eastl::make_tuple(3, 5, 10)); // 3 + 5 + 10 = 18 - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(18) != toMap.end()); - - toMapIterator = toMap.emplace_hint(toMapInsertResult.first, eastl::piecewise_construct, eastl::make_tuple(18), eastl::make_tuple(1, 80, 100)); // 1 + 80 + 100 = 181 - EATEST_VERIFY(toMapIterator->first == 18); - EATEST_VERIFY(toMapIterator->second.mX == 18); - EATEST_VERIFY(toMap.find(18) != toMap.end()); - - EATEST_VERIFY(toMap.find(19) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), eastl::piecewise_construct, eastl::make_tuple(19), eastl::make_tuple(4, 5, 10)); // 4 + 5 + 10 = 19 // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 19); - EATEST_VERIFY(toMap.find(19) != toMap.end()); - - // iterator t1A.insert(const_iterator position, const value_type& value); - TestObject to20(20); - value_type value20(20, to20); - EATEST_VERIFY(toMap.find(20) == toMap.end()); - toMapInsertResult = toMap.emplace(value20); - EATEST_VERIFY(toMapInsertResult.second == true); - EATEST_VERIFY(toMap.find(20) != toMap.end()); - - value_type value201(20, TestObject(201)); - toMapIterator = toMap.insert(toMapInsertResult.first, value201); - EATEST_VERIFY(toMapIterator->first == 20); - EATEST_VERIFY(toMapIterator->second.mX == 20); - EATEST_VERIFY(toMap.find(20) != toMap.end()); - - TestObject to21(21); - value_type value21(21, to21); - EATEST_VERIFY(toMap.find(21) == toMap.end()); - toMapIterator = toMap.insert(toMap.begin(), value21); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 21); - EATEST_VERIFY(toMap.find(21) != toMap.end()); - - // void insert(std::initializer_list<value_type> ilist); - toMap.insert({ value_type(22, TestObject(22)), value_type(23, TestObject(23)), value_type(24, TestObject(24)) }); - EATEST_VERIFY(toMap.find(22) != toMap.end()); - EATEST_VERIFY(toMap.find(23) != toMap.end()); - EATEST_VERIFY(toMap.find(24) != toMap.end()); - - return nErrorCount; -} - -struct NonCopyable -{ - NonCopyable() : mX(0) {} - NonCopyable(int x) : mX(x) {} - - int mX; - - EA_NON_COPYABLE(NonCopyable) -}; - -inline bool operator<(const NonCopyable& a, const NonCopyable& b) { return a.mX < b.mX; } - -template <typename T> -int TestMapCpp11NonCopyable() -{ - int nErrorCount = 0; - - // Verify that operator[]() can be called for a type that is default constructible but not copy constructible. C++11 - // relaxed the requirements on operator[]() and so this should compile. - T ncMap; - ncMap[1].mX = 1; - EATEST_VERIFY(ncMap[1].mX == 1); - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestMultimapCpp11 -// -// This function is designed to work with multimap, fixed_multimap, hash_multimap, fixed_hash_multimap -// -// This is similar to the TestSetCpp11 function, with some differences related -// to handling of duplicate entries. -// -template <typename T1> -int TestMultimapCpp11() -{ - int nErrorCount = 0; - - // template <class... Args> - // insert_return_type emplace(Args&&... args); - // - // template <class... Args> - // iterator emplace_hint(const_iterator position, Args&&... args); - // - // insert_return_type insert(value_type&& value); - // iterator insert(const_iterator position, value_type&& value); - // void insert(std::initializer_list<value_type> ilist); - TestObject::Reset(); - - typedef T1 TOMap; - typedef typename TOMap::value_type value_type; - typename TOMap::iterator toMapIterator; - - TOMap toMap; - TestObject to0(0); - TestObject to1(1); - - toMapIterator = toMap.emplace(value_type(0, to0)); - EATEST_VERIFY(toMapIterator->first == 0); - //EATEST_VERIFY((TestObject::sTOCopyCtorCount == 2) && (TestObject::sTOMoveCtorCount == 1)); // Disabled until we can guarantee its behavior and deal with how it's different between compilers of differing C++11 support. - - toMapIterator = toMap.emplace(value_type(1, eastl::move(to1))); - EATEST_VERIFY(toMapIterator->first == 1); - - // insert_return_type t1A.emplace(value_type&& value); - TestObject to4(4); - value_type value40(4, to4); - EATEST_VERIFY(toMap.find(4) == toMap.end()); - EATEST_VERIFY(value40.second.mX == 4); // It should change to 0 below during the move swap. - toMapIterator = toMap.emplace(eastl::move(value40)); - EATEST_VERIFY(toMapIterator->first == 4); - EATEST_VERIFY(toMap.find(4) != toMap.end()); - EATEST_VERIFY(value40.second.mX == 0); - - value_type value41(4, TestObject(41)); - toMapIterator = toMap.emplace(eastl::move(value41)); - EATEST_VERIFY(toMapIterator->first == 4); - EATEST_VERIFY(toMapIterator->second.mX == 41); - EATEST_VERIFY(toMap.count(4) == 2); - - // iterator t1A.emplace_hint(const_iterator position, value_type&& value); - TestObject to5(5); - value_type value50(5, to5); - EATEST_VERIFY(toMap.find(5) == toMap.end()); - toMapIterator = toMap.emplace(eastl::move(value50)); - EATEST_VERIFY(toMapIterator->first == 5); - EATEST_VERIFY(toMap.find(5) != toMap.end()); - - value_type value51(5, TestObject(51)); - toMapIterator = toMap.emplace_hint(toMapIterator, eastl::move(value51)); - EATEST_VERIFY(toMapIterator->first == 5); - EATEST_VERIFY(toMapIterator->second.mX == 51); - EATEST_VERIFY(toMap.count(5) == 2); - - TestObject to6(6); - value_type value6(6, to6); - EATEST_VERIFY(toMap.find(6) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), eastl::move(value6)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 6); - EATEST_VERIFY(toMap.find(6) != toMap.end()); - - TestObject to2(2); - EATEST_VERIFY(toMap.find(2) == toMap.end()); - toMapIterator = toMap.emplace(value_type(2, to2)); - EATEST_VERIFY(toMapIterator->first == 2); - EATEST_VERIFY(toMap.find(2) != toMap.end()); - toMapIterator = toMap.emplace(value_type(2, to2)); - EATEST_VERIFY(toMapIterator->first == 2); - EATEST_VERIFY(toMap.find(2) != toMap.end()); - - // iterator t1A.emplace_hint(const_iterator position, const value_type& value); - TestObject to7(7); - value_type value70(7, to7); - EATEST_VERIFY(toMap.find(7) == toMap.end()); - toMapIterator = toMap.emplace(value70); - EATEST_VERIFY(toMapIterator->first == 7); - EATEST_VERIFY(toMap.find(7) != toMap.end()); - - value_type value71(7, TestObject(71)); - toMapIterator = toMap.emplace_hint(toMapIterator, value71); - EATEST_VERIFY(toMapIterator->first == 7); - EATEST_VERIFY(toMapIterator->second.mX == 71); - EATEST_VERIFY(toMap.count(7) == 2); - - TestObject to8(8); - value_type value8(8, to8); - EATEST_VERIFY(toMap.find(8) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), value8); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 8); - EATEST_VERIFY(toMap.find(8) != toMap.end()); - - // insert_return_type t1A.insert(value_type&& value); - TestObject to3(3); - EATEST_VERIFY(toMap.find(3) == toMap.end()); - toMapIterator = toMap.insert(value_type(3, to3)); - EATEST_VERIFY(toMapIterator->first == 3); - EATEST_VERIFY(toMap.find(3) != toMap.end()); - toMapIterator = toMap.insert(value_type(3, to3)); - EATEST_VERIFY(toMapIterator->first == 3); - EATEST_VERIFY(toMap.find(3) != toMap.end()); - - - // iterator t1A.insert(const_iterator position, value_type&& value); - TestObject to9(9); - value_type value90(9, to9); - EATEST_VERIFY(toMap.find(9) == toMap.end()); - toMapIterator = toMap.emplace(eastl::move(value90)); - EATEST_VERIFY(toMapIterator->first == 9); - EATEST_VERIFY(toMap.find(9) != toMap.end()); - - value_type value91(9, TestObject(91)); - toMapIterator = toMap.insert(toMapIterator, eastl::move(value91)); - EATEST_VERIFY(toMapIterator->first == 9); - EATEST_VERIFY(toMapIterator->second.mX == 91); - EATEST_VERIFY(toMap.count(9) == 2); - - TestObject to10(10); - value_type value10(10, to10); - EATEST_VERIFY(toMap.find(10) == toMap.end()); - toMapIterator = toMap.insert(toMap.begin(), eastl::move(value10)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 10); - EATEST_VERIFY(toMap.find(10) != toMap.end()); - - // iterator t1A.emplace(Args&&... args); - TestObject to11(11); - EATEST_VERIFY(toMap.find(11) == toMap.end()); - toMapIterator = toMap.emplace(11, to11); - EATEST_VERIFY(toMapIterator->first == 11); - EATEST_VERIFY(toMap.find(11) != toMap.end()); - - TestObject to111(111); - toMapIterator = toMap.emplace(11, to111); - EATEST_VERIFY(toMapIterator->first == 11); - EATEST_VERIFY(toMapIterator->second.mX == 111); - EATEST_VERIFY(toMap.count(11) == 2); - - TestObject to12(12); - EATEST_VERIFY(toMap.find(12) == toMap.end()); - toMapIterator = toMap.emplace(12, eastl::move(to12)); - EATEST_VERIFY(toMapIterator->first == 12); - EATEST_VERIFY(toMap.find(12) != toMap.end()); - - TestObject to121(121); - toMapIterator = toMap.emplace(12, eastl::move(to121)); - EATEST_VERIFY(toMapIterator->first == 12); - EATEST_VERIFY(toMapIterator->second.mX == 121); - EATEST_VERIFY(toMap.count(12) == 2); - - EATEST_VERIFY(toMap.find(13) == toMap.end()); - toMapIterator = toMap.emplace(eastl::piecewise_construct, eastl::make_tuple(13), eastl::make_tuple(1, 2, 10)); // 1 + 2 + 10 = 13 - EATEST_VERIFY(toMapIterator->first == 13); - EATEST_VERIFY(toMap.find(13) != toMap.end()); - - toMapIterator = toMap.emplace(eastl::piecewise_construct, eastl::make_tuple(13), eastl::make_tuple(1, 30, 100)); // 1 + 30 + 100 = 131 - EATEST_VERIFY(toMapIterator->first == 13); - EATEST_VERIFY(toMapIterator->second.mX == 131); - EATEST_VERIFY(toMap.count(13) == 2); - - // iterator t1A.emplace_hint(const_iterator position, Args&&... args); - TestObject to14(14); - EATEST_VERIFY(toMap.find(14) == toMap.end()); - toMapIterator = toMap.emplace(14, to14); - EATEST_VERIFY(toMap.find(14) != toMap.end()); - - TestObject to141(141); - toMapIterator = toMap.emplace_hint(toMapIterator, 14, to141); - EATEST_VERIFY(toMapIterator->first == 14); - EATEST_VERIFY(toMapIterator->second.mX == 141); - EATEST_VERIFY(toMap.count(14) == 2); - - TestObject to15(15); - EATEST_VERIFY(toMap.find(15) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), 15, to15); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 15); - EATEST_VERIFY(toMap.find(15) != toMap.end()); - - TestObject to16(16); - EATEST_VERIFY(toMap.find(16) == toMap.end()); - toMapIterator = toMap.emplace(16, eastl::move(to16)); - EATEST_VERIFY(toMap.find(16) != toMap.end()); - - TestObject to161(161); - toMapIterator = toMap.emplace_hint(toMapIterator, 16, eastl::move(to161)); - EATEST_VERIFY(toMapIterator->first == 16); - EATEST_VERIFY(toMapIterator->second.mX == 161); - EATEST_VERIFY(toMap.count(16) == 2); - - TestObject to17(17); - EATEST_VERIFY(toMap.find(17) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), 17, eastl::move(to17)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 17); - EATEST_VERIFY(toMap.find(17) != toMap.end()); - - EATEST_VERIFY(toMap.find(18) == toMap.end()); - toMapIterator = toMap.emplace(eastl::piecewise_construct, eastl::make_tuple(18), eastl::make_tuple(3, 5, 10)); // 3 + 5 + 10 = 18 - EATEST_VERIFY(toMap.find(18) != toMap.end()); - - toMapIterator = toMap.emplace_hint(toMapIterator, eastl::piecewise_construct, eastl::make_tuple(18), eastl::make_tuple(1, 80, 100)); // 1 + 80 + 100 = 181 - EATEST_VERIFY(toMapIterator->first == 18); - EATEST_VERIFY(toMapIterator->second.mX == 181); - EATEST_VERIFY(toMap.count(18) == 2); - - EATEST_VERIFY(toMap.find(19) == toMap.end()); - toMapIterator = toMap.emplace_hint(toMap.begin(), eastl::piecewise_construct, eastl::make_tuple(19), eastl::make_tuple(4, 5, 10)); // 4 + 5 + 10 = 19 // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 19); - EATEST_VERIFY(toMap.find(19) != toMap.end()); - - // iterator t1A.insert(const_iterator position, const value_type& value); - TestObject to20(20); - value_type value20(20, to20); - EATEST_VERIFY(toMap.find(20) == toMap.end()); - toMapIterator = toMap.emplace(value20); - EATEST_VERIFY(toMap.find(20) != toMap.end()); - - value_type value201(20, TestObject(201)); - toMapIterator = toMap.insert(toMapIterator, value201); - EATEST_VERIFY(toMapIterator->first == 20); - EATEST_VERIFY(toMapIterator->second.mX == 201); - EATEST_VERIFY(toMap.count(20) == 2); - - TestObject to21(21); - value_type value21(21, to21); - EATEST_VERIFY(toMap.find(21) == toMap.end()); - toMapIterator = toMap.insert(toMap.begin(), value21); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(toMapIterator->first == 21); - EATEST_VERIFY(toMap.find(21) != toMap.end()); - - // void insert(std::initializer_list<value_type> ilist); - toMap.insert({ value_type(22, TestObject(22)), value_type(23, TestObject(23)), value_type(24, TestObject(24)), value_type(24, TestObject(241)) }); - EATEST_VERIFY(toMap.find(22) != toMap.end()); - EATEST_VERIFY(toMap.find(23) != toMap.end()); - EATEST_VERIFY(toMap.count(24) == 2); - - return nErrorCount; -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestMapCpp17 -// -// This function is designed to work with map, fixed_map, hash_map, fixed_hash_map, unordered_map. -// -template <typename T1> -int TestMapCpp17() -{ - - int nErrorCount = 0; - - TestObject::Reset(); - - typedef T1 TOMap; - typedef typename TOMap::mapped_type mapped_type; - typename TOMap::iterator toMapIterator; - - - { - // pair<iterator, bool> try_emplace (const key_type& k, Args&&... args); - // pair<iterator, bool> try_emplace (key_type&& k, Args&&... args); - // iterator try_emplace (const_iterator hint, const key_type& k, Args&&... args); - // iterator try_emplace (const_iterator hint, key_type&& k, Args&&... args); - - TOMap toMap; - - { // do initial insert - auto result = toMap.try_emplace(7, 7); // test fwding to conversion-ctor - VERIFY(result.second); - VERIFY(result.first->second == mapped_type(7)); - VERIFY(toMap.size() == 1); - } - - auto ctorCount = TestObject::sTOCtorCount; - - { // verify duplicate not inserted - auto result = toMap.try_emplace(7, mapped_type(7)); // test fwding to copy-ctor - VERIFY(!result.second); - VERIFY(result.first->second == mapped_type(7)); - VERIFY(toMap.size() == 1); - - // we explicitly constructed an element for the parameter - // and one for the VERIFY check - ctorCount += 2; - VERIFY(ctorCount == TestObject::sTOCtorCount); - } - - { // verify duplicate not inserted - auto hint = toMap.find(7); - auto result = toMap.try_emplace(hint, 7, 7); // test fwding to conversion-ctor - VERIFY(result->first == 7); - VERIFY(result->second == mapped_type(7)); - VERIFY(toMap.size() == 1); - // we explicitly constructed an element for the VERIFY check - ++ctorCount; - VERIFY(ctorCount == TestObject::sTOCtorCount); - } - - { // verify duplicate not inserted - auto hint = toMap.find(7); - auto result = toMap.try_emplace(hint, 7, mapped_type(7)); // test fwding to copy-ctor - VERIFY(result->first == 7); - VERIFY(result->second == mapped_type(7)); - VERIFY(toMap.size() == 1); - - // we explicitly constructed an element for the parameter - // and one for the VERIFY check - ctorCount += 2; - VERIFY(ctorCount == TestObject::sTOCtorCount); - } - - { - { - auto result = toMap.try_emplace(8, 8); - // emplacing a new value should call exactly one constructor, - // when the value is constructed in place inside the container. - ++ctorCount; - VERIFY(result.second); - VERIFY(result.first->second == mapped_type(8)); - // One more constructor for the temporary in the VERIFY - ++ctorCount; - VERIFY(toMap.size() == 2); - VERIFY(ctorCount == TestObject::sTOCtorCount); - } - { - auto result = toMap.try_emplace(9, mapped_type(9)); - VERIFY(result.second); - VERIFY(result.first->second == mapped_type(9)); - VERIFY(toMap.size() == 3); - // one more constructor for the temporary argument, - // one for moving it to the container, and one for the VERIFY - ctorCount += 3; - VERIFY(ctorCount == TestObject::sTOCtorCount); - - } - } - } - - { - // eastl::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); - // eastl::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); - // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); - // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); - - TOMap toMap; - - { - // initial rvalue insert - auto result = toMap.insert_or_assign(3, mapped_type(3)); - VERIFY(result.second); - VERIFY(toMap.size() == 1); - VERIFY(result.first->first == 3); - VERIFY(result.first->second == mapped_type(3)); - - // verify rvalue assign occurred - result = toMap.insert_or_assign(3, mapped_type(9)); - VERIFY(!result.second); - VERIFY(toMap.size() == 1); - VERIFY(result.first->first == 3); - VERIFY(result.first->second == mapped_type(9)); - } - - { - mapped_type mt5(5); - mapped_type mt6(6); - mapped_type mt7(7); - - { - // initial lvalue insert - auto result = toMap.insert_or_assign(5, mt5); - VERIFY(result.second); - VERIFY(toMap.size() == 2); - VERIFY(result.first->first == 5); - VERIFY(result.first->second == mt5); - } - - { - // verify lvalue assign occurred - auto result = toMap.insert_or_assign(5, mt7); - VERIFY(!result.second); - VERIFY(toMap.size() == 2); - VERIFY(result.first->first == 5); - VERIFY(result.first->second == mt7); - } - - { - // verify lvalue hints - auto hint = toMap.find(5); - auto result = toMap.insert_or_assign(hint, 6, mt6); - VERIFY(result != toMap.end()); - VERIFY(toMap.size() == 3); - VERIFY(result->first == 6); - VERIFY(result->second == mt6); - } - - { - // verify rvalue hints - auto hint = toMap.find(6); - auto result = toMap.insert_or_assign(hint, 7, mapped_type(7)); - VERIFY(result != toMap.end()); - VERIFY(toMap.size() == 4); - VERIFY(result->first == 7); - VERIFY(result->second == mapped_type(7)); - } - } - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} - - -template<typename HashContainer> -struct HashContainerReserveTest -{ - int operator()() - { - int nErrorCount = 0; - - HashContainer hashContainer; - - const typename HashContainer::size_type reserve_sizes[] = {16, 128, 4096, 32768}; - for (auto& reserve_size : reserve_sizes) - { - hashContainer.reserve(reserve_size); - - // verify bucket count and hashtable load_factor requirements - VERIFY(hashContainer.bucket_count() >= reserve_size); - VERIFY(hashContainer.load_factor() <= ceilf(reserve_size / hashContainer.get_max_load_factor())); - } - - return nErrorCount; - } -}; - - - - - diff --git a/test/source/TestMemory.cpp b/test/source/TestMemory.cpp deleted file mode 100644 index 77caf9f..0000000 --- a/test/source/TestMemory.cpp +++ /dev/null @@ -1,775 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/memory.h> -#include <EASTL/utility.h> -#include <EASTL/vector.h> -#include <EAStdC/EAMemory.h> -#include <EAStdC/EAAlignment.h> - - -// Regression for user reported operator new problem (12/8/2009): -class AssetHandler -{ -public: - inline static void* operator new(size_t size, const char* /*text*/, unsigned int /*flags*/) - { - return ::operator new(size); - } - inline static void operator delete(void* p) - { - return ::operator delete(p); - } -}; -typedef eastl::vector<AssetHandler> AssetHandlerArray; - -// Regression test for a default memory fill optimization that defers to memset instead of explicitly -// value-initialization each element in a vector individually. This test ensures that the value of the memset is -// consistent with an explicitly value-initialized element (namely when the container holds a scalar value that is -// memset to zero). -template <typename T> -int TestValueInitOptimization() -{ - int nErrorCount = 0; - const int ELEM_COUNT = 100; - - { - eastl::vector<T> v1; - eastl::vector<ValueInitOf<T>> v2; - - v1.resize(ELEM_COUNT); - v2.resize(ELEM_COUNT); - - for (int i = 0; i < ELEM_COUNT; i++) - { EATEST_VERIFY(v1[i] == v2[i].get()); } - } - - { - eastl::vector<T> v1(ELEM_COUNT); - eastl::vector<ValueInitOf<T>> v2(ELEM_COUNT); - - for (int i = 0; i < ELEM_COUNT; i++) - { EATEST_VERIFY(v1[i] == v2[i].get()); } - } - - EATEST_VERIFY(nErrorCount == 0); - return nErrorCount; -} - - -// LCTestObject -// -// Helps test the late_constructed utility. -// Has an unusual alignment so we can test that aspect of late_constructed. -// -struct EA_ALIGN(64) LCTestObject -{ - int mX; // - static int64_t sTOCount; // Count of all current existing objects. - static int64_t sTOCtorCount; // Count of times any ctor was called. - static int64_t sTODtorCount; // Count of times dtor was called. - - explicit LCTestObject(int x = 0) - : mX(x) - { - ++sTOCount; - ++sTOCtorCount; - } - - LCTestObject(int x0, int x1, int x2) - : mX(x0 + x1 + x2) - { - ++sTOCount; - ++sTOCtorCount; - } - - LCTestObject(const LCTestObject& testObject) - : mX(testObject.mX) - { - ++sTOCount; - ++sTOCtorCount; - } - - #if !defined(EA_COMPILER_NO_RVALUE_REFERENCES) - LCTestObject(TestObject&& testObject) - : mX(testObject.mX) - { - ++sTOCount; - ++sTOCtorCount; - } - #endif - - LCTestObject& operator=(const LCTestObject& testObject) - { - mX = testObject.mX; - return *this; - } - - #if !defined(EA_COMPILER_NO_RVALUE_REFERENCES) - LCTestObject& operator=(LCTestObject&& testObject) - { - eastl::swap(mX, testObject.mX); - return *this; - } - #endif - - ~LCTestObject() - { - --sTOCount; - ++sTODtorCount; - } -}; - -int64_t LCTestObject::sTOCount = 0; -int64_t LCTestObject::sTOCtorCount = 0; -int64_t LCTestObject::sTODtorCount = 0; - - -eastl::late_constructed<LCTestObject, true, true> gLCTestObjectTrueTrue; -eastl::late_constructed<LCTestObject, false, true> gLCTestObjectFalseTrue; -eastl::late_constructed<LCTestObject, false, false> gLCTestObjectFalseFalse; -eastl::late_constructed<LCTestObject, true, false> gLCTestObjectTrueFalse; - -struct TypeWithPointerTraits {}; - -namespace eastl -{ - template <> - struct pointer_traits<TypeWithPointerTraits> - { - // Note: only parts of the traits we are interested to test are defined here. - static const int* to_address(TypeWithPointerTraits) - { - return &a; - } - - inline static constexpr int a = 42; - }; -} - - -/////////////////////////////////////////////////////////////////////////////// -// TestMemory -// -int TestMemory() -{ - using namespace eastl; - - int nErrorCount = 0; - - TestObject::Reset(); - - { - // get_temporary_buffer(ptrdiff_t n, size_t alignment, size_t alignmentOffset, char* pName); - - pair<int*, ptrdiff_t> pr1 = get_temporary_buffer<int>(100, 1, 0, EASTL_NAME_VAL("Temp int array")); - memset(pr1.first, 0, 100 * sizeof(int)); - return_temporary_buffer(pr1.first); - - // Note that - pair<TestObject*, ptrdiff_t> pr2 = get_temporary_buffer<TestObject>(300); - memset(pr2.first, 0, 300 * sizeof(TestObject)); - return_temporary_buffer(pr2.first, pr2.second); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - { - LCTestObject* pLCTO; - - LCTestObject::sTOCount = 0; - LCTestObject::sTOCtorCount = 0; - LCTestObject::sTODtorCount = 0; - - // Verify alignment requirements. - // We don't verify that gLCTestObjectTrueTrue.get() is aligned for all platforms because some platforms can't do that with global memory. - static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::value_type>::value == 64, "late_constructed alignment failure."); - static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::storage_type>::value == 64, "late_constructed alignment failure."); - static_assert(eastl::alignment_of<late_constructed<LCTestObject> >::value >= 64, "late_constructed alignment failure."); - - - // late_constructed / gLCTestObjectTrueTrue - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - EATEST_VERIFY(!gLCTestObjectTrueTrue.is_constructed()); - - pLCTO = gLCTestObjectTrueTrue.get(); // This will auto-construct LCTestObject. - EATEST_VERIFY(pLCTO != NULL); - EATEST_VERIFY(gLCTestObjectTrueTrue.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectTrueTrue->mX = 17; - EATEST_VERIFY(gLCTestObjectTrueTrue->mX == 17); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectTrueTrue.destruct(); - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1)); - EATEST_VERIFY(!gLCTestObjectTrueTrue.is_constructed()); - - gLCTestObjectTrueTrue->mX = 18; - EATEST_VERIFY(gLCTestObjectTrueTrue->mX == 18); - EATEST_VERIFY(gLCTestObjectTrueTrue.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1)); - - gLCTestObjectTrueTrue.destruct(); - (*gLCTestObjectTrueTrue).mX = 19; - EATEST_VERIFY(gLCTestObjectTrueTrue->mX == 19); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2)); - - gLCTestObjectTrueTrue.destruct(); - LCTestObject::sTOCount = 0; - LCTestObject::sTOCtorCount = 0; - LCTestObject::sTODtorCount = 0; - - // late_constructed / gLCTestObjectFalseTrue - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - EATEST_VERIFY(!gLCTestObjectFalseTrue.is_constructed()); - - pLCTO = gLCTestObjectFalseTrue.get(); // This will not auto-construct LCTestObject. - EATEST_VERIFY(pLCTO == NULL); - EATEST_VERIFY(!gLCTestObjectFalseTrue.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectFalseTrue.construct(); - pLCTO = gLCTestObjectFalseTrue.get(); - EATEST_VERIFY(pLCTO != NULL); - EATEST_VERIFY(gLCTestObjectFalseTrue.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectFalseTrue->mX = 17; - EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 17); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectFalseTrue.destruct(); - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1)); - EATEST_VERIFY(!gLCTestObjectFalseTrue.is_constructed()); - - gLCTestObjectFalseTrue.construct(14); - EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 14); - gLCTestObjectFalseTrue->mX = 18; - EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 18); - EATEST_VERIFY(gLCTestObjectFalseTrue.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1)); - - gLCTestObjectFalseTrue.destruct(); - gLCTestObjectFalseTrue.construct(10, 20, 30); - EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 10+20+30); - (*gLCTestObjectFalseTrue).mX = 19; - EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 19); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2)); - - gLCTestObjectFalseTrue.destruct(); - } - - { - LCTestObject* pLCTO; - - LCTestObject::sTOCount = 0; - LCTestObject::sTOCtorCount = 0; - LCTestObject::sTODtorCount = 0; - - // Verify alignment requirements. - // We don't verify that gLCTestObjectTrueTrue.get() is aligned for all platforms because some platforms can't do that with global memory. - static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::value_type>::value == 64, "late_constructed alignment failure."); - static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::storage_type>::value == 64, "late_constructed alignment failure."); - static_assert(eastl::alignment_of<late_constructed<LCTestObject> >::value >= 64, "late_constructed alignment failure."); - - - // late_constructed / gLCTestObjectTrueFalse - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - EATEST_VERIFY(!gLCTestObjectTrueFalse.is_constructed()); - - pLCTO = gLCTestObjectTrueFalse.get(); // This will auto-construct LCTestObject. - EATEST_VERIFY(pLCTO != NULL); - EATEST_VERIFY(gLCTestObjectTrueFalse.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectTrueFalse->mX = 17; - EATEST_VERIFY(gLCTestObjectTrueFalse->mX == 17); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectTrueFalse.destruct(); - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1)); - EATEST_VERIFY(!gLCTestObjectTrueFalse.is_constructed()); - - gLCTestObjectTrueFalse->mX = 18; - EATEST_VERIFY(gLCTestObjectTrueFalse->mX == 18); - EATEST_VERIFY(gLCTestObjectTrueFalse.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1)); - - gLCTestObjectTrueFalse.destruct(); - (*gLCTestObjectTrueFalse).mX = 19; - EATEST_VERIFY(gLCTestObjectTrueFalse->mX == 19); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2)); - - gLCTestObjectTrueFalse.destruct(); - LCTestObject::sTOCount = 0; - LCTestObject::sTOCtorCount = 0; - LCTestObject::sTODtorCount = 0; - - // late_constructed / gLCTestObjectFalseFalse - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed()); - - pLCTO = gLCTestObjectFalseFalse.get(); // This will not auto-construct LCTestObject. - EATEST_VERIFY(pLCTO == NULL); - EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectFalseFalse.construct(); - pLCTO = gLCTestObjectFalseFalse.get(); - EATEST_VERIFY(pLCTO != NULL); - EATEST_VERIFY(gLCTestObjectFalseFalse.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectFalseFalse->mX = 17; - EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 17); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - gLCTestObjectFalseFalse.destruct(); - EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1)); - EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed()); - - gLCTestObjectFalseFalse.construct(14); - EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 14); - gLCTestObjectFalseFalse->mX = 18; - EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 18); - EATEST_VERIFY(gLCTestObjectFalseFalse.is_constructed()); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1)); - - gLCTestObjectFalseFalse.destruct(); - gLCTestObjectFalseFalse.construct(10, 20, 30); - EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 10+20+30); - (*gLCTestObjectFalseFalse).mX = 19; - EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 19); - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2)); - - gLCTestObjectFalseFalse.destruct(); - } - - LCTestObject::sTOCount = 0; - LCTestObject::sTOCtorCount = 0; - LCTestObject::sTODtorCount = 0; - { - eastl::late_constructed<LCTestObject, true, false> lc; - lc.construct(); - } - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - LCTestObject::sTOCount = 0; - LCTestObject::sTOCtorCount = 0; - LCTestObject::sTODtorCount = 0; - { - eastl::late_constructed<LCTestObject, false, false> lc; - lc.construct(); - } - EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - - - // We use the vector container to supply a RandomAccessIterator. - // We use the list container to supply a BidirectionalIterator. - // We use the slist container to supply a ForwardIterator. - // We use our generic_input_iterator adapter to supply an InputIterator. - - // eastl::vector<int> intVector; - // eastl::list<int> intList; - // eastl::slist<int> intSlist; - - // template <typename ForwardIterator, typename ForwardIteratorDest> - // inline ForwardIteratorDest uninitialized_relocate_start(ForwardIterator first, ForwardIterator last, ForwardIteratorDest dest) - - // template <typename ForwardIterator, typename ForwardIteratorDest> - // inline ForwardIteratorDest uninitialized_relocate_commit(ForwardIterator first, ForwardIterator last, ForwardIteratorDest dest) - - // template <typename ForwardIterator, typename ForwardIteratorDest> - // inline ForwardIteratorDest uninitialized_relocate_abort(ForwardIterator first, ForwardIterator last, ForwardIteratorDest dest) - - // template <typename ForwardIterator, typename ForwardIteratorDest> - // inline ForwardIteratorDest uninitialized_relocate(ForwardIterator first, ForwardIterator last, ForwardIteratorDest dest) - - // This test does little more than verify that the code compiles. - int* pEnd = eastl::uninitialized_relocate_start<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL); - EATEST_VERIFY(pEnd == NULL); - - pEnd = eastl::uninitialized_relocate_commit<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL); - EATEST_VERIFY(pEnd == NULL); - - pEnd = eastl::uninitialized_relocate_abort<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL); - EATEST_VERIFY(pEnd == NULL); - - pEnd = eastl::uninitialized_relocate<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL); - EATEST_VERIFY(pEnd == NULL); - - - - // template <typename InputIterator, typename ForwardIterator> - // ForwardIterator uninitialized_copy(InputIterator sourceFirst, InputIterator sourceLast, ForwardIterator destination); - - pEnd = eastl::uninitialized_copy<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL); - EATEST_VERIFY(pEnd == NULL); - - - - // template <typename First, typename Last, typename Result> - // Result uninitialized_copy_ptr(First first, Last last, Result result) - - pEnd = eastl::uninitialized_copy_ptr<int*, int*, int*>((int*)NULL, (int*)NULL, (int*)NULL); - EATEST_VERIFY(pEnd == NULL); - - - - // template <typename ForwardIterator, typename T> - // void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& value) - - eastl::uninitialized_fill<int*, int>((int*)NULL, (int*)NULL, (int)0); - - - - // template <typename T> - // void uninitialized_fill_ptr(T* first, T* last, const T& value) - - eastl::uninitialized_fill_ptr<int>((int*)NULL, (int*)NULL, (int)0); - - - - // template <typename ForwardIterator, typename Count, typename T> - // void uninitialized_fill_n(ForwardIterator first, Count n, const T& value) - - eastl::uninitialized_fill_n<int*, int, int>((int*)NULL, (int)0, (int)0); - - - - // template <typename T, typename Count> - // void uninitialized_fill_n_ptr(T* first, Count n, const T& value) - - eastl::uninitialized_fill_n_ptr<int, int>((int*)NULL, (int)0, (int)0); - - - - - // template <typename InputIterator, typename ForwardIterator, typename T> - // void uninitialized_copy_fill(InputIterator first1, InputIterator last1, - // ForwardIterator first2, ForwardIterator last2, const T& value) - - eastl::uninitialized_copy_fill<int*, int*, int>((int*)NULL, (int*)NULL, (int*)NULL, (int*)NULL, (int)0); - - - - // template <typename ForwardIterator, typename T, typename InputIterator> - // ForwardIterator uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid, const T& value, InputIterator first, InputIterator last) - - eastl::uninitialized_fill_copy<int*, int, int*>((int*)NULL, (int*)NULL, (int)0, (int*)NULL, (int*)NULL); - - - - // template <typename InputIterator1, typename InputIterator2, typename ForwardIterator> - // ForwardIterator uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1, - // InputIterator2 first2, InputIterator2 last2, - // ForwardIterator result) - - eastl::uninitialized_copy_copy<int*, int*, int*>((int*)NULL, (int*)NULL, (int*)NULL, (int*)NULL, (int*)NULL); - - // uninitialized_default_construct - { - TestObject::Reset(); - char testCharArray[sizeof(TestObject) * 10]; - TestObject* pTestMemory = (TestObject*)(testCharArray); - - eastl::uninitialized_default_construct(pTestMemory, pTestMemory + 10); - EATEST_VERIFY(TestObject::sTODefaultCtorCount == 10); - } - - // uninitialized_default_construct_n - { - TestObject::Reset(); - char testCharArray[sizeof(TestObject) * 10]; - TestObject* pTestMemory = (TestObject*)(testCharArray); - - auto endIter = eastl::uninitialized_default_construct_n(pTestMemory, 5); - EATEST_VERIFY(TestObject::sTODefaultCtorCount == 5); - EATEST_VERIFY(endIter == (pTestMemory + 5)); - } - - // uninitialized_value_construct - { - TestObject::Reset(); - char testCharArray[sizeof(TestObject) * 10]; - TestObject* pTestMemory = (TestObject*)(testCharArray); - - eastl::uninitialized_value_construct(pTestMemory, pTestMemory + 10); - EATEST_VERIFY(TestObject::sTODefaultCtorCount == 10); - } - - // uninitialized_value_construct_n - { - TestObject::Reset(); - char testCharArray[sizeof(TestObject) * 10]; - TestObject* pTestMemory = (TestObject*)(testCharArray); - - auto endIter = eastl::uninitialized_value_construct_n(pTestMemory, 5); - EATEST_VERIFY(TestObject::sTODefaultCtorCount == 5); - EATEST_VERIFY(endIter == (pTestMemory + 5)); - } - - // Verify that uninitialized_value_construct does not do any additional initialization besides zero-initialization. - // - /// Value-Initialization: - // If T is a class, the object is default-initialized (after being zero-initialized if T's default - // constructor is not user-provided/deleted); otherwise, the object is zero-initialized. - { - struct foo - { - // foo() = default; // intentionally removed to force zero-initialization behavior - char mV; - }; - - static const int ARRAY_SIZE_IN_BYTES = sizeof(foo) * 10; - - char testCharArray[ARRAY_SIZE_IN_BYTES]; - EA::StdC::Memfill8(testCharArray, 42, ARRAY_SIZE_IN_BYTES); - foo* pTestMemory = (foo*)testCharArray; - - eastl::uninitialized_value_construct(pTestMemory, pTestMemory + 10); - - for (int i = 0; i < 10; i++) - { - EATEST_VERIFY(pTestMemory[i].mV == 0); // verify that memory is zero-initialized - } - } - - // Verify that uninitialized_default_construct does not do any additional initialization besides the calling of a empty - // constructor. - // - // Default-initialization: - // If T is a class, the default constructor is called; otherwise, no initialization is done, resulting in - // indeterminate values. - { - struct foo - { - foo() {} // default ctor intentionally a no-op - char mV; - }; - - static const int ARRAY_SIZE_IN_BYTES = sizeof(foo) * 10; - - char testCharArray[ARRAY_SIZE_IN_BYTES]; - EA::StdC::Memfill8(testCharArray, 42, ARRAY_SIZE_IN_BYTES); - foo* pTestMemory = (foo*)testCharArray; - - eastl::uninitialized_default_construct(pTestMemory, pTestMemory + 10); - - for (int i = 0; i < 10; i++) - { - EATEST_VERIFY(pTestMemory[i].mV == 42); // verify original memset value is intact - } - } - - // template <typename T> - // void destruct(T* p) - { - TestObject::Reset(); - uint64_t testObjectMemory[((sizeof(TestObject) / sizeof(uint64_t)) + 1) * 2]; - - TestObject* pTestObject = new(testObjectMemory) TestObject; - destruct(pTestObject); - EATEST_VERIFY(TestObject::IsClear()); - } - - // template <typename T> - // void destroy_at(T* p) - { - TestObject::Reset(); - uint64_t testObjectMemory[((sizeof(TestObject) / sizeof(uint64_t)) + 1) * 2]; - TestObject* pTestObject = new(testObjectMemory) TestObject; - destroy_at(pTestObject); - - EATEST_VERIFY(TestObject::IsClear()); - } - - - // template <typename ForwardIterator> - // void destruct(ForwardIterator first, ForwardIterator last) - { - TestObject::Reset(); - char testObjectMemory[sizeof(TestObject) * 3]; - TestObject* pTestObject = new(testObjectMemory) TestObject[2]; - destruct(pTestObject, pTestObject + 2); - - EATEST_VERIFY(TestObject::IsClear()); - } - - // template <typename ForwardIterator> - // void destroy(ForwardIterator first, ForwardIterator last) - { - TestObject::Reset(); - char testObjectMemory[sizeof(TestObject) * 3]; - TestObject* pTestObject = new(testObjectMemory) TestObject[2]; - destroy(pTestObject, pTestObject + 2); - - EATEST_VERIFY(TestObject::IsClear()); - } - - // template <typename ForwardIterator, typename Size> - // void destroy_n(ForwardIterator first, Size n) - { - TestObject::Reset(); - char testObjectMemory[sizeof(TestObject) * 3]; - TestObject* pTestObject = new (testObjectMemory) TestObject[2]; - - destroy_n(pTestObject, 1); // destroy TestObject[0] - destroy_n(pTestObject + 1, 1); // destroy TestObject[1] - - EATEST_VERIFY(TestObject::IsClear()); - } - - - { - // Regression for user reported operator new problem (12/8/2009): - eastl::vector<AssetHandler> ahArray; - ahArray.push_back(AssetHandler()); - } - - - // void* align(size_t alignment, size_t size, void*& ptr, size_t& space); - // void* align_advance(size_t alignment, size_t size, void*& ptr, size_t& space); - { - const size_t kBufferSize = 256; - char buffer[kBufferSize * 2]; - size_t space = sizeof(buffer); - void* ptr = buffer; - void* ptrSaved; - void* ptrAligned; - size_t i; - - // First get 256 bytes of space aligned to 256. - // It's a coincidence that we are using eastl::align to set up a buffer for testing eastl::align below. - ptrSaved = eastl::align(256, 256, ptr, space); - - // At this point we have 256 bytes of memory aligned on 256 bytes, within buffer. - // We test allocating multiple blocks from this space at various alignments values. - // We also test that the function sets ptr to the next available location after the - // returned allocated block. - EA::StdC::Memset8(buffer, 0x00, sizeof(buffer)); - EATEST_VERIFY(EA::StdC::IsAligned(ptr, 256)); - - // align test - // Try a number of allocation sizes. - for(size_t a = 1; a < 64; a *= 2) - { - // Do multiple sequental allocations from the storage. - for(i = 0, space = 256, ptr = ptrSaved; i < kBufferSize; i += a) - { - ptrAligned = eastl::align(a, a, ptr, space); - - EATEST_VERIFY((uintptr_t)ptrAligned == ((uintptr_t)ptrSaved + i)); - EATEST_VERIFY(ptr == ptrAligned); - EATEST_VERIFY(space == (kBufferSize - i)); - EATEST_VERIFY(EA::StdC::IsAligned(ptrAligned, a)); - EATEST_VERIFY(EA::StdC::Memcheck8(ptrAligned, 0x00, a) == NULL); - - ptr = (char*)ptr + a; - space -= a; - memset(ptrAligned, 0xff, a); // Do this so that next time around we can verify this memory isn't returned. - } - - EA::StdC::Memset8(buffer, 0x00, sizeof(buffer)); - } - - // align_advance test (similar to but not identical to the align test) - // Try a number of allocation sizes. - for(size_t a = 1; a < 64; a *= 2) - { - // Do multiple sequental allocations from the storage. - for(i = 0, space = 256, ptr = ptrSaved; i < kBufferSize; i += a) - { - ptrAligned = eastl::align_advance(a, a, ptr, space, &ptr, &space); - - EATEST_VERIFY((uintptr_t)ptrAligned == ((uintptr_t)ptrSaved + i)); - EATEST_VERIFY((uintptr_t)ptr == (uintptr_t)ptrAligned + a); - EATEST_VERIFY(space == (kBufferSize - i) - a); - EATEST_VERIFY(EA::StdC::IsAligned(ptrAligned, a)); - EATEST_VERIFY(EA::StdC::Memcheck8(ptrAligned, 0x00, a) == NULL); - - memset(ptrAligned, 0xff, a); // Do this so that next time around we can verify this memory isn't returned. - } - - EA::StdC::Memset8(buffer, 0x00, sizeof(buffer)); - } - } - - // to_address - { - // Normal pointers. - int a; - int* ptrA = &a; - EATEST_VERIFY(ptrA == to_address(ptrA)); - - // Smart pointer. - struct MockSmartPointer - { - const int* operator->() const - { - return &a; - } - - int a = 42; - }; - - MockSmartPointer sp; - EATEST_VERIFY(&sp.a == to_address(sp)); - - // Type with specialized pointer_traits. - TypeWithPointerTraits t; - const int* result = to_address(t); - EATEST_VERIFY(result != nullptr && *result == 42); - } - - { - // Test that align handles integral overflow correctly and returns NULL. - void* ptr; - void* ptrSaved; - size_t space; - void* pResult; - - space = 64; - ptr = 0; - ptr = (char*)ptr - space; - ptrSaved = ptr; - pResult = eastl::align(1, space + 1, ptr, space); // Possible alignment, impossible size due to wraparound. - EATEST_VERIFY((pResult == NULL) && (ptr == ptrSaved)); - - space = 64; - ptr = 0; - ptr = (char*)ptr - space; - ptrSaved = ptr; - pResult = eastl::align(space * 2, 32, ptr, space); // Impossible alignment due to wraparound, possible size. - EATEST_VERIFY((pResult == NULL) && (ptr == ptrSaved)); - } - - { - nErrorCount += TestValueInitOptimization<int>(); - nErrorCount += TestValueInitOptimization<char>(); - nErrorCount += TestValueInitOptimization<short>(); - nErrorCount += TestValueInitOptimization<float>(); - nErrorCount += TestValueInitOptimization<double>(); - nErrorCount += TestValueInitOptimization<void*>(); - } - - EATEST_VERIFY(nErrorCount == 0); - return nErrorCount; -} - - - - - - - - - - - diff --git a/test/source/TestMeta.cpp b/test/source/TestMeta.cpp deleted file mode 100644 index 8d2e9d1..0000000 --- a/test/source/TestMeta.cpp +++ /dev/null @@ -1,120 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" - -#ifdef EA_COMPILER_CPP14_ENABLED -#include "ConceptImpls.h" -#include <EASTL/meta.h> - - -int TestGetTypeIndex() -{ - using namespace eastl; - - int nErrorCount = 0; - - static_assert(meta::get_type_index_v<short, short, char, int> == 0, "error"); - static_assert(meta::get_type_index_v<char, short, char, int> == 1, "error"); - static_assert(meta::get_type_index_v<int, short, char, int> == 2, "error"); - static_assert(meta::get_type_index_v<int, int, int, int> == 0, "error"); - - return nErrorCount; -} - -int TestGetType() -{ - using namespace eastl; - - int nErrorCount = 0; - - static_assert(is_same_v<meta::get_type_at_t<2, short, short, char, int>, char>, "error"); - static_assert(is_same_v<meta::get_type_at_t<3, char, short, char, int>, int>, "error"); - // static_assert(is_same_v<meta::get_type_at_t<4, int, short, char, int>, int>, "error"); - static_assert(is_same_v<meta::get_type_at_t<1, int, int, int, int>, int>, "error"); - - return nErrorCount; -} - -int TestTypeCount() -{ - using namespace eastl; - - int nErrorCount = 0; - - static_assert(meta::type_count_v<short, short, char, int> == 1, "error"); - static_assert(meta::type_count_v<char, short, char, int> == 1, "error"); - static_assert(meta::type_count_v<int, short, char, int> == 1, "error"); - static_assert(meta::type_count_v<int, int, int, int> == 3, "error"); - static_assert(meta::type_count_v<int, int, int, int, int, int, int, int, int> == 8, "error"); - static_assert(meta::type_count_v<int, int, int, int, char, int, int, int, int> == 7, "error"); - static_assert(meta::type_count_v<int, int, char, int, char, int, int, int, int> == 6, "error"); - static_assert(meta::type_count_v<int, int, char, int, char, int, int, int, char> == 5, "error"); - static_assert(meta::type_count_v<int, int, char, int, char, int, const int, int, char> == 4, "error"); - static_assert(meta::type_count_v<int, volatile int, char, int, char, int, const int, const volatile int, char> == 2, "error"); - - return nErrorCount; -} - -int TestDuplicateTypeCheck() -{ - using namespace eastl; - - int nErrorCount = 0; - - static_assert( meta::duplicate_type_check_v<short, short, char, int>, "error"); - static_assert( meta::duplicate_type_check_v<short, short, char, int, long, unsigned, long long>, "error"); - static_assert( meta::duplicate_type_check_v<int, const int, volatile int, const volatile int, int>, "error"); - static_assert(!meta::duplicate_type_check_v<short, short, char, int, long, unsigned, short, long long>, "error"); - - return nErrorCount; -} - -int TestOverloadResolution() -{ - using namespace eastl; - using namespace eastl::meta; - - int nErrorCount = 0; - - static_assert(is_same_v<overload_resolution_t<int, overload_set<int>>, int>, "error"); - static_assert(is_same_v<overload_resolution_t<int, overload_set<short>>, short>, "error"); - static_assert(is_same_v<overload_resolution_t<int, overload_set<long>>, long>, "error"); - static_assert(is_same_v<overload_resolution_t<short, overload_set<int>>, int>, "error"); - static_assert(is_same_v<overload_resolution_t<int, overload_set<int, short, long>>, int>, "error"); - static_assert(is_same_v<overload_resolution_t<int, overload_set<short, int, long, float>>, int>, "error"); - static_assert(is_same_v<overload_resolution_t<int, overload_set<short, long, int, float, char>>, int>, "error"); - - static_assert(is_same_v<overload_resolution_t<int, overload_set<int>>, int>, "error"); - static_assert(is_same_v<overload_resolution_t<int, overload_set<int, short>>, int>, "error"); - static_assert(is_same_v<overload_resolution_t<int, overload_set<int, short, long>>, int>, "error"); - - return nErrorCount; -} - - -int TestMeta() -{ - int nErrorCount = 0; - - nErrorCount += TestGetTypeIndex(); - nErrorCount += TestGetType(); - nErrorCount += TestTypeCount(); - nErrorCount += TestDuplicateTypeCheck(); - nErrorCount += TestOverloadResolution(); - - return nErrorCount; -} - -#endif // EA_COMPILER_CPP14_ENABLED - - - - - - - - - diff --git a/test/source/TestNumericLimits.cpp b/test/source/TestNumericLimits.cpp deleted file mode 100644 index 1964442..0000000 --- a/test/source/TestNumericLimits.cpp +++ /dev/null @@ -1,159 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/numeric_limits.h> - - -struct NonNumericType -{ - NonNumericType(int value) : mValue(value){} - bool operator==(int value) const { return mValue == value; } - int mValue; // This exists for the purpose of allowing the type to act like a number and allow the test logic below to work. -}; - - -/////////////////////////////////////////////////////////////////////////////// -// TestNumericLimits -// -int TestNumericLimits() -{ - int nErrorCount = 0; - - // To consider: Some day when we get more time, make a big table-driven set of - // expected results to all member variables and function calls. - - // Test a type that is not numeric,. - EATEST_VERIFY(!eastl::numeric_limits<NonNumericType>::is_bounded); - EATEST_VERIFY( eastl::numeric_limits<NonNumericType>::max() == 0); - - EATEST_VERIFY(!eastl::numeric_limits<const NonNumericType>::is_bounded); - EATEST_VERIFY( eastl::numeric_limits<const NonNumericType>::max() == 0); - - EATEST_VERIFY(!eastl::numeric_limits<volatile NonNumericType>::is_bounded); - EATEST_VERIFY( eastl::numeric_limits<volatile NonNumericType>::max() == 0); - - EATEST_VERIFY(!eastl::numeric_limits<const volatile NonNumericType>::is_bounded); - EATEST_VERIFY( eastl::numeric_limits<const volatile NonNumericType>::max() == 0); - - // Test bool in all const-volatile variants. - EATEST_VERIFY(eastl::numeric_limits<bool>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<bool>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<const bool>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<const bool>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<volatile bool>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<volatile bool>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<const volatile bool>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<const volatile bool>::max() != 0); - - // Do basic tests of the remaining types. - EATEST_VERIFY(eastl::numeric_limits<char>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<char>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<unsigned char>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<unsigned char>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<signed char>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<signed char>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<wchar_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<wchar_t>::max() != 0); - - #if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE - EATEST_VERIFY(eastl::numeric_limits<char8_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<char8_t>::max() != 0); - #endif - - EATEST_VERIFY(eastl::numeric_limits<char16_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<char16_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<char32_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<char32_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<unsigned short>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<unsigned short>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<signed short>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<signed short>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<unsigned int>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<unsigned int>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<signed int>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<signed int>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<unsigned long>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<unsigned long>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<signed long>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<signed long>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<unsigned long long>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<unsigned long long>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<signed long long>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<signed long long>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<float>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<float>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<double>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<double>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<long double>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<long double>::max() != 0); - - // We don't yet have a generic global way to identify what the name of the supported 128 bit type is. - // We just happen to know that for gcc/clang it is __int128. - #if (EA_COMPILER_INTMAX_SIZE >= 16) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) // If __int128_t/__uint128_t is supported... - EATEST_VERIFY(eastl::numeric_limits<__uint128_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<__uint128_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<__int128_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<__int128_t>::max() != 0); - #endif - - // Test sized types. - EATEST_VERIFY(eastl::numeric_limits<uint8_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<uint8_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<int8_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<int8_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<uint16_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<uint16_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<int16_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<int16_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<uint32_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<uint32_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<int32_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<int32_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<uint64_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<uint64_t>::max() != 0); - - EATEST_VERIFY(eastl::numeric_limits<int64_t>::is_bounded); - EATEST_VERIFY(eastl::numeric_limits<int64_t>::max() != 0); - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestOptional.cpp b/test/source/TestOptional.cpp deleted file mode 100644 index 36307ad..0000000 --- a/test/source/TestOptional.cpp +++ /dev/null @@ -1,695 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EASTL/type_traits.h> -#include <EASTL/sort.h> -#include <EASTL/vector.h> -#include <EASTL/string.h> -#include <EASTL/optional.h> -#include <EASTL/unique_ptr.h> - - -///////////////////////////////////////////////////////////////////////////// -struct IntStruct -{ - IntStruct(int in) : data(in) {} - int data; -}; - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) -auto operator<=>(const IntStruct& lhs, const IntStruct& rhs) { return lhs.data <=> rhs.data; } -#else -bool operator<(const IntStruct& lhs, const IntStruct& rhs) - { return lhs.data < rhs.data; } -#endif -bool operator==(const IntStruct& lhs, const IntStruct& rhs) - { return lhs.data == rhs.data; } - - - -///////////////////////////////////////////////////////////////////////////// -struct destructor_test -{ - ~destructor_test() { destructor_ran = true; } - static bool destructor_ran; - static void reset() { destructor_ran = false; } -}; -bool destructor_test::destructor_ran = false; - -///////////////////////////////////////////////////////////////////////////// -struct move_test -{ - move_test() = default; - move_test(move_test&&) { was_moved = true; } - move_test& operator=(move_test&&) { was_moved = true; return *this;} - - // issue a compiler error is container tries to copy - move_test(move_test const&) = delete; - move_test& operator=(const move_test&) = delete; - - static bool was_moved; -}; - -bool move_test::was_moved = false; - -///////////////////////////////////////////////////////////////////////////// -template <typename T> -class forwarding_test -{ - eastl::optional<T> m_optional; - -public: - forwarding_test() : m_optional() {} - forwarding_test(T&& t) : m_optional(t) {} - ~forwarding_test() { m_optional.reset(); } - - template <typename U> - T GetValueOrDefault(U&& def) const - { - return m_optional.value_or(eastl::forward<U>(def)); - } -}; - -///////////////////////////////////////////////////////////////////////////// -struct assignment_test -{ - assignment_test() { ++num_objects_inited; } - assignment_test(assignment_test&&) { ++num_objects_inited; } - assignment_test(const assignment_test&) { ++num_objects_inited; } - assignment_test& operator=(assignment_test&&) { return *this; } - assignment_test& operator=(const assignment_test&) { return *this; } - ~assignment_test() { --num_objects_inited; } - - static int num_objects_inited; -}; - -int assignment_test::num_objects_inited = 0; - - -///////////////////////////////////////////////////////////////////////////// -// TestOptional -// -int TestOptional() -{ - using namespace eastl; - int nErrorCount = 0; - #if defined(EASTL_OPTIONAL_ENABLED) && EASTL_OPTIONAL_ENABLED - { - { - VERIFY( (is_same<optional<int>::value_type, int>::value)); - VERIFY( (is_same<optional<short>::value_type, short>::value)); - VERIFY(!(is_same<optional<short>::value_type, long>::value)); - VERIFY( (is_same<optional<const short>::value_type, const short>::value)); - VERIFY( (is_same<optional<volatile short>::value_type, volatile short>::value)); - VERIFY( (is_same<optional<const volatile short>::value_type, const volatile short>::value)); - - VERIFY(is_empty<nullopt_t>::value); - #if EASTL_TYPE_TRAIT_is_literal_type_CONFORMANCE - VERIFY(is_literal_type<nullopt_t>::value); - #endif - - #if EASTL_TYPE_TRAIT_is_trivially_destructible_CONFORMANCE - VERIFY(is_trivially_destructible<int>::value); - VERIFY(is_trivially_destructible<Internal::optional_storage<int>>::value); - VERIFY(is_trivially_destructible<optional<int>>::value); - VERIFY(is_trivially_destructible<optional<int>>::value == is_trivially_destructible<int>::value); - #endif - - { - struct NotTrivialDestructible { ~NotTrivialDestructible() {} }; - VERIFY(!is_trivially_destructible<NotTrivialDestructible>::value); - VERIFY(!is_trivially_destructible<optional<NotTrivialDestructible>>::value); - VERIFY(!is_trivially_destructible<Internal::optional_storage<NotTrivialDestructible>>::value); - VERIFY(is_trivially_destructible<optional<NotTrivialDestructible>>::value == is_trivially_destructible<NotTrivialDestructible>::value); - } - } - - { - optional<int> o; - VERIFY(!o); - VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D); - o = 1024; - VERIFY(static_cast<bool>(o)); - VERIFY(o.value_or(0x8BADF00D) == 1024); - VERIFY(o.value() == 1024); - - // Test reset - o.reset(); - VERIFY(!o); - VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D); - } - - { - optional<int> o(nullopt); - VERIFY(!o); - VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D); - } - - { - optional<int> o = {}; - VERIFY(!o); - VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D); - } - - { - optional<int> o(42); - VERIFY(bool(o)); - VERIFY(o.value_or(0x8BADF00D) == 42); - o = nullopt; - VERIFY(!o); - VERIFY(o.value_or(0x8BADF00D) == (int)0x8BADF00D); - } - - { - optional<int> o(42); - VERIFY(static_cast<bool>(o)); - VERIFY(o.value_or(0x8BADF00D) == 42); - VERIFY(o.value() == 42); - } - - { - auto o = make_optional(42); - VERIFY((is_same<decltype(o), optional<int>>::value)); - VERIFY(static_cast<bool>(o)); - VERIFY(o.value_or(0x8BADF00D) == 42); - VERIFY(o.value() == 42); - } - - { - int a = 42; - auto o = make_optional(a); - VERIFY((is_same<decltype(o)::value_type, int>::value)); - VERIFY(o.value() == 42); - } - - { - // test make_optional stripping refs/cv-qualifers - int a = 42; - const volatile int& intRef = a; - auto o = make_optional(intRef); - VERIFY((is_same<decltype(o)::value_type, int>::value)); - VERIFY(o.value() == 42); - } - - { - int a = 10; - const volatile int& aRef = a; - auto o = eastl::make_optional(aRef); - VERIFY(o.value() == 10); - } - - { - { - struct local { int payload1; }; - auto o = eastl::make_optional<local>(42); - VERIFY(o.value().payload1 == 42); - } - { - struct local { int payload1; int payload2; }; - auto o = eastl::make_optional<local>(42, 43); - VERIFY(o.value().payload1 == 42); - VERIFY(o.value().payload2 == 43); - } - - { - struct local - { - local(std::initializer_list<int> ilist) - { - payload1 = ilist.begin()[0]; - payload2 = ilist.begin()[1]; - } - - int payload1; - int payload2; - }; - - auto o = eastl::make_optional<local>({42, 43}); - VERIFY(o.value().payload1 == 42); - VERIFY(o.value().payload2 == 43); - } - } - - { - optional<int> o1(42), o2(24); - VERIFY(o1.value() == 42); - VERIFY(o2.value() == 24); - VERIFY(*o1 == 42); - VERIFY(*o2 == 24); - o1 = eastl::move(o2); - VERIFY(*o2 == 24); - VERIFY(*o1 == 24); - VERIFY(o2.value() == 24); - VERIFY(o1.value() == 24); - VERIFY(bool(o1)); - VERIFY(bool(o2)); - } - - { - struct local { int payload; }; - optional<local> o = local{ 42 }; - VERIFY(o->payload == 42); - } - - { - struct local - { - int test() const { return 42; } - }; - - { - const optional<local> o = local{}; - VERIFY(o->test() == 42); - VERIFY((*o).test() == 42); - VERIFY(o.value().test() == 42); - VERIFY(bool(o)); - } - - { - optional<local> o = local{}; - VERIFY(bool(o)); - o = nullopt; - VERIFY(!bool(o)); - - VERIFY(o.value_or(local{}).test() == 42); - VERIFY(!bool(o)); - } - } - } - - { - move_test t; - optional<move_test> o(eastl::move(t)); - VERIFY(move_test::was_moved); - } - - { - forwarding_test<float>ft(1.f); - float val = ft.GetValueOrDefault(0.f); - VERIFY(val == 1.f); - } - - { - assignment_test::num_objects_inited = 0; - { - optional<assignment_test> o1; - optional<assignment_test> o2 = assignment_test(); - optional<assignment_test> o3(o2); - VERIFY(assignment_test::num_objects_inited == 2); - o1 = nullopt; - VERIFY(assignment_test::num_objects_inited == 2); - o1 = o2; - VERIFY(assignment_test::num_objects_inited == 3); - o1 = o2; - VERIFY(assignment_test::num_objects_inited == 3); - o1 = nullopt; - VERIFY(assignment_test::num_objects_inited == 2); - o2 = o1; - VERIFY(assignment_test::num_objects_inited == 1); - o1 = o2; - VERIFY(assignment_test::num_objects_inited == 1); - } - VERIFY(assignment_test::num_objects_inited == 0); - - { - optional<assignment_test> o1; - VERIFY(assignment_test::num_objects_inited == 0); - o1 = nullopt; - VERIFY(assignment_test::num_objects_inited == 0); - o1 = optional<assignment_test>(assignment_test()); - VERIFY(assignment_test::num_objects_inited == 1); - o1 = optional<assignment_test>(assignment_test()); - VERIFY(assignment_test::num_objects_inited == 1); - optional<assignment_test> o2(eastl::move(o1)); - VERIFY(assignment_test::num_objects_inited == 2); - o1 = nullopt; - VERIFY(assignment_test::num_objects_inited == 1); - } - VERIFY(assignment_test::num_objects_inited == 0); - } - - #if EASTL_VARIADIC_TEMPLATES_ENABLED - { - struct vec3 - { - vec3(std::initializer_list<float> ilist) { auto* p = ilist.begin(); x = *p++; y = *p++; z = *p++; } - vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} // testing variadic template constructor overload - float x = 0, y = 0, z = 0; - }; - - { - optional<vec3> o{ in_place, 4.f, 5.f, 6.f }; - VERIFY(o->x == 4 && o->y == 5 && o->z == 6); - } - - { - optional<vec3> o{ in_place, {4.f, 5.f, 6.f} }; - VERIFY(o->x == 4 && o->y == 5 && o->z == 6); - } - - { - optional<string> o(in_place, {'a', 'b', 'c'}); - VERIFY(o == string("abc")); - } - - // http://en.cppreference.com/w/cpp/utility/optional/emplace - { - optional<vec3> o; - o.emplace(42.f, 42.f, 42.f); - VERIFY(o->x == 42.f && o->y == 42.f && o->z == 42.f); - } - - { - optional<vec3> o; - o.emplace({42.f, 42.f, 42.f}); - VERIFY(o->x == 42.f && o->y == 42.f && o->z == 42.f); - } - - { - optional<int> o; - o.emplace(42); - VERIFY(*o == 42); - } - - struct nonCopyableNonMovable - { - nonCopyableNonMovable(int v) : val(v) {} - - nonCopyableNonMovable(const nonCopyableNonMovable&) = delete; - nonCopyableNonMovable(nonCopyableNonMovable&&) = delete; - nonCopyableNonMovable& operator=(const nonCopyableNonMovable&) = delete; - - int val = 0; - }; - - { - optional<nonCopyableNonMovable> o; - o.emplace(42); - VERIFY(o->val == 42); - } - - { - // Verify emplace will destruct object if it has been engaged. - destructor_test::reset(); - optional<destructor_test> o; - o.emplace(); - VERIFY(!destructor_test::destructor_ran); - - destructor_test::reset(); - o.emplace(); - VERIFY(destructor_test::destructor_ran); - } - } - #endif - - - // swap - { - { - optional<int> o1 = 42, o2 = 24; - VERIFY(*o1 == 42); - VERIFY(*o2 == 24); - o1.swap(o2); - VERIFY(*o1 == 24); - VERIFY(*o2 == 42); - } - - { - optional<int> o1 = 42, o2 = 24; - VERIFY(*o1 == 42); - VERIFY(*o2 == 24); - swap(o1, o2); - VERIFY(*o1 == 24); - VERIFY(*o2 == 42); - } - - { - optional<int> o1 = 42, o2; - VERIFY(*o1 == 42); - VERIFY(o2.has_value() == false); - swap(o1, o2); - VERIFY(o1.has_value() == false); - VERIFY(*o2 == 42); - } - - { - optional<int> o1 = nullopt, o2 = 42; - VERIFY(o1.has_value() == false); - VERIFY(*o2 == 42); - swap(o1, o2); - VERIFY(*o1 == 42); - VERIFY(o2.has_value() == false); - } - } - - { - optional<IntStruct> o(in_place, 10); - optional<IntStruct> e; - - VERIFY(o < IntStruct(42)); - VERIFY(!(o < IntStruct(2))); - VERIFY(!(o < IntStruct(10))); - VERIFY(e < o); - VERIFY(e < IntStruct(10)); - - VERIFY(o > IntStruct(4)); - VERIFY(!(o > IntStruct(42))); - - VERIFY(o >= IntStruct(4)); - VERIFY(o >= IntStruct(10)); - VERIFY(IntStruct(4) <= o); - VERIFY(IntStruct(10) <= o); - - VERIFY(o == IntStruct(10)); - VERIFY(o->data == IntStruct(10).data); - - VERIFY(o != IntStruct(11)); - VERIFY(o->data != IntStruct(11).data); - - VERIFY(e == nullopt); - VERIFY(nullopt == e); - - VERIFY(o != nullopt); - VERIFY(nullopt != o); - VERIFY(nullopt < o); - VERIFY(o > nullopt); - VERIFY(!(nullopt > o)); - VERIFY(!(o < nullopt)); - VERIFY(nullopt <= o); - VERIFY(o >= nullopt); - } - - #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - optional<IntStruct> o(in_place, 10); - optional<IntStruct> e; - - VERIFY((o <=> IntStruct(42)) < 0); - VERIFY((o <=> IntStruct(2)) >= 0); - VERIFY((o <=> IntStruct(10)) >= 0); - VERIFY((e <=> o) < 0); - VERIFY((e <=> IntStruct(10)) < 0); - - VERIFY((o <=> IntStruct(4)) > 0); - VERIFY(o <=> IntStruct(42) <= 0); - - VERIFY((o <=> IntStruct(4)) >= 0); - VERIFY((o <=> IntStruct(10)) >= 0); - VERIFY((IntStruct(4) <=> o) <= 0); - VERIFY((IntStruct(10) <=> o) <= 0); - - VERIFY((o <=> IntStruct(10)) == 0); - VERIFY((o->data <=> IntStruct(10).data) == 0); - - VERIFY((o <=> IntStruct(11)) != 0); - VERIFY((o->data <=> IntStruct(11).data) != 0); - - VERIFY((e <=> nullopt) == 0); - VERIFY((nullopt <=> e) == 0); - - VERIFY((o <=> nullopt) != 0); - VERIFY((nullopt <=> o) != 0); - VERIFY((nullopt <=> o) < 0); - VERIFY((o <=> nullopt) > 0); - VERIFY((nullopt <=> o) <= 0); - VERIFY((o <=> nullopt) >= 0); - } - #endif - - // hash - { - { - // verify that the hash an empty eastl::optional object is zero. - typedef hash<optional<int>> hash_optional_t; - optional<int> e; - VERIFY(hash_optional_t{}(e) == 0); - } - - { - // verify that the hash is the same as the hash of the underlying type - const char* const pMessage = "Electronic Arts Canada"; - typedef hash<optional<string>> hash_optional_t; - optional<string> o = string(pMessage); - VERIFY(hash_optional_t{}(o) == hash<string>{}(pMessage)); - } - } - - // sorting - { - vector<optional<int>> v = {{122}, {115}, nullopt, {223}}; - sort(begin(v), end(v)); - vector<optional<int>> sorted = {nullopt, 115, 122, 223}; - - VERIFY(v == sorted); - } - - // test destructors being called. - { - destructor_test::reset(); - { - optional<destructor_test> o = destructor_test{}; - } - VERIFY(destructor_test::destructor_ran); - - destructor_test::reset(); - { - optional<destructor_test> o; - } - // destructor shouldn't be called as object wasn't constructed. - VERIFY(!destructor_test::destructor_ran); - - - destructor_test::reset(); - { - optional<destructor_test> o = {}; - } - // destructor shouldn't be called as object wasn't constructed. - VERIFY(!destructor_test::destructor_ran); - - destructor_test::reset(); - { - optional<destructor_test> o = nullopt; - } - // destructor shouldn't be called as object wasn't constructed. - VERIFY(!destructor_test::destructor_ran); - } - - // optional rvalue tests - { - VERIFY(*optional<uint32_t>(1u) == 1u); - VERIFY(optional<uint32_t>(1u).value() == 1u); - VERIFY(optional<uint32_t>(1u).value_or(0xdeadf00d) == 1u); - VERIFY(optional<uint32_t>().value_or(0xdeadf00d) == 0xdeadf00d); - VERIFY(optional<uint32_t>(1u).has_value() == true); - VERIFY(optional<uint32_t>().has_value() == false); - VERIFY( optional<IntStruct>(in_place, 10)->data == 10); - - } - - // alignment type tests - { - static_assert(alignof(optional<Align16>) == alignof(Align16), "optional alignment failure"); - static_assert(alignof(optional<Align32>) == alignof(Align32), "optional alignment failure"); - static_assert(alignof(optional<Align64>) == alignof(Align64), "optional alignment failure"); - } - - { - // user reported regression that failed to compile - struct local_struct - { - local_struct() {} - ~local_struct() {} - }; - static_assert(!eastl::is_trivially_destructible_v<local_struct>, ""); - - { - local_struct ls; - eastl::optional<local_struct> o{ls}; - } - { - const local_struct ls; - eastl::optional<local_struct> o{ls}; - } - } - - { - { - // user regression - eastl::optional<eastl::string> o = eastl::string("Hello World"); - eastl::optional<eastl::string> co; - - co = o; // force copy-assignment - - VERIFY( o.value().data() != co.value().data()); - VERIFY( o.value().data() == eastl::string("Hello World")); - VERIFY(co.value().data() == eastl::string("Hello World")); - } - { - // user regression - EA_DISABLE_VC_WARNING(4625 4626) // copy/assignment operator constructor was implicitly defined as deleted - struct local - { - eastl::unique_ptr<int> ptr; - }; - EA_RESTORE_VC_WARNING() - - eastl::optional<local> o1 = local{eastl::make_unique<int>(42)}; - eastl::optional<local> o2; - - o2 = eastl::move(o1); - - VERIFY(!!o1 == true); - VERIFY(!!o2 == true); - VERIFY(!!o1->ptr == false); - VERIFY(!!o2->ptr == true); - VERIFY(o2->ptr.get() != nullptr); - } - { - // user regression - static bool copyCtorCalledWithUninitializedValue; - static bool moveCtorCalledWithUninitializedValue; - copyCtorCalledWithUninitializedValue = moveCtorCalledWithUninitializedValue = false; - struct local - { - uint32_t val; - local() - : val(0xabcdabcd) - {} - local(const local& other) - : val(other.val) - { - if (other.val != 0xabcdabcd) - copyCtorCalledWithUninitializedValue = true; - } - local(local&& other) - : val(eastl::move(other.val)) - { - if (other.val != 0xabcdabcd) - moveCtorCalledWithUninitializedValue = true; - } - local& operator=(const local&) = delete; - }; - eastl::optional<local> n; - eastl::optional<local> o1(n); - VERIFY(!copyCtorCalledWithUninitializedValue); - eastl::optional<local> o2(eastl::move(n)); - VERIFY(!moveCtorCalledWithUninitializedValue); - } - } - - { - auto testFn = []() -> optional<int> - { - return eastl::nullopt; - }; - - auto o = testFn(); - VERIFY(!!o == false); - } - - #endif // EASTL_OPTIONAL_ENABLED - return nErrorCount; -} - diff --git a/test/source/TestRandom.cpp b/test/source/TestRandom.cpp deleted file mode 100644 index cefd7a5..0000000 --- a/test/source/TestRandom.cpp +++ /dev/null @@ -1,168 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#if defined(_MSC_VER) - //#pragma warning(disable: 4267) // 'argument' : conversion from 'size_t' to 'uint32_t', possible loss of data. -#endif - - -#include "EASTLTest.h" -#include <EASTL/numeric_limits.h> -#include <EASTL/set.h> -#include <EASTL/random.h> - - -struct GeneratorUint8 -{ - uint8_t mValue; - GeneratorUint8() : mValue(0) {} - uint8_t operator()(){ return mValue++; } // This is a pretty bad random number generator, but works for our tests. -}; - -struct GeneratorUint16 -{ - uint16_t mValue; - GeneratorUint16() : mValue(0) {} - uint16_t operator()(){ return mValue++; } -}; - -struct GeneratorUint32 -{ - uint32_t mValue; - GeneratorUint32() : mValue(0) {} - uint32_t operator()(){ return mValue++; } -}; - - - - -/////////////////////////////////////////////////////////////////////////////// -// TestRandom -// -int TestRandom() -{ - int nErrorCount = 0; - - { - // template<class IntType = int> - // class uniform_int_distribution - - // The C++11 Standard defines a number of formal Generators, such as std::mersenne_twister_engine, - // linear_congruential_engine, discard_block_engine, etc. - - using namespace eastl; - - { - eastl::uniform_int_distribution<uint8_t> uid(1, 6); - GeneratorUint8 g; - - for(uint32_t i = 0; i < UINT8_MAX; i += 1) - { - uint8_t value = uid(g); - EATEST_VERIFY((value >= 1) && (value <= 6)); - // To do: Validate the randomness of the value. - } - - eastl::uniform_int_distribution<uint8_t> uid2(1, 6); - EATEST_VERIFY(uid == uid2); - } - - { - eastl::uniform_int_distribution<uint16_t> uid(1, 6); - GeneratorUint16 g; - - for(uint32_t i = 0; i < (UINT16_MAX - (UINT16_MAX / 50)); i += (UINT16_MAX / 50)) - { - uint16_t value = uid(g); - EATEST_VERIFY((value >= 1) && (value <= 6)); - // To do: Validate the randomness of the value. - } - - eastl::uniform_int_distribution<uint16_t> uid2(1, 6); - EATEST_VERIFY(uid == uid2); - } - - { - eastl::uniform_int_distribution<uint32_t> uid(1, 6); - GeneratorUint32 g; - - for(uint32_t i = 0; i < (UINT32_MAX - (UINT32_MAX / 500)); i += (UINT32_MAX / 500)) - { - uint32_t value = uid(g); - EATEST_VERIFY((value >= 1) && (value <= 6)); - // To do: Validate the randomness of the value. - } - - eastl::uniform_int_distribution<uint32_t> uid2(1, 6); - EATEST_VERIFY(uid == uid2); - } - } - - - - /// Example usage: - /// eastl_size_t Rand(eastl_size_t n) { return (eastl_size_t)(rand() % n); } // Note: The C rand function is poor and slow. - /// pointer_to_unary_function<eastl_size_t, eastl_size_t> randInstance(Rand); - /// random_shuffle(pArrayBegin, pArrayEnd, randInstance); - /// - /// Example usage: - /// struct Rand{ eastl_size_t operator()(eastl_size_t n) { return (eastl_size_t)(rand() % n); } }; // Note: The C rand function is poor and slow. - /// Rand randInstance; - /// random_shuffle(pArrayBegin, pArrayEnd, randInstance); - - - { - // void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rng) - using namespace eastl; - - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - int intArray[] = { 3, 2, 6, 5, 4, 1 }; - - random_shuffle(intArray, intArray + 0, rng); - EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "random_shuffle", 3, 2, 6, 5, 4, 1, -1)); - - random_shuffle(intArray, intArray + (sizeof(intArray) / sizeof(intArray[0])), rng); - bool changed = false; - for(int i = 0; (i < 5) && !changed; i++) - { - changed = (intArray[0] != 3) || (intArray[1] != 2) || (intArray[2] != 6) || - (intArray[3] != 5) || (intArray[4] != 4) || (intArray[5] != 1); - } - EATEST_VERIFY(changed); - - // Test of possible bug report by user John Chin. - // The report is that shuffling an ordered array 0, 1, 2, 3, 4 ... results in duplicates, such as 5, 2, 2, 4 ... - eastl::vector<eastl_size_t> rngArray; - - for(eastl_size_t i = 0; i < 200; ++i) - rngArray.push_back(i); - - random_shuffle(rngArray.begin(), rngArray.end(), rng); - EATEST_VERIFY(rngArray.validate()); - - eastl::set<eastl_size_t> intSet; - - for(eastl_size_t s = 0, sEnd = rngArray.size(); s < sEnd; ++s) - intSet.insert(rngArray[s]); - - // If the shuffled array is unique, then a set of its values should be the same size as the array. - EATEST_VERIFY(intSet.size() == rngArray.size()); - } - - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestRatio.cpp b/test/source/TestRatio.cpp deleted file mode 100644 index 9f30fc1..0000000 --- a/test/source/TestRatio.cpp +++ /dev/null @@ -1,107 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EABase/eabase.h> -#include <EASTL/ratio.h> - - -int TestRatio() -{ - using namespace eastl; - - int nErrorCount = 0; - { - using namespace eastl::Internal; - - // lcm (least common multiple) - static_assert(lcm<0,0>::value == 0, "lcm failure"); - static_assert(lcm<10,6>::value == 30, "lcm failure"); - static_assert(lcm<21,6>::value == 42, "lcm failure"); - static_assert(lcm<21,6>::value == lcm<6,21>::value, "lcm failure"); - - // gcd (greatest common divisor) - static_assert(gcd<6, 4>::value == 2, "gcd failure"); - static_assert(gcd<54, 24>::value == 6, "gcd failure"); - static_assert(gcd<42, 56>::value == 14, "gcd failure"); - static_assert(gcd<48, 18>::value == 6, "gcd failure"); - static_assert(gcd<50, 40>::value == 10, "gcd failure"); - static_assert(gcd<6, 4>::value != 9, "gcd failure"); - static_assert(gcd<0, 0>::value == 1, "gcd failure"); - static_assert(gcd<1, 0>::value == 1, "gcd failure"); - static_assert(gcd<0, 1>::value == 1, "gcd failure"); - static_assert(gcd<34,7>::value == gcd<7, 34>::value, "gcd failure"); - static_assert(gcd<9223372036854775807, 9223372036854775807>::value == 9223372036854775807, "gcd failure"); - - // simplify - typedef ct_simplify<ratio<50, 40>>::ratio_type smp_rt; - typedef ct_simplify<ratio<50, 40>>::this_type smp_tt; - static_assert(smp_rt::num == 5 && smp_rt::den == 4, "simplify failure"); - static_assert(smp_tt::divisor == 10, "simplify failure0"); - static_assert(smp_rt::num == 5, "simplify failure1"); - static_assert(smp_rt::den == 4, "simplify failure2"); - } - - { - // ratio_add - typedef ratio_add<ratio<2, 3>, ratio<1, 6>> sum; - static_assert(sum::num == 5 && sum::den == 6, "ratio_add failure"); - typedef ratio_add<ratio<3,4>, ratio<5,10>> sum2; - static_assert(sum2::num == 5 && sum2::den == 4, "ratio_add failure"); - - // ratio_subtract - typedef ratio_subtract<ratio<10,10>, ratio<1,2>> sum3; - static_assert(sum3::num == 1 && sum3::den == 2, "ratio_subtract failure"); - - // ratio_multiply - typedef ratio_multiply<ratio<10,10>, ratio<1,2>> sum4; - static_assert(sum4::num == 1 && sum4::den == 2, "ratio_multiply failure"); - typedef ratio_multiply<ratio<2,5>, ratio<1,2>> sum5; - static_assert(sum5::num == 1 && sum5::den == 5, "ratio_multiply failure"); - typedef ratio_multiply<ratio<1,3>, ratio<9,16>> sum6; - static_assert(sum6::num == 3 && sum6::den == 16, "ratio_multiply failure"); - - // ratio_divide - typedef ratio_divide<ratio<1,8>, ratio<1,4>> sum8; - static_assert(sum8::num == 1 && sum8::den == 2, "ratio_divide failure"); - typedef ratio_divide<ratio<2,3>, ratio<5>> sum9; - static_assert(sum9::num == 2 && sum9::den == 15, "ratio_divide failure"); - - // ratio_equal - static_assert(ratio_equal<ratio<1>, ratio<1>>::value, "ratio_equal failure"); - static_assert(ratio_equal<ratio<1,1>, ratio<4,4>>::value, "ratio_equal failure"); - static_assert(ratio_equal<ratio<5,10>, ratio<1,2>>::value, "ratio_equal failure"); - static_assert(ratio_equal<ratio<2,3>, ratio<4,6>>::value, "ratio_equal failure"); - - // ratio_not_equal - static_assert(!ratio_not_equal<ratio<5,10>, ratio<1,2>>::value, "ratio_not_equal failure"); - - // ratio_less - static_assert(ratio_less<ratio<2,10>, ratio<1,2>>::value, "ratio_less failure"); - static_assert(ratio_less<ratio<23,37>, ratio<57,90>>::value, "ratio_less failure"); - - // ratio_less_equal - static_assert(ratio_less_equal<ratio<2,10>, ratio<1,2>>::value, "ratio_less_equal failure"); - static_assert(ratio_less_equal<ratio<2,10>, ratio<1,5>>::value, "ratio_less_equal failure"); - static_assert(ratio_less_equal<ratio<1,100>, ratio<1,5>>::value, "ratio_less_equal failure"); - - // ratio_greater - static_assert(ratio_greater<ratio<1,2>, ratio<1,4>>::value, "ratio_greater failure"); - - // ratio_greater_equal - static_assert(ratio_greater_equal<ratio<3,4>, ratio<1,2>>::value, "ratio_greater_equal failure"); - } - - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestRingBuffer.cpp b/test/source/TestRingBuffer.cpp deleted file mode 100644 index d640380..0000000 --- a/test/source/TestRingBuffer.cpp +++ /dev/null @@ -1,1139 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/bonus/ring_buffer.h> -#include <EASTL/bonus/fixed_ring_buffer.h> -#include <EASTL/vector.h> -#include <EASTL/deque.h> -#include <EASTL/string.h> -#include <EASTL/list.h> -#include <EASTL/fixed_vector.h> -#include <EASTL/fixed_string.h> - - - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::ring_buffer< int, eastl::vector<int> >; -template class eastl::ring_buffer< Align64, eastl::vector<Align64> >; -template class eastl::ring_buffer< TestObject, eastl::vector<TestObject> >; - -template class eastl::ring_buffer< int, eastl::deque<int> >; -template class eastl::ring_buffer< Align64, eastl::deque<Align64> >; -template class eastl::ring_buffer< TestObject, eastl::deque<TestObject> >; - -template class eastl::ring_buffer< int, eastl::list<int> >; -template class eastl::ring_buffer< Align64, eastl::list<Align64> >; -template class eastl::ring_buffer< TestObject, eastl::list<TestObject> >; - -// TODO(rparolin): To consider adding support for eastl::array. -// template class eastl::ring_buffer< int, eastl::array<int, 64>>; - -typedef eastl::fixed_string<char, 256, false> RBFixedString; -typedef eastl::fixed_vector<RBFixedString, 100, false> RBFixedStringVector; -typedef RBFixedStringVector::overflow_allocator_type RBFixedStringVectorOverflowAllocator; -template class eastl::ring_buffer<RBFixedString, RBFixedStringVector, RBFixedStringVectorOverflowAllocator>; - -typedef eastl::fixed_vector<int, 100, false> RBFixedIntVector; -template class eastl::ring_buffer<int, RBFixedIntVector, RBFixedIntVector::overflow_allocator_type>; -// template class eastl::ring_buffer<int, RBFixedIntVector>; // currently fails to compile - -typedef eastl::fixed_vector<int, 100> RBFixedIntVectorWithOverFlow; -template class eastl::ring_buffer<int, RBFixedIntVectorWithOverFlow, RBFixedIntVectorWithOverFlow::overflow_allocator_type>; -// template class eastl::ring_buffer<int, RBFixedIntVectorWithOverFlow>; // currently fails to compile - - - -int TestRingBuffer() -{ - int nErrorCount = 0; - - // GCC prior to 4.1 has a fatal code generation bug in string arrays, which we use below. - #if !defined(EA_DEBUG) && defined(__GNUC__) && !defined(__EDG__) && (((__GNUC__ * 100) + __GNUC_MINOR__) < 401) - return nErrorCount; - #endif - - { // regression for bug in the capacity() function for the case of capacity == 0. - - vector<int> emptyIntArray; - ring_buffer<int, vector<int> > intRingBuffer(emptyIntArray); - - EATEST_VERIFY(intRingBuffer.validate()); - EATEST_VERIFY(intRingBuffer.capacity() == 0); - - intRingBuffer.resize(0); - EATEST_VERIFY(intRingBuffer.validate()); - EATEST_VERIFY(intRingBuffer.size() == 0); - - intRingBuffer.resize(1); - EATEST_VERIFY(intRingBuffer.validate()); - EATEST_VERIFY(intRingBuffer.size() == 1); - } - - { - EA::UnitTest::Rand rng(EA::UnitTest::GetRandSeed()); - - typedef ring_buffer< string, vector<string> > RBVectorString; - - int counter = 0; - char counterBuffer[32]; - - // explicit ring_buffer(size_type size = 0); - const int kOriginalCapacity = 50; - RBVectorString rbVectorString(50); - - // bool empty() const; - // size_type size() const; - // bool validate() const; - EATEST_VERIFY(rbVectorString.validate()); - EATEST_VERIFY(rbVectorString.empty()); - EATEST_VERIFY(rbVectorString.size() == 0); - EATEST_VERIFY(rbVectorString.capacity() == 50); - - // void clear(); - rbVectorString.clear(); - EATEST_VERIFY(rbVectorString.validate()); - EATEST_VERIFY(rbVectorString.empty()); - EATEST_VERIFY(rbVectorString.size() == 0); - EATEST_VERIFY(rbVectorString.capacity() == 50); - - // container_type& get_container(); - RBVectorString::container_type& c = rbVectorString.get_container(); - EATEST_VERIFY(c.size() == (kOriginalCapacity + 1)); // We need to add one because the ring_buffer mEnd is necessarily an unused element. - - // iterator begin(); - // iterator end(); - // int validate_iterator(const_iterator i) const; - RBVectorString::iterator it = rbVectorString.begin(); - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current)); - - while(it != rbVectorString.end()) // This loop should do nothing. - { - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current)); - ++it; - } - - // void push_back(const value_type& value); - sprintf(counterBuffer, "%d", counter++); - rbVectorString.push_back(string(counterBuffer)); - EATEST_VERIFY(rbVectorString.validate()); - EATEST_VERIFY(!rbVectorString.empty()); - EATEST_VERIFY(rbVectorString.size() == 1); - EATEST_VERIFY(rbVectorString.capacity() == 50); - - it = rbVectorString.begin(); - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - EATEST_VERIFY(*it == "0"); - - // reference front(); - // reference back(); - string& sFront = rbVectorString.front(); - string& sBack = rbVectorString.back(); - EATEST_VERIFY(&sFront == &sBack); - - // void push_back(); - string& ref = rbVectorString.push_back(); - EATEST_VERIFY(rbVectorString.validate()); - EATEST_VERIFY(rbVectorString.size() == 2); - EATEST_VERIFY(rbVectorString.capacity() == 50); - EATEST_VERIFY(&ref == &rbVectorString.back()); - - it = rbVectorString.begin(); - ++it; - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - EATEST_VERIFY(it->empty()); - - sprintf(counterBuffer, "%d", counter++); - *it = counterBuffer; - EATEST_VERIFY(*it == "1"); - - ++it; - EATEST_VERIFY(it == rbVectorString.end()); - - it = rbVectorString.begin(); - while(it != rbVectorString.end()) - { - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - ++it; - } - - // reference operator[](size_type n); - string& s0 = rbVectorString[0]; - EATEST_VERIFY(s0 == "0"); - - string& s1 = rbVectorString[1]; - EATEST_VERIFY(s1 == "1"); - - // Now we start hammering the ring buffer with push_back. - for(eastl_size_t i = 0, iEnd = rbVectorString.capacity() * 5; i != iEnd; i++) - { - sprintf(counterBuffer, "%d", counter++); - rbVectorString.push_back(string(counterBuffer)); - EATEST_VERIFY(rbVectorString.validate()); - } - - int counterCheck = counter - 1; - char counterCheckBuffer[32]; - sprintf(counterCheckBuffer, "%d", counterCheck); - EATEST_VERIFY(rbVectorString.back() == counterCheckBuffer); - - // reverse_iterator rbegin(); - // reverse_iterator rend(); - for(RBVectorString::reverse_iterator ri = rbVectorString.rbegin(); ri != rbVectorString.rend(); ++ri) - { - sprintf(counterCheckBuffer, "%d", counterCheck--); - EATEST_VERIFY(*ri == counterCheckBuffer); - } - - ++counterCheck; - - // iterator begin(); - // iterator end(); - for(RBVectorString::iterator i = rbVectorString.begin(); i != rbVectorString.end(); ++i) - { - EATEST_VERIFY(rbVectorString.validate_iterator(i) == (isf_valid | isf_current | isf_can_dereference)); - EATEST_VERIFY(*i == counterCheckBuffer); - sprintf(counterCheckBuffer, "%d", ++counterCheck); - } - - // void clear(); - rbVectorString.clear(); - EATEST_VERIFY(rbVectorString.validate()); - EATEST_VERIFY(rbVectorString.empty()); - EATEST_VERIFY(rbVectorString.size() == 0); - EATEST_VERIFY(rbVectorString.capacity() == 50); - - // Random operations - // Not easy to test the expected values without some tedium. - for(int j = 0; j < 10000 + (gEASTL_TestLevel * 10000); j++) - { - sprintf(counterBuffer, "%d", counter++); - - const eastl_size_t op = rng.RandLimit(12); - const eastl_size_t s = rbVectorString.size(); - - if(op == 0) - { - // void push_back(const value_type& value); - - rbVectorString.push_back(string(counterBuffer)); - EATEST_VERIFY(rbVectorString.size() == eastl::min(s + 1, rbVectorString.capacity())); - } - else if(op == 1) - { - // void push_back(); - - string& ref2 = rbVectorString.push_back(); - rbVectorString.back() = string(counterBuffer); - EATEST_VERIFY(rbVectorString.size() == eastl::min(s + 1, rbVectorString.capacity())); - EATEST_VERIFY(&ref2 == &rbVectorString.back()); - } - else if(op == 2) - { - // void pop_back(); - - if(!rbVectorString.empty()) - { - rbVectorString.pop_back(); - EATEST_VERIFY(rbVectorString.size() == (s - 1)); - } - } - else if(op == 3) - { - // void push_front(const value_type& value); - - rbVectorString.push_front(string(counterBuffer)); - EATEST_VERIFY(rbVectorString.size() == eastl::min(s + 1, rbVectorString.capacity())); - } - else if(op == 4) - { - // void push_front(); - - string& ref2 = rbVectorString.push_front(); - rbVectorString.front() = string(counterBuffer); - EATEST_VERIFY(rbVectorString.size() == eastl::min(s + 1, rbVectorString.capacity())); - EATEST_VERIFY(&ref2 == &rbVectorString.front()); - } - else if(op == 5) - { - // void pop_front(); - - if(!rbVectorString.empty()) - { - rbVectorString.pop_front(); - EATEST_VERIFY(rbVectorString.size() == (s - 1)); - } - } - else if(op == 6) - { - // iterator insert(iterator position, const value_type& value); - - it = rbVectorString.begin(); - const eastl_size_t dist = rng.RandLimit((uint32_t)s + 1); - eastl::advance(it, dist); - - if(it == rbVectorString.end()) - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current)); - else - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - - rbVectorString.insert(it, string(counterBuffer)); - EATEST_VERIFY(rbVectorString.size() == eastl::min(s + 1, rbVectorString.capacity())); - } - else if(op == 7) - { - // void insert(iterator position, size_type n, const value_type& value); - - it = rbVectorString.begin(); - const eastl_size_t dist = rng.RandLimit((uint32_t)s + 1); - eastl::advance(it, dist); - - if(it == rbVectorString.end()) - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current)); - else - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - - const eastl_size_t count = (eastl_size_t)rng.RandLimit(10); - - rbVectorString.insert(it, count, string(counterBuffer)); - EATEST_VERIFY(rbVectorString.size() == eastl::min(s + count, rbVectorString.capacity())); - } - else if(op == 8) - { - // template <typename InputIterator> - // void insert(iterator position, InputIterator first, InputIterator last); - - string stringArray[10]; - - it = rbVectorString.begin(); - const eastl_size_t dist = rng.RandLimit((uint32_t)s + 1); - eastl::advance(it, dist); - - if(it == rbVectorString.end()) - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current)); - else - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - - const eastl_size_t count = (eastl_size_t)rng.RandLimit(10); - - rbVectorString.insert(it, stringArray, stringArray + count); - EATEST_VERIFY(rbVectorString.size() == eastl::min(s + count, rbVectorString.capacity())); - } - else if(op == 9) - { - // iterator erase(iterator position); - - if(!rbVectorString.empty()) - { - it = rbVectorString.begin(); - const eastl_size_t dist = rng.RandLimit((uint32_t)s); - eastl::advance(it, dist); - EATEST_VERIFY(rbVectorString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - rbVectorString.erase(it); - - EATEST_VERIFY(rbVectorString.size() == (s - 1)); - } - } - else if(op == 10) - { - // iterator erase(iterator first, iterator last); - - if(!rbVectorString.empty()) - { - RBVectorString::iterator it1 = rbVectorString.begin(); - const eastl_size_t pos = rng.RandLimit((uint32_t)s / 4); - eastl::advance(it1, pos); - EATEST_VERIFY(rbVectorString.validate_iterator(it1) == (isf_valid | isf_current | isf_can_dereference)); - - RBVectorString::iterator it2 = it1; - const eastl_size_t dist = rng.RandLimit((uint32_t)s / 4); - eastl::advance(it2, dist); - EATEST_VERIFY(rbVectorString.validate_iterator(it2) == (isf_valid | isf_current | isf_can_dereference)); - - EATEST_VERIFY(s > (pos + dist)); - rbVectorString.erase(it1, it2); - EATEST_VERIFY(rbVectorString.size() == (s - dist)); - } - } - else if(op == 11) - { - // void resize(size_type n); - const eastl_size_t nSubOp = rng.RandLimit(100); - - if(nSubOp == 1) - { - rbVectorString.resize(kOriginalCapacity); - EATEST_VERIFY(rbVectorString.size() == (RBVectorString::size_type)kOriginalCapacity); - } - else if(nSubOp == 2) - { - const eastl_size_t newSize = rng.RandLimit((uint32_t)s * 2) + 2; - - rbVectorString.resize(newSize); - EATEST_VERIFY(rbVectorString.size() == newSize); - } - else if(nSubOp == 3) - { - rbVectorString.clear(); - EATEST_VERIFY(rbVectorString.size() == 0); - } - } - - EATEST_VERIFY(rbVectorString.validate()); - } - - // We make sure that after the above we still have some contents. - if(rbVectorString.size() < 8) - rbVectorString.resize(8); - - EATEST_VERIFY(rbVectorString.validate()); - - // Test const functions - // const_iterator begin() const; - // const_iterator end() const; - // const_reverse_iterator rbegin() const; - // const_reverse_iterator rend() const; - // const_reference front() const; - // const_reference back() const; - // const_reference operator[](size_type n) const; - // const container_type& get_container() const; - const RBVectorString& rbVSConst = rbVectorString; - - for(RBVectorString::const_iterator ic = rbVSConst.begin(); ic != rbVSConst.end(); ++ic) - { - EATEST_VERIFY(rbVectorString.validate_iterator(ic) == (isf_valid | isf_current | isf_can_dereference)); - } - - for(RBVectorString::const_reverse_iterator ric = rbVSConst.rbegin(); ric != rbVSConst.rend(); ++ric) - { - if(ric == rbVSConst.rbegin()) - EATEST_VERIFY(rbVectorString.validate_iterator(ric.base()) == (isf_valid | isf_current)); - else - EATEST_VERIFY(rbVectorString.validate_iterator(ric.base()) == (isf_valid | isf_current | isf_can_dereference)); - } - - EATEST_VERIFY(rbVSConst.front() == rbVectorString.front()); - EATEST_VERIFY(rbVSConst.back() == rbVectorString.back()); - EATEST_VERIFY(rbVSConst[0] == rbVectorString[0]); - EATEST_VERIFY(&rbVSConst.get_container() == &rbVectorString.get_container()); - - - // Test additional constructors. - // ring_buffer(const this_type& x); - // explicit ring_buffer(const Container& x); - // this_type& operator=(const this_type& x); - // void swap(this_type& x); - RBVectorString rbVectorString2(rbVectorString); - RBVectorString rbVectorString3(rbVectorString.get_container()); - RBVectorString rbVectorString4(rbVectorString.capacity() / 2); - RBVectorString rbVectorString5(rbVectorString.capacity() * 2); - - EATEST_VERIFY(rbVectorString.validate()); - EATEST_VERIFY(rbVectorString2.validate()); - EATEST_VERIFY(rbVectorString3.validate()); - EATEST_VERIFY(rbVectorString4.validate()); - EATEST_VERIFY(rbVectorString5.validate()); - - EATEST_VERIFY(rbVectorString == rbVectorString2); - EATEST_VERIFY(rbVectorString3.get_container() == rbVectorString2.get_container()); - - rbVectorString3 = rbVectorString4; - EATEST_VERIFY(rbVectorString3.validate()); - - eastl::swap(rbVectorString2, rbVectorString4); - EATEST_VERIFY(rbVectorString2.validate()); - EATEST_VERIFY(rbVectorString3.validate()); - EATEST_VERIFY(rbVectorString4.validate()); - EATEST_VERIFY(rbVectorString == rbVectorString4); - EATEST_VERIFY(rbVectorString2 == rbVectorString3); - - // void ring_buffer<T, Container>::reserve(size_type n) - eastl_size_t cap = rbVectorString2.capacity(); - rbVectorString2.reserve(cap += 2); - EATEST_VERIFY(rbVectorString2.validate()); - EATEST_VERIFY(rbVectorString2.capacity() == cap); - rbVectorString2.reserve(cap -= 4); // This should act as a no-op if we are following convention. - EATEST_VERIFY(rbVectorString2.validate()); - - // void ring_buffer<T, Container>::set_capacity(size_type n) - cap = rbVectorString2.capacity(); - rbVectorString2.resize(cap); - EATEST_VERIFY(rbVectorString2.size() == cap); - rbVectorString2.set_capacity(cap += 2); - EATEST_VERIFY(rbVectorString2.validate()); - EATEST_VERIFY(rbVectorString2.capacity() == cap); - rbVectorString2.set_capacity(cap -= 4); - EATEST_VERIFY(rbVectorString2.capacity() == cap); - EATEST_VERIFY(rbVectorString2.validate()); - - // template <typename InputIterator> - // void assign(InputIterator first, InputIterator last); - string stringArray[10]; - for(int q = 0; q < 10; q++) - stringArray[q] = (char)('0' + (char)q); - - rbVectorString5.assign(stringArray, stringArray + 10); - EATEST_VERIFY(rbVectorString5.validate()); - EATEST_VERIFY(rbVectorString5.size() == 10); - EATEST_VERIFY(rbVectorString5.front() == "0"); - EATEST_VERIFY(rbVectorString5.back() == "9"); - } - - - { - // Additional testing - typedef ring_buffer< int, vector<int> > RBVectorInt; - - RBVectorInt rbVectorInt(6); - - rbVectorInt.push_back(0); - rbVectorInt.push_back(1); - rbVectorInt.push_back(2); - rbVectorInt.push_back(3); - rbVectorInt.push_back(4); - rbVectorInt.push_back(5); - EATEST_VERIFY(rbVectorInt[0] == 0); - EATEST_VERIFY(rbVectorInt[5] == 5); - - // iterator insert(iterator position, const value_type& value); - rbVectorInt.insert(rbVectorInt.begin(), 999); - EATEST_VERIFY(rbVectorInt[0] == 999); - EATEST_VERIFY(rbVectorInt[1] == 0); - EATEST_VERIFY(rbVectorInt[5] == 4); - - rbVectorInt.clear(); - rbVectorInt.push_back(0); - rbVectorInt.push_back(1); - rbVectorInt.push_back(2); - rbVectorInt.push_back(3); - rbVectorInt.push_back(4); - - // iterator insert(iterator position, const value_type& value); - rbVectorInt.insert(rbVectorInt.begin(), 999); - EATEST_VERIFY(rbVectorInt[0] == 999); - EATEST_VERIFY(rbVectorInt[1] == 0); - EATEST_VERIFY(rbVectorInt[5] == 4); - - rbVectorInt.clear(); - rbVectorInt.push_back(0); - rbVectorInt.push_back(1); - rbVectorInt.push_back(2); - rbVectorInt.push_back(3); - rbVectorInt.push_back(4); - rbVectorInt.push_back(5); - rbVectorInt.push_back(6); - EATEST_VERIFY(rbVectorInt[0] == 1); - EATEST_VERIFY(rbVectorInt[5] == 6); - - // iterator insert(iterator position, const value_type& value); - rbVectorInt.insert(rbVectorInt.begin(), 999); - EATEST_VERIFY(rbVectorInt[0] == 999); - EATEST_VERIFY(rbVectorInt[1] == 1); - EATEST_VERIFY(rbVectorInt[5] == 5); - - // iterator insert(iterator position, const value_type& value); - RBVectorInt::iterator it = rbVectorInt.begin(); - eastl::advance(it, 3); - rbVectorInt.insert(it, 888); - EATEST_VERIFY(rbVectorInt[0] == 999); - EATEST_VERIFY(rbVectorInt[1] == 1); - EATEST_VERIFY(rbVectorInt[2] == 2); - EATEST_VERIFY(rbVectorInt[3] == 888); - EATEST_VERIFY(rbVectorInt[4] == 3); - EATEST_VERIFY(rbVectorInt[5] == 4); - } - - - { - EA::UnitTest::Rand rng(EA::UnitTest::GetRandSeed()); - - typedef ring_buffer< string, list<string> > RBListString; - - int counter = 0; - char counterBuffer[32]; - - // explicit ring_buffer(size_type size = 0); - const int kOriginalCapacity = 50; - RBListString rbListString(50); - - // bool empty() const; - // size_type size() const; - // bool validate() const; - EATEST_VERIFY(rbListString.validate()); - EATEST_VERIFY(rbListString.empty()); - EATEST_VERIFY(rbListString.size() == 0); - EATEST_VERIFY(rbListString.capacity() == 50); - - // void clear(); - rbListString.clear(); - EATEST_VERIFY(rbListString.validate()); - EATEST_VERIFY(rbListString.empty()); - EATEST_VERIFY(rbListString.size() == 0); - EATEST_VERIFY(rbListString.capacity() == 50); - - // container_type& get_container(); - RBListString::container_type& c = rbListString.get_container(); - EATEST_VERIFY(c.size() == (kOriginalCapacity + 1)); // We need to add one because the ring_buffer mEnd is necessarily an unused element. - - // iterator begin(); - // iterator end(); - // int validate_iterator(const_iterator i) const; - RBListString::iterator it = rbListString.begin(); - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current)); - - while(it != rbListString.end()) // This loop should do nothing. - { - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current)); - ++it; - } - - // void push_back(const value_type& value); - sprintf(counterBuffer, "%d", counter++); - rbListString.push_back(string(counterBuffer)); - EATEST_VERIFY(rbListString.validate()); - EATEST_VERIFY(!rbListString.empty()); - EATEST_VERIFY(rbListString.size() == 1); - EATEST_VERIFY(rbListString.capacity() == 50); - - it = rbListString.begin(); - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - EATEST_VERIFY(*it == "0"); - - // reference front(); - // reference back(); - string& sFront = rbListString.front(); - string& sBack = rbListString.back(); - EATEST_VERIFY(&sFront == &sBack); - - // void push_back(); - string& ref = rbListString.push_back(); - EATEST_VERIFY(rbListString.validate()); - EATEST_VERIFY(rbListString.size() == 2); - EATEST_VERIFY(rbListString.capacity() == 50); - EATEST_VERIFY(&ref == &rbListString.back()); - - it = rbListString.begin(); - ++it; - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - EATEST_VERIFY(it->empty()); - - sprintf(counterBuffer, "%d", counter++); - *it = counterBuffer; - EATEST_VERIFY(*it == "1"); - - ++it; - EATEST_VERIFY(it == rbListString.end()); - - it = rbListString.begin(); - while(it != rbListString.end()) - { - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - ++it; - } - - // reference operator[](size_type n); - string& s0 = rbListString[0]; - EATEST_VERIFY(s0 == "0"); - - string& s1 = rbListString[1]; - EATEST_VERIFY(s1 == "1"); - - // Now we start hammering the ring buffer with push_back. - for(eastl_size_t i = 0, iEnd = rbListString.capacity() * 5; i != iEnd; i++) - { - sprintf(counterBuffer, "%d", counter++); - rbListString.push_back(string(counterBuffer)); - EATEST_VERIFY(rbListString.validate()); - } - - int counterCheck = counter - 1; - char counterCheckBuffer[32]; - sprintf(counterCheckBuffer, "%d", counterCheck); - EATEST_VERIFY(rbListString.back() == counterCheckBuffer); - - // reverse_iterator rbegin(); - // reverse_iterator rend(); - for(RBListString::reverse_iterator ri = rbListString.rbegin(); ri != rbListString.rend(); ++ri) - { - sprintf(counterCheckBuffer, "%d", counterCheck--); - EATEST_VERIFY(*ri == counterCheckBuffer); - } - - ++counterCheck; - - // iterator begin(); - // iterator end(); - for(RBListString::iterator i = rbListString.begin(); i != rbListString.end(); ++i) - { - EATEST_VERIFY(rbListString.validate_iterator(i) == (isf_valid | isf_current | isf_can_dereference)); - EATEST_VERIFY(*i == counterCheckBuffer); - sprintf(counterCheckBuffer, "%d", ++counterCheck); - } - - // void clear(); - rbListString.clear(); - EATEST_VERIFY(rbListString.validate()); - EATEST_VERIFY(rbListString.empty()); - EATEST_VERIFY(rbListString.size() == 0); - EATEST_VERIFY(rbListString.capacity() == 50); - - // Random operations - // Not easy to test the expected values without some tedium. - for(int j = 0; j < 10000 + (gEASTL_TestLevel * 10000); j++) - { - sprintf(counterBuffer, "%d", counter++); - - const eastl_size_t op = rng.RandLimit(12); - const eastl_size_t s = rbListString.size(); - - if(op == 0) - { - // void push_back(const value_type& value); - - rbListString.push_back(string(counterBuffer)); - EATEST_VERIFY(rbListString.size() == eastl::min(s + 1, rbListString.capacity())); - } - else if(op == 1) - { - // void push_back(); - - string& ref2 = rbListString.push_back(); - rbListString.back() = string(counterBuffer); - EATEST_VERIFY(rbListString.size() == eastl::min(s + 1, rbListString.capacity())); - EATEST_VERIFY(&ref2 == &rbListString.back()); - } - else if(op == 2) - { - // void pop_back(); - - if(!rbListString.empty()) - { - rbListString.pop_back(); - EATEST_VERIFY(rbListString.size() == (s - 1)); - } - } - else if(op == 3) - { - // void push_front(const value_type& value); - - rbListString.push_front(string(counterBuffer)); - EATEST_VERIFY(rbListString.size() == eastl::min(s + 1, rbListString.capacity())); - } - else if(op == 4) - { - // void push_front(); - - string& ref2 = rbListString.push_front(); - rbListString.front() = string(counterBuffer); - EATEST_VERIFY(rbListString.size() == eastl::min(s + 1, rbListString.capacity())); - EATEST_VERIFY(&ref2 == &rbListString.front()); - } - else if(op == 5) - { - // void pop_front(); - - if(!rbListString.empty()) - { - rbListString.pop_front(); - EATEST_VERIFY(rbListString.size() == (s - 1)); - } - } - else if(op == 6) - { - // iterator insert(iterator position, const value_type& value); - - it = rbListString.begin(); - const eastl_size_t dist = rng.RandLimit((uint32_t)s + 1); - eastl::advance(it, dist); - - if(it == rbListString.end()) - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current)); - else - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - - rbListString.insert(it, string(counterBuffer)); - EATEST_VERIFY(rbListString.size() == eastl::min(s + 1, rbListString.capacity())); - } - else if(op == 7) - { - // void insert(iterator position, size_type n, const value_type& value); - - it = rbListString.begin(); - const eastl_size_t dist = rng.RandLimit((uint32_t)s + 1); - eastl::advance(it, dist); - - if(it == rbListString.end()) - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current)); - else - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - - const eastl_size_t count = (eastl_size_t)rng.RandLimit(10); - - rbListString.insert(it, count, string(counterBuffer)); - EATEST_VERIFY(rbListString.size() == eastl::min(s + count, rbListString.capacity())); - } - else if(op == 8) - { - // template <typename InputIterator> - // void insert(iterator position, InputIterator first, InputIterator last); - - string stringArray[10]; - - it = rbListString.begin(); - const eastl_size_t dist = rng.RandLimit((uint32_t)s + 1); - eastl::advance(it, dist); - - if(it == rbListString.end()) - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current)); - else - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - - const eastl_size_t count = (eastl_size_t)rng.RandLimit(10); - - rbListString.insert(it, stringArray, stringArray + count); - EATEST_VERIFY(rbListString.size() == eastl::min(s + count, rbListString.capacity())); - } - else if(op == 9) - { - // iterator erase(iterator position); - - if(!rbListString.empty()) - { - it = rbListString.begin(); - const eastl_size_t dist = rng.RandLimit((uint32_t)s); - eastl::advance(it, dist); - EATEST_VERIFY(rbListString.validate_iterator(it) == (isf_valid | isf_current | isf_can_dereference)); - rbListString.erase(it); - - EATEST_VERIFY(rbListString.size() == (s - 1)); - } - } - else if(op == 10) - { - // iterator erase(iterator first, iterator last); - - if(!rbListString.empty()) - { - RBListString::iterator it1 = rbListString.begin(); - const eastl_size_t pos = rng.RandLimit((uint32_t)s / 4); - eastl::advance(it1, pos); - EATEST_VERIFY(rbListString.validate_iterator(it1) == (isf_valid | isf_current | isf_can_dereference)); - - RBListString::iterator it2 = it1; - const eastl_size_t dist = rng.RandLimit((uint32_t)s / 4); - eastl::advance(it2, dist); - EATEST_VERIFY(rbListString.validate_iterator(it2) == (isf_valid | isf_current | isf_can_dereference)); - - EATEST_VERIFY(s > (pos + dist)); - rbListString.erase(it1, it2); - EATEST_VERIFY(rbListString.size() == (s - dist)); - } - } - else if(op == 11) - { - // void resize(size_type n); - const eastl_size_t nSubOp = rng.RandLimit(100); - - if(nSubOp == 1) - { - rbListString.resize(kOriginalCapacity); - EATEST_VERIFY(rbListString.size() == (RBListString::size_type)kOriginalCapacity); - } - else if(nSubOp == 2) - { - const eastl_size_t newSize = rng.RandLimit((uint32_t)s * 2) + 2; - - rbListString.resize(newSize); - EATEST_VERIFY(rbListString.size() == newSize); - } - else if(nSubOp == 3) - { - rbListString.clear(); - EATEST_VERIFY(rbListString.size() == 0); - } - } - - EATEST_VERIFY(rbListString.validate()); - } - - // We make sure that after the above we still have some contents. - if(rbListString.size() < 8) - rbListString.resize(8); - - EATEST_VERIFY(rbListString.validate()); - - // Test const functions - // const_iterator begin() const; - // const_iterator end() const; - // const_reverse_iterator rbegin() const; - // const_reverse_iterator rend() const; - // const_reference front() const; - // const_reference back() const; - // const_reference operator[](size_type n) const; - // const container_type& get_container() const; - const RBListString& rbVSConst = rbListString; - - for(RBListString::const_iterator ic = rbVSConst.begin(); ic != rbVSConst.end(); ++ic) - { - EATEST_VERIFY(rbListString.validate_iterator(ic) == (isf_valid | isf_current | isf_can_dereference)); - } - - for(RBListString::const_reverse_iterator ric = rbVSConst.rbegin(); ric != rbVSConst.rend(); ++ric) - { - if(ric == rbVSConst.rbegin()) - EATEST_VERIFY(rbListString.validate_iterator(ric.base()) == (isf_valid | isf_current)); - else - EATEST_VERIFY(rbListString.validate_iterator(ric.base()) == (isf_valid | isf_current | isf_can_dereference)); - } - - EATEST_VERIFY(rbVSConst.front() == rbListString.front()); - EATEST_VERIFY(rbVSConst.back() == rbListString.back()); - EATEST_VERIFY(rbVSConst[0] == rbListString[0]); - EATEST_VERIFY(&rbVSConst.get_container() == &rbListString.get_container()); - - - // Test additional constructors. - // ring_buffer(const this_type& x); - // explicit ring_buffer(const Container& x); - // this_type& operator=(const this_type& x); - // void swap(this_type& x); - RBListString rbListString2(rbListString); - RBListString rbListString3(rbListString.get_container()); - RBListString rbListString4(rbListString.capacity() / 2); - RBListString rbListString5(rbListString.capacity() * 2); - - EATEST_VERIFY(rbListString.validate()); - EATEST_VERIFY(rbListString2.validate()); - EATEST_VERIFY(rbListString3.validate()); - EATEST_VERIFY(rbListString4.validate()); - EATEST_VERIFY(rbListString5.validate()); - - EATEST_VERIFY(rbListString == rbListString2); - EATEST_VERIFY(rbListString3.get_container() == rbListString2.get_container()); - - rbListString3 = rbListString4; - EATEST_VERIFY(rbListString3.validate()); - - eastl::swap(rbListString2, rbListString4); - EATEST_VERIFY(rbListString2.validate()); - EATEST_VERIFY(rbListString3.validate()); - EATEST_VERIFY(rbListString4.validate()); - EATEST_VERIFY(rbListString == rbListString4); - EATEST_VERIFY(rbListString2 == rbListString3); - - // void ring_buffer<T, Container>::reserve(size_type n) - eastl_size_t cap = rbListString2.capacity(); - rbListString2.reserve(cap += 2); - EATEST_VERIFY(rbListString2.validate()); - EATEST_VERIFY(rbListString2.capacity() == cap); - rbListString2.reserve(cap -= 4); // This should act as a no-op if we are following convention. - EATEST_VERIFY(rbListString2.validate()); - - - // template <typename InputIterator> - // void assign(InputIterator first, InputIterator last); - string stringArray[10]; - for(int q = 0; q < 10; q++) - stringArray[q] = '0' + (char)q; - - rbListString5.assign(stringArray, stringArray + 10); - EATEST_VERIFY(rbListString5.validate()); - EATEST_VERIFY(rbListString5.size() == 10); - EATEST_VERIFY(rbListString5.front() == "0"); - EATEST_VERIFY(rbListString5.back() == "9"); - - - // ring_buffer(this_type&& x); - // ring_buffer(this_type&& x, const allocator_type& allocator); - // this_type& operator=(this_type&& x); - - RBListString rbListStringM1(eastl::move(rbListString5)); - EATEST_VERIFY(rbListStringM1.validate() && rbListString5.validate()); - EATEST_VERIFY((rbListStringM1.size() == 10) && (rbListString5.size() == 0)); - - RBListString rbListStringM2(eastl::move(rbListStringM1), RBListString::allocator_type()); - EATEST_VERIFY(rbListStringM2.validate() && rbListStringM1.validate()); - EATEST_VERIFY((rbListStringM2.size() == 10) && (rbListStringM1.size() == 0)); - - rbListStringM1 = eastl::move(rbListStringM2); - EATEST_VERIFY(rbListStringM1.validate() && rbListStringM2.validate()); - EATEST_VERIFY((rbListStringM1.size() == 10) && (rbListStringM2.size() == 0)); - } - - - - { - // ring_buffer(std::initializer_list<value_type> ilist, const allocator_type& allocator = allocator_type()); - // this_type& operator=(std::initializer_list<value_type> ilist); - // void insert(iterator position, std::initializer_list<value_type> ilist); - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - ring_buffer<int> intBuffer = { 0, 1, 2 }; - EATEST_VERIFY(VerifySequence(intBuffer.begin(), intBuffer.end(), int(), "ring_buffer std::initializer_list", 0, 1, 2, -1)); - - intBuffer = { 16, 17, 18 }; - EATEST_VERIFY(VerifySequence(intBuffer.begin(), intBuffer.end(), int(), "ring_buffer std::initializer_list", 16, 17, 18, -1)); - - // We need to increase the capacity in order to insert new items because the ctor above set the capacity to be only enough to hold the initial list. - intBuffer.reserve(intBuffer.capacity() + 2); - intBuffer.insert(intBuffer.begin(), { 14, 15 }); - EATEST_VERIFY(VerifySequence(intBuffer.begin(), intBuffer.end(), int(), "ring_buffer std::initializer_list", 14, 15, 16, 17, 18, -1)); - #endif - } - - { - // Regression for user-reported problem. - typedef eastl::fixed_vector<float, 8> GamepadData_t; - typedef eastl::ring_buffer<GamepadData_t> GamepadDataDelayBuffer_t; - typedef eastl::fixed_vector<GamepadDataDelayBuffer_t, 32> GamepadDataDelayBufferTable_t; - - GamepadDataDelayBufferTable_t mDelayTable; - mDelayTable.resize(32); - for(eastl_size_t i = 0; i < mDelayTable.size(); i++) - mDelayTable[i].reserve(16); - - GamepadData_t data(8, 1.f); - mDelayTable[0].push_back(data); - mDelayTable[0].push_back(data); - mDelayTable[0].push_back(data); - mDelayTable[0].push_back(data); - - EATEST_VERIFY(mDelayTable[0].size() == 4); - GamepadData_t dataFront = mDelayTable[0].front(); - EATEST_VERIFY((dataFront.size() == 8) && (dataFront[0] == 1.f)); - mDelayTable[0].pop_front(); - } - - { - // Regression for bug with iterator subtraction - typedef eastl::ring_buffer<int> IntBuffer_t; - IntBuffer_t intBuffer = { 0, 1, 2, 3, 4, 5, 6, 7 }; - IntBuffer_t::iterator it = intBuffer.begin(); - - EATEST_VERIFY(*it == 0); - it += 4; - EATEST_VERIFY(*it == 4); - it--; - EATEST_VERIFY(*it == 3); - it -= 2; - EATEST_VERIFY(*it == 1); - - intBuffer.push_back(8); - intBuffer.push_back(9); - intBuffer.push_back(10); - intBuffer.push_back(11); - - EATEST_VERIFY(*it == 10); - it -= 3; - EATEST_VERIFY(*it == 7); // Test looping around the end of the underlying container - it -= 5; - EATEST_VERIFY(*it == 11); // Test wrapping around begin to end of the ring_buffer - it -= 2; - EATEST_VERIFY(*it == 9); // It is important to test going back to the beginning of the underlying container. - - } - - // fixed_ring_buffer<T,N> tests - // ring_buffer<T, fixed_vector<T,N>> tests - { - { - // (MAX_ELEMENTS - 1) accommodates the ring_buffer sentinel - const int MAX_ELEMENTS = 8; - eastl::ring_buffer<int, eastl::fixed_vector<int, MAX_ELEMENTS, false>> rb(MAX_ELEMENTS - 1); - - for (int i = 0; i < MAX_ELEMENTS - 1; i++) - rb.push_back(i); - - auto it = rb.begin(); - for (int i = 0; i < MAX_ELEMENTS - 1; i++) - { EATEST_VERIFY(*it++ == i); } - } - - #if !defined(EA_COMPILER_NO_TEMPLATE_ALIASES) - { - const int MAX_ELEMENTS = 25; - eastl::fixed_ring_buffer<int, MAX_ELEMENTS> rb(MAX_ELEMENTS); - - for(int i = 0; i < MAX_ELEMENTS; i++) - rb.push_back(i); - - auto it = rb.begin(); - for(int i = 0; i < MAX_ELEMENTS; i++) - { EATEST_VERIFY(*it++ == i); } - } - #endif - - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) && !defined(EA_COMPILER_NO_TEMPLATE_ALIASES) - { - const int MAX_ELEMENTS = 8; - eastl::fixed_ring_buffer<int, MAX_ELEMENTS> rb = {0, 1, 2, 3, 4, 5, 6, 7}; - - auto it = rb.begin(); - for(int i = 0; i < MAX_ELEMENTS; i++) - { EATEST_VERIFY(*it++ == i); } - } - - { - struct LocalStruct {}; - fixed_ring_buffer<LocalStruct, 8> rb = {{{}, {}, {}}}; - EATEST_VERIFY(rb.size() == 3); - } - #endif - } - - { - const auto MAX_ELEMENTS = EASTL_MAX_STACK_USAGE; - - // create a container simulating LARGE state that exceeds - // our maximum stack size macro. This forces our ring_buffer implementation - // to allocate the container in the heap instead of holding it on the stack. - // This test ensures that allocation is NOT serviced by the default global heap. - // Instead it is serviced by the allocator of the ring_buffers underlying container. - struct PaddedVector : public eastl::vector<int, MallocAllocator> - { - char mPadding[EASTL_MAX_STACK_USAGE]; - }; - - MallocAllocator::reset_all(); - CountingAllocator::resetCount(); - - { - CountingAllocator countingAlloc; - AutoDefaultAllocator _(&countingAlloc); - - eastl::ring_buffer<int, PaddedVector> intBuffer(1); - for (int i = 0; i < MAX_ELEMENTS; i++) - intBuffer.push_back(i); - - #if !EASTL_OPENSOURCE - const auto cacheAllocationCount = gEASTLTest_TotalAllocationCount; - #endif - const auto cacheMallocatorCount = MallocAllocator::mAllocCountAll; - const auto forceReAllocSize = intBuffer.size() * 2; - - intBuffer.resize(forceReAllocSize); - - #if !EASTL_OPENSOURCE - VERIFY(cacheAllocationCount == gEASTLTest_TotalAllocationCount); - #endif - VERIFY(cacheMallocatorCount < MallocAllocator::mAllocCountAll); - VERIFY(CountingAllocator::neverUsed()); - } - } - - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestSList.cpp b/test/source/TestSList.cpp deleted file mode 100644 index 94a4d3a..0000000 --- a/test/source/TestSList.cpp +++ /dev/null @@ -1,928 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EASTL/slist.h> -#include <EABase/eabase.h> -#include <EASTL/fixed_allocator.h> - -using namespace eastl; - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -struct TestObj -{ - TestObj() : mI(0), mMoveCtor(0), mCopyCtor(0) {} - explicit TestObj(int i) : mI(i), mMoveCtor(0), mCopyCtor(0) {} - explicit TestObj(int a, int b, int c, int d) : mI(a+b+c+d), mMoveCtor(0), mCopyCtor(0) {} - - TestObj(TestObj&& other) - { - mI = other.mI; - mMoveCtor = other.mMoveCtor; - mCopyCtor = other.mCopyCtor; - mMoveCtor++; - } - - TestObj(const TestObj& other) - { - mI = other.mI; - mMoveCtor = other.mMoveCtor; - mCopyCtor = other.mCopyCtor; - mCopyCtor++; - } - - TestObj& operator=(const TestObj& other) - { - mI = other.mI; - mMoveCtor = other.mMoveCtor; - mCopyCtor = other.mCopyCtor; - return *this; - } - - int mI; - int mMoveCtor; - int mCopyCtor; -}; - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// TestSList -int TestSList() -{ - int nErrorCount = 0; - - // slist(); - { - slist<int> list; - VERIFY(list.empty()); - VERIFY(list.size() == 0); - } - - // slist(const allocator_type& allocator); - { - MallocAllocator::reset_all(); - - VERIFY(MallocAllocator::mAllocCountAll == 0); - slist<int, MallocAllocator> list; - list.resize(100, 42); - VERIFY(MallocAllocator::mAllocCountAll == 100); - } - - // explicit slist(size_type n, const allocator_type& allocator = EASTL_SLIST_DEFAULT_ALLOCATOR); - { - slist<int> list(100); - VERIFY(list.size() == 100); - VERIFY(!list.empty()); - } - - // slist(size_type n, const value_type& value, const allocator_type& allocator = EASTL_SLIST_DEFAULT_ALLOCATOR); - { - slist<int> list(32, 42); - VERIFY(list.size() == 32); - VERIFY(list.front() == 42); - VERIFY(!list.empty()); - } - - // slist(const this_type& x); - { - slist<int> list1; - list1.resize(100, 42); - - VERIFY(!list1.empty()); - slist<int> list2(list1); - VERIFY(!list2.empty()); - VERIFY(list1 == list2); - } - - // slist(std::initializer_list<value_type> ilist, const allocator_type& allocator = EASTL_SLIST_DEFAULT_ALLOCATOR); - { - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - slist<int> list1({1,2,3,4,5,6,7,8}); - VERIFY(!list1.empty()); - VERIFY(list1.size() == 8); - #endif - } - - // slist(this_type&& x); - { - slist<int> list1; - list1.resize(100,42); - - slist<int> list2(eastl::move(list1)); - - VERIFY(list1.empty()); - VERIFY(!list2.empty()); - VERIFY(list1 != list2); - } - - // slist(this_type&& x, const allocator_type& allocator); - { } - - // slist(InputIterator first, InputIterator last); - { - slist<int> list1; - list1.resize(100, 42); - VERIFY(!list1.empty()); - - slist<int> list2(list1.begin(), list1.end()); - VERIFY(!list2.empty()); - VERIFY(list1 == list2); - } - - // this_type& operator=(const this_type& x); - { - slist<int> list1; - list1.resize(100, 42); - VERIFY(!list1.empty()); - - slist<int> list2 = list1; - VERIFY(!list2.empty()); - VERIFY(list1 == list2); - } - - // this_type& operator=(std::initializer_list<value_type>); - { - slist<int> list1 = {1,2,3,4,5,6,7,8}; - VERIFY(!list1.empty()); - } - - // this_type& operator=(this_type&& x); - { - slist<int> list1; - list1.resize(100, 42); - slist<int> list2 = eastl::move(list1); - - VERIFY(list1.empty()); - VERIFY(!list2.empty()); - VERIFY(list1 != list2); - } - - // void swap(this_type& x); - { - slist<int> list1; - list1.resize(8, 37); - - slist<int> list2; - VERIFY(!list1.empty()); - VERIFY(list1.size() == 8); - VERIFY(list2.empty()); - - list2.swap(list1); - - VERIFY(list1.empty()); - VERIFY(!list2.empty()); - } - - // void assign(size_type n, const value_type& value); - { - slist<int> list1; - list1.assign(100, 42); - - VERIFY(!list1.empty()); - VERIFY(list1.size() == 100); - - for(auto& e : list1) - VERIFY(e == 42); - } - - // void assign(std::initializer_list<value_type> ilist); - { - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - slist<int> list1; - list1.assign({1,2,3,4,5,6,7,8}); - - VERIFY(!list1.empty()); - VERIFY(list1.size() == 8); - - auto i = eastl::begin(list1); - VERIFY(*i == 1); i++; - VERIFY(*i == 2); i++; - VERIFY(*i == 3); i++; - VERIFY(*i == 4); i++; - VERIFY(*i == 5); i++; - VERIFY(*i == 6); i++; - VERIFY(*i == 7); i++; - VERIFY(*i == 8); i++; - VERIFY(i == eastl::end(list1)); - #endif - } - - // void assign(InputIterator first, InputIterator last); - { - slist<int> list1; - list1.resize(100, 42); - VERIFY(!list1.empty()); - - slist<int> list2; - list2.assign(list1.begin(), list1.end()); - VERIFY(!list2.empty()); - VERIFY(list1 == list2); - } - - // iterator begin() EA_NOEXCEPT; - // const_iterator begin() const EA_NOEXCEPT; - // const_iterator cbegin() const EA_NOEXCEPT; - { - slist<int> list1; - list1.resize(100, 1); - VERIFY(!list1.empty()); - - const auto ci = list1.begin(); - auto i = list1.begin(); - auto ci2 = list1.cbegin(); - - VERIFY(*i == 1); - VERIFY(*ci == 1); - VERIFY(*ci2 == 1); - } - - // iterator end() EA_NOEXCEPT; - // const_iterator end() const EA_NOEXCEPT; - // const_iterator cend() const EA_NOEXCEPT; - { - slist<int> list1; - list1.resize(100, 42); - VERIFY(!list1.empty()); - - const auto ci = list1.end(); - auto i = list1.end(); - auto ci2 = list1.cend(); - - VERIFY(i == eastl::end(list1)); - VERIFY(ci == eastl::end(list1)); - VERIFY(ci2 == eastl::end(list1)); - } - - // iterator before_begin() EA_NOEXCEPT; - // const_iterator before_begin() const EA_NOEXCEPT; - // const_iterator cbefore_begin() const EA_NOEXCEPT; - // iterator previous(const_iterator position); - // const_iterator previous(const_iterator position) const; - { - slist<int> list1; - - auto b = list1.begin(); - auto prev = list1.previous(b); - - VERIFY(prev == list1.before_begin()); - } - - // reference front(); - // const_reference front() const; - { - slist<int> list1; - list1.resize(100, 1); - - VERIFY(list1.begin() == eastl::begin(list1)); - VERIFY(list1.front() == 1); - - const slist<int> clist1(list1); - VERIFY(clist1.front() == 1); - VERIFY(list1.validate()); - VERIFY(clist1.validate()); - } - - - // void emplace_front(Args&&... args); - // void emplace_front(value_type&& value); - // void emplace_front(const value_type& value); - { - slist<TestObj> list1; - list1.emplace_front(42); - VERIFY(list1.front().mI == 42); - VERIFY(list1.front().mCopyCtor == 0); - VERIFY(list1.front().mMoveCtor == 0); - VERIFY(list1.size() == 1); - VERIFY(list1.validate()); - - list1.emplace_front(1,2,3,4); - VERIFY(list1.front().mCopyCtor == 0); - VERIFY(list1.front().mMoveCtor == 0); - VERIFY(list1.front().mI == (1+2+3+4)); - VERIFY(list1.size() == 2); - VERIFY(list1.validate()); - } - - // void push_front(const value_type& value); - // reference push_front(); - // void push_front(value_type&& value); - { - slist<TestObj> list1; - list1.push_front(TestObj(42)); - VERIFY(list1.front().mI == 42); - VERIFY(list1.front().mCopyCtor == 0); - VERIFY(list1.front().mMoveCtor == 1); - VERIFY(list1.size() == 1); - - list1.push_front(); - VERIFY(list1.front().mCopyCtor == 0); - VERIFY(list1.front().mMoveCtor == 0); - VERIFY(list1.front().mI == 0); - VERIFY(list1.size() == 2); - - list1.push_front().mI = 1492; - VERIFY(list1.front().mI == 1492); - VERIFY(list1.validate()); - } - - // void pop_front(); - { - slist<int> list1; - list1.push_front(4); - list1.push_front(3); - list1.push_front(2); - list1.push_front(1); - - list1.pop_front(); - VERIFY(list1.front() == 2); - VERIFY(list1.size() == 3); - VERIFY(list1.validate()); - - list1.pop_front(); - VERIFY(list1.front() == 3); - VERIFY(list1.size() == 2); - VERIFY(list1.validate()); - - list1.pop_front(); - VERIFY(list1.front() == 4); - VERIFY(list1.size() == 1); - VERIFY(list1.validate()); - } - - // bool empty() const EA_NOEXCEPT; - // size_type size() const EA_NOEXCEPT; - { - slist<int> list1; - VERIFY(list1.empty()); - VERIFY(list1.size() == 0); - VERIFY(list1.validate()); - - list1.push_front(42); - VERIFY(!list1.empty()); - VERIFY(list1.size() == 1); - VERIFY(list1.validate()); - - list1.pop_front(); - VERIFY(list1.empty()); - VERIFY(list1.size() == 0); - VERIFY(list1.validate()); - } - - - // void resize(size_type n, const value_type& value); - // void resize(size_type n); - { - slist<int> list1; - VERIFY(list1.empty()); - list1.resize(100, 42); - VERIFY(list1.front() == 42); - VERIFY(!list1.empty()); - VERIFY(list1.size() == 100); - VERIFY(list1.validate()); - - slist<int> list2; - VERIFY(list2.empty()); - list2.resize(100); - VERIFY(!list2.empty()); - VERIFY(list2.size() == 100); - VERIFY(list2.validate()); - } - - // iterator insert(const_iterator position); - // iterator insert(const_iterator position, const value_type& value); - // void insert(const_iterator position, size_type n, const value_type& value); - { - static const int MAGIC_VALUE = 4242; - struct TestVal - { - TestVal() : mV(MAGIC_VALUE) {} - TestVal(int v) : mV(v) {} - operator int() { return mV; } - int mV; - }; - - slist<TestVal> list1; - VERIFY(list1.empty()); - - auto insert_iter = eastl::begin(list1); - list1.insert(insert_iter); - VERIFY(list1.size() == 1); - VERIFY(!list1.empty()); - VERIFY(list1.validate()); - - list1.insert(insert_iter, 42); - VERIFY(list1.size() == 2); - VERIFY(!list1.empty()); - VERIFY(list1.front() == MAGIC_VALUE); - VERIFY(list1.validate()); - - - list1.insert(insert_iter, 43); - VERIFY(list1.size() == 3); - VERIFY(!list1.empty()); - VERIFY(list1.front() == MAGIC_VALUE); - VERIFY(list1.validate()); - } - - // template <typename InputIterator> - // void insert(const_iterator position, InputIterator first, InputIterator last); - { - slist<int> list1; - VERIFY(list1.empty()); - list1.resize(100, 42); - VERIFY(list1.size() == 100); - VERIFY(!list1.empty()); - VERIFY(list1.validate()); - - slist<int> list2; - list2.resize(400, 24); - VERIFY(list2.size() == 400); - VERIFY(!list2.empty()); - VERIFY(list1.validate()); - - list1.insert(eastl::end(list1), eastl::begin(list2), eastl::end(list2)); // [42,42,42,...,42, | 24,24,24,24...] - VERIFY(!list1.empty()); - VERIFY(list1.size() == 500); - VERIFY(list1.front() == 42); - VERIFY(list1.validate()); - - auto boundary_iter = list1.begin(); - eastl::advance(boundary_iter, 100); // move to insertation point - VERIFY(*boundary_iter == 24); - VERIFY(list1.validate()); - } - - - // Returns an iterator pointing to the last inserted element, or position if insertion count is zero. - // iterator insert_after(const_iterator position); - // iterator insert_after(const_iterator position, const value_type& value); - // iterator insert_after(const_iterator position, size_type n, const value_type& value); - // iterator insert_after(const_iterator position, std::initializer_list<value_type> ilist); - { - slist<int> list1; - VERIFY(list1.empty()); - list1.push_front(); - - list1.insert_after(list1.begin()); - VERIFY(!list1.empty()); - VERIFY(list1.size() == 2); - VERIFY(list1.validate()); - - list1.insert_after(list1.begin(), 43); - VERIFY(list1.size() == 3); - VERIFY(list1.validate()); - - list1.insert_after(list1.begin(), 10, 42); - VERIFY(list1.size() == 13); - VERIFY(eastl::count_if(list1.begin(), list1.end(), [](int i) { return i == 42; }) == 10); - VERIFY(list1.validate()); - - list1.insert_after(list1.begin(), {1,2,3,4,5,6,7,8,9,0}); - VERIFY(list1.size() == 23); - VERIFY(list1.validate()); - } - - // iterator insert_after(const_iterator position, value_type&& value); - { - slist<TestObj> list1; - VERIFY(list1.empty()); - list1.push_front(); - - auto inserted = list1.insert_after(list1.begin(), TestObj(42)); - VERIFY(!list1.empty()); - VERIFY((*inserted).mCopyCtor == 0); - VERIFY((*inserted).mMoveCtor == 1); - } - - // iterator insert_after(const_iterator position, InputIterator first, InputIterator last); - { - slist<int> list1 = {0,1,2,3,4}; - slist<int> list2 = {9,8,7,6,5}; - list1.insert_after(list1.begin(), list2.begin(), list2.end()); - VERIFY(list1 == slist<int>({0,9,8,7,6,5,1,2,3,4})); - } - - // iterator emplace_after(const_iterator position, Args&&... args); - // iterator emplace_after(const_iterator position, value_type&& value); - // iterator emplace_after(const_iterator position, const value_type& value); - { - slist<TestObj> list1; - list1.emplace_after(list1.before_begin(), 42); - VERIFY(list1.front().mI == 42); - VERIFY(list1.front().mCopyCtor == 0); - VERIFY(list1.front().mMoveCtor == 0); - VERIFY(list1.size() == 1); - VERIFY(list1.validate()); - - list1.emplace_after(list1.before_begin(),1,2,3,4); - VERIFY(list1.front().mCopyCtor == 0); - VERIFY(list1.front().mMoveCtor == 0); - VERIFY(list1.front().mI == (1+2+3+4)); - VERIFY(list1.size() == 2); - VERIFY(list1.validate()); - } - - // iterator erase(const_iterator position); - // iterator erase(const_iterator first, const_iterator last); - { - slist<int> list1 = {0,1,2,3,4,5,6,7}; - - auto p = list1.begin(); - p++; p++; p++; - - list1.erase(p); - VERIFY(list1 == slist<int>({0,1,2,4,5,6,7})); - - list1.erase(list1.begin(), list1.end()); - VERIFY(list1 == slist<int>({})); - VERIFY(list1.size() == 0); - VERIFY(list1.empty()); - } - - // iterator erase_after(const_iterator position); - // iterator erase_after(const_iterator before_first, const_iterator last); - { - slist<int> list1 = {0,1,2,3,4,5,6,7}; - auto p = list1.begin(); - - list1.erase_after(p); - VERIFY(list1 == slist<int>({0,2,3,4,5,6,7})); - VERIFY(list1.validate()); - - list1.erase_after(p); - VERIFY(list1 == slist<int>({0,3,4,5,6,7})); - VERIFY(list1.validate()); - - list1.erase_after(p); - VERIFY(list1 == slist<int>({0,4,5,6,7})); - VERIFY(list1.validate()); - - list1.erase_after(p, list1.end()); - VERIFY(list1 == slist<int>({0})); - VERIFY(list1.validate()); - } - - // void clear(); - { - slist<int> list1; - list1.resize(100, 42); - VERIFY(!list1.empty()); - VERIFY(list1.size() == 100); - VERIFY(list1.validate()); - - list1.clear(); - VERIFY(list1.empty()); - VERIFY(list1.size() == 0); - VERIFY(list1.validate()); - } - - // void reset_lose_memory(); - { - typedef eastl::slist<int, fixed_allocator> SIntList; - typedef SIntList::node_type SIntListNode; - const size_t kBufferCount = 100; - SIntListNode buffer1[kBufferCount]; - SIntList list1; - const size_t kAlignOfSIntListNode = EA_ALIGN_OF(SIntListNode); - list1.get_allocator().init(buffer1, sizeof(buffer1), sizeof(SIntListNode), kAlignOfSIntListNode); - - VERIFY(list1.empty()); - VERIFY(list1.size() == 0); - VERIFY(list1.validate()); - - list1.resize(kBufferCount, 42); - VERIFY(!list1.empty()); - VERIFY(list1.size() == kBufferCount); - VERIFY(list1.validate()); - - list1.reset_lose_memory(); - VERIFY(list1.empty()); - VERIFY(list1.size() == 0); - VERIFY(list1.validate()); - } - - // void remove(const value_type& value); - { - slist<int> list1 = {0,1,2,3,4}; - slist<int> list2 = {0,1,3,4}; - - list1.remove(2); - - VERIFY(list1 == list2); - VERIFY(list1.validate()); - VERIFY(list2.validate()); - } - - // void remove_if(Predicate predicate); - { - slist<int> list1; - list1.resize(100, 42); - VERIFY(list1.size() == 100); - VERIFY(list1.validate()); - - list1.remove_if([](int i) { return i == 1234; }); // intentionally remove nothing. - VERIFY(list1.size() == 100); - VERIFY(list1.validate()); - - list1.remove_if([](int i) { return i == 42; }); - VERIFY(list1.size() == 0); - VERIFY(list1.validate()); - } - - // void reverse() EA_NOEXCEPT; - { - slist<int> list1 = {0,1,2,3,4}; - slist<int> list2 = {4,3,2,1,0}; - VERIFY(list1 != list2); - - list1.reverse(); - VERIFY(list1 == list2); - } - - // void splice(const_iterator position, this_type& x); - // void splice(const_iterator position, this_type& x, const_iterator i); - // void splice(const_iterator position, this_type& x, const_iterator first, const_iterator last); - { - slist<int> valid = {0,1,2,3,4,5,6,7}; - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - list1.splice(list1.end(), list2); - - VERIFY(list1 == valid); - VERIFY(list1.validate()); - } - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - - list1.splice(list1.begin(), list2, list2.begin()); - VERIFY(list1 == slist<int>({4,0,1,2,3})); - VERIFY(list2 == slist<int>({5,6,7})); - - list1.splice(list1.begin(), list2, list2.begin()); - VERIFY(list1 == slist<int>({5,4,0,1,2,3})); - VERIFY(list2 == slist<int>({6,7})); - - list1.splice(list1.begin(), list2, list2.begin()); - VERIFY(list1 == slist<int>({6,5,4,0,1,2,3})); - VERIFY(list2 == slist<int>({7})); - - list1.splice(list1.begin(), list2, list2.begin()); - VERIFY(list1 == slist<int>({7,6,5,4,0,1,2,3})); - VERIFY(list2 == slist<int>({})); - - VERIFY(list1.validate()); - VERIFY(list2.validate()); - } - } - - // void splice(const_iterator position, this_type&& x); - // void splice(const_iterator position, this_type&& x, const_iterator i); - // void splice(const_iterator position, this_type&& x, const_iterator first, const_iterator last); - { - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - - list1.splice(list1.begin(), eastl::move(list2)); - VERIFY(list1 == slist<int>({4,5,6,7,0,1,2,3})); - } - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - - list1.splice(list1.begin(), eastl::move(list2), list2.begin()); - VERIFY(list1 == slist<int>({4,0,1,2,3})); - } - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - - auto b = list2.begin(); - auto e = list2.end(); - e = list2.previous(e); - e = list2.previous(e); - - list1.splice(list1.begin(), eastl::move(list2), b, e); - VERIFY(list1 == slist<int>({4,5,0,1,2,3})); - } - } - - // void splice_after(const_iterator position, this_type& x); - // void splice_after(const_iterator position, this_type& x, const_iterator i); - // void splice_after(const_iterator position, this_type& x, const_iterator first, const_iterator last); - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - - list1.splice_after(list1.begin(), list2); - VERIFY(list1 == slist<int>({0,4,5,6,7,1,2,3})); - VERIFY(list1.validate()); - VERIFY(list2.validate()); - } - - // void splice_after(const_iterator position, this_type&& x); - // void splice_after(const_iterator position, this_type&& x, const_iterator i); - // void splice_after(const_iterator position, this_type&& x, const_iterator first, const_iterator last); - { - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - - list1.splice_after(list1.begin(), eastl::move(list2)); - VERIFY(list1 == slist<int>({0,4,5,6,7,1,2,3})); - } - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - - list1.splice_after(list1.begin(), eastl::move(list2), list2.begin()); - VERIFY(list1 == slist<int>({0,5,6,7,1,2,3})); - } - { - slist<int> list1 = {0,1,2,3}; - slist<int> list2 = {4,5,6,7}; - - auto b = list2.begin(); - auto e = list2.end(); - e = list2.previous(e); - e = list2.previous(e); - - list1.splice_after(list1.begin(), eastl::move(list2), b, e); - VERIFY(list1 == slist<int>({0,5,6,1,2,3})); - } - } - - // void sort(); - { - slist<int> list1 = {0, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 1, 0}; - VERIFY(!eastl::is_sorted(eastl::begin(list1), eastl::end(list1))); - VERIFY(list1.validate()); - - list1.sort(); - - VERIFY(eastl::is_sorted(eastl::begin(list1), eastl::end(list1))); - VERIFY(list1.validate()); - } - - // template <class Compare> - // void sort(Compare compare); - { - auto compare = [](int a, int b) { return a > b;}; - - slist<int> list1 = {0, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 1, 0}; - VERIFY(!eastl::is_sorted(eastl::begin(list1), eastl::end(list1), compare)); - list1.sort(compare); - VERIFY(eastl::is_sorted(eastl::begin(list1), eastl::end(list1), compare)); - } - - { // Test empty base-class optimization - struct UnemptyDummyAllocator : eastl::dummy_allocator - { - int foo; - }; - - typedef eastl::slist<int, eastl::dummy_allocator> list1; - typedef eastl::slist<int, UnemptyDummyAllocator> list2; - - EATEST_VERIFY(sizeof(list1) < sizeof(list2)); - } - - { // Test erase / erase_if - { - slist<int> l = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto numErased = eastl::erase(l, 5); - VERIFY((l == slist<int>{0, 1, 2, 3, 4, 6, 7, 8, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase(l, 7); - VERIFY((l == slist<int>{0, 1, 2, 3, 4, 6, 8, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase(l, 2); - VERIFY((l == slist<int>{0, 1, 3, 4, 6, 8, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase(l, 0); - VERIFY((l == slist<int>{1, 3, 4, 6, 8, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase(l, 4); - VERIFY((l == slist<int>{1, 3, 6, 8, 9})); - VERIFY(numErased == 1); - } - - { - slist<int> l = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto numErased = eastl::erase_if(l, [](auto e) { return e % 2 == 0; }); - VERIFY((l == slist<int>{1, 3, 5, 7, 9})); - VERIFY(numErased == 5); - - numErased = eastl::erase_if(l, [](auto e) { return e == 5; }); - VERIFY((l == slist<int>{1, 3, 7, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase_if(l, [](auto e) { return e % 3 == 0; }); - VERIFY((l == slist<int>{1, 7})); - VERIFY(numErased == 2); - } - } - - { // Test global operators - { - slist<int> list1 = {0, 1, 2, 3, 4, 5}; - slist<int> list2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - slist<int> list3 = {5, 6, 7, 8}; - - VERIFY(list1 == list1); - VERIFY(!(list1 != list1)); - - VERIFY(list1 != list2); - VERIFY(list2 != list3); - VERIFY(list1 != list3); - - VERIFY(list1 < list2); - VERIFY(list1 <= list2); - - VERIFY(list2 > list1); - VERIFY(list2 >= list1); - - VERIFY(list3 > list1); - VERIFY(list3 > list2); - } - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - slist<int> list1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - slist<int> list2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - slist<int> list3 = {-1, 0, 1, 2, 3, 4, 5}; - - // Verify equality between list1 and list2 - VERIFY((list1 <=> list2) == 0); - VERIFY(!((list1 <=> list2) != 0)); - VERIFY((list1 <=> list2) <= 0); - VERIFY((list1 <=> list2) >= 0); - VERIFY(!((list1 <=> list2) < 0)); - VERIFY(!((list1 <=> list2) > 0)); - - list1.push_front(-2); // Make list1 less than list2. - list2.push_front(-1); - - // Verify list1 < list2 - VERIFY(!((list1 <=> list2) == 0)); - VERIFY((list1 <=> list2) != 0); - VERIFY((list1 <=> list2) <= 0); - VERIFY(!((list1 <=> list2) >= 0)); - VERIFY(((list1 <=> list2) < 0)); - VERIFY(!((list1 <=> list2) > 0)); - - - // Verify list3.size() < list2.size() and list3 is a subset of list2 - VERIFY(!((list3 <=> list2) == 0)); - VERIFY((list3 <=> list2) != 0); - VERIFY((list3 <=> list2) <= 0); - VERIFY(!((list3 <=> list2) >= 0)); - VERIFY(((list3 <=> list2) < 0)); - VERIFY(!((list3 <=> list2) > 0)); - } - - { - slist<int> list1 = {1, 2, 3, 4, 5, 6, 7}; - slist<int> list2 = {7, 6, 5, 4, 3, 2, 1}; - slist<int> list3 = {1, 2, 3, 4}; - - struct weak_ordering_slist - { - slist<int> slist; - inline std::weak_ordering operator<=>(const weak_ordering_slist& b) const { return slist <=> b.slist; } - }; - - VERIFY(synth_three_way{}(weak_ordering_slist{list1}, weak_ordering_slist{list2}) == std::weak_ordering::less); - VERIFY(synth_three_way{}(weak_ordering_slist{list3}, weak_ordering_slist{list1}) == std::weak_ordering::less); - VERIFY(synth_three_way{}(weak_ordering_slist{list2}, weak_ordering_slist{list1}) == std::weak_ordering::greater); - VERIFY(synth_three_way{}(weak_ordering_slist{list2}, weak_ordering_slist{list3}) == std::weak_ordering::greater); - VERIFY(synth_three_way{}(weak_ordering_slist{list1}, weak_ordering_slist{list1}) == std::weak_ordering::equivalent); - - struct strong_ordering_slist - { - slist<int> slist; - inline std::strong_ordering operator<=>(const strong_ordering_slist& b) const { return slist <=> b.slist; } - }; - - VERIFY(synth_three_way{}(strong_ordering_slist{list1}, strong_ordering_slist{list2}) == std::strong_ordering::less); - VERIFY(synth_three_way{}(strong_ordering_slist{list3}, strong_ordering_slist{list1}) == std::strong_ordering::less); - VERIFY(synth_three_way{}(strong_ordering_slist{list2}, strong_ordering_slist{list1}) == std::strong_ordering::greater); - VERIFY(synth_three_way{}(strong_ordering_slist{list2}, strong_ordering_slist{list3}) == std::strong_ordering::greater); - VERIFY(synth_three_way{}(strong_ordering_slist{list1}, strong_ordering_slist{list1}) == std::strong_ordering::equal); - } -#endif - } - - return nErrorCount; -} - diff --git a/test/source/TestSegmentedVector.cpp b/test/source/TestSegmentedVector.cpp deleted file mode 100644 index bb920b7..0000000 --- a/test/source/TestSegmentedVector.cpp +++ /dev/null @@ -1,89 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EASTL/segmented_vector.h> -#include <EASTL/list.h> - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::segmented_vector<bool, 16>; -template class eastl::segmented_vector<int, 16>; -template class eastl::segmented_vector<Align64, 16>; -template class eastl::segmented_vector<TestObject, 16>; - - -int TestSegmentedVector() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { - eastl::segmented_vector<int, 8> sv; - sv.push_back(0); - sv.push_back(1); - sv.push_back(2); - sv.push_back(3); - - { - auto i = sv.begin(); - EATEST_VERIFY(*i == 0); - EATEST_VERIFY(*i++ == 0); - EATEST_VERIFY(*i++ == 1); - EATEST_VERIFY(*i++ == 2); - EATEST_VERIFY(*i++ == 3); - } - - { - auto i = sv.begin(); - EATEST_VERIFY(*i == 0); - EATEST_VERIFY(*(++i) == 1); - EATEST_VERIFY(*(++i) == 2); - EATEST_VERIFY(*(++i) == 3); - } - } - - { - // Construct segmented_vectors of different types. - eastl::segmented_vector<int, 8> vectorOfInt; - eastl::segmented_vector<TestObject, 8> vectorOfTO; - eastl::segmented_vector<eastl::list<TestObject>, 8> vectorOfListOfTO; - - EATEST_VERIFY(vectorOfInt.empty()); - EATEST_VERIFY(vectorOfTO.empty()); - EATEST_VERIFY(vectorOfListOfTO.empty()); - } - - { - // Test basic segmented_vector operations. - eastl::segmented_vector<int, 4> vectorOfInt; - - vectorOfInt.push_back(42); - EATEST_VERIFY(vectorOfInt.size() == 1); - EATEST_VERIFY(vectorOfInt.segment_count() == 1); - EATEST_VERIFY(vectorOfInt.empty() == false); - - vectorOfInt.push_back(43); - vectorOfInt.push_back(44); - vectorOfInt.push_back(45); - vectorOfInt.push_back(46); - EATEST_VERIFY(vectorOfInt.size() == 5); - EATEST_VERIFY(vectorOfInt.segment_count() == 2); - - EATEST_VERIFY(vectorOfInt.front() == 42); - EATEST_VERIFY(vectorOfInt.back() == 46); - - vectorOfInt.pop_back(); - EATEST_VERIFY(vectorOfInt.size() == 4); - EATEST_VERIFY(vectorOfInt.segment_count() == 1); - - vectorOfInt.clear(); - EATEST_VERIFY(vectorOfInt.empty()); - EATEST_VERIFY(vectorOfInt.size() == 0); - EATEST_VERIFY(vectorOfInt.segment_count() == 0); - } - - return nErrorCount; -} diff --git a/test/source/TestSet.cpp b/test/source/TestSet.cpp deleted file mode 100644 index 9a590c2..0000000 --- a/test/source/TestSet.cpp +++ /dev/null @@ -1,256 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "TestSet.h" -#include "EASTLTest.h" -#include <EASTL/map.h> -#include <EASTL/set.h> -#include <EASTL/functional.h> -#include <EASTL/internal/config.h> -#include <EABase/eabase.h> - - -EA_DISABLE_ALL_VC_WARNINGS() -#include <stdio.h> - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <set> - #include <map> - #include <algorithm> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::set<int>; -template class eastl::multiset<float>; -template class eastl::set<TestObject>; -template class eastl::multiset<TestObject>; - - -/////////////////////////////////////////////////////////////////////////////// -// typedefs -// -typedef eastl::set<int> VS1; -typedef eastl::set<TestObject> VS4; -typedef eastl::multiset<int> VMS1; -typedef eastl::multiset<TestObject> VMS4; - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - typedef std::set<int> VS3; - typedef std::set<TestObject> VS6; - typedef std::multiset<int> VMS3; - typedef std::multiset<TestObject> VMS6; -#endif - -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// xvalue_test -// -// Test utility type that sets the class data to known value when its data has -// has been moved out. This enables us to write tests that verify that the -// destruction action taken on container elements occured during move operations. -// -struct xvalue_test -{ - static const int MOVED_FROM = -1; - - int data = 42; - - xvalue_test(int in) : data(in) {} - ~xvalue_test() = default; - - xvalue_test(const xvalue_test& other) - : data(other.data) {} - - xvalue_test& operator=(const xvalue_test& other) - { - data = other.data; - return *this; - } - - xvalue_test(xvalue_test&& other) - { - data = other.data; - other.data = MOVED_FROM; - } - - xvalue_test& operator=(xvalue_test&& other) - { - data = other.data; - other.data = MOVED_FROM; - return *this; - } - - friend bool operator<(const xvalue_test& rhs, const xvalue_test& lhs) - { return rhs.data < lhs.data; } -}; - - - -int TestSet() -{ - int nErrorCount = 0; - - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - { // Test construction - nErrorCount += TestSetConstruction<VS1, VS3, false>(); - nErrorCount += TestSetConstruction<VS4, VS6, false>(); - - nErrorCount += TestSetConstruction<VMS1, VMS3, true>(); - nErrorCount += TestSetConstruction<VMS4, VMS6, true>(); - } - - - { // Test mutating functionality. - nErrorCount += TestSetMutation<VS1, VS3, false>(); - nErrorCount += TestSetMutation<VS4, VS6, false>(); - - nErrorCount += TestSetMutation<VMS1, VMS3, true>(); - nErrorCount += TestSetMutation<VMS4, VMS6, true>(); - } - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - - { // Test searching functionality. - nErrorCount += TestSetSearch<VS1, false>(); - nErrorCount += TestSetSearch<VS4, false>(); - - nErrorCount += TestSetSearch<VMS1, true>(); - nErrorCount += TestSetSearch<VMS4, true>(); - } - - - { - // C++11 emplace and related functionality - nErrorCount += TestSetCpp11<eastl::set<TestObject> >(); - - nErrorCount += TestMultisetCpp11<eastl::multiset<TestObject> >(); - } - - - { // Misc tests - - // const key_compare& key_comp() const; - // key_compare& key_comp(); - VS1 vs; - const VS1 vsc; - - const VS1::key_compare& kc = vsc.key_comp(); - vs.key_comp() = kc; - } - - { // non-const comparator test - struct my_less - { - bool operator()(int a, int b) { return a < b; } - }; - - { - set<int, my_less> a = {0, 1, 2, 3, 4}; - auto i = a.find(42); - VERIFY(i == a.end()); - } - } - - { // set erase_if tests - set<int> s = {0, 1, 2, 3, 4}; - auto numErased = eastl::erase_if(s, [](auto i) { return i % 2 == 0;}); - VERIFY((s == set<int>{1,3})); - VERIFY(numErased == 3); - } - - { // multiset erase_if tests - multiset<int> s = {0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4}; - auto numErased = eastl::erase_if(s, [](auto i) { return i % 2 == 0;}); - VERIFY((s == multiset<int>{1, 1, 1, 3, 3, 3})); - VERIFY(numErased == 7); - } - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { // Test set <=> - set<int> s1 = {0, 1, 2, 3, 4}; - set<int> s2 = {4, 3, 2, 1, 0}; - set<int> s3 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - set<int> s4 = {1, 2, 3, 4, 5, 6}; - set<int> s5 = {9}; - - VERIFY(s1 == s2); - VERIFY(s1 != s3); - VERIFY(s3 > s4); - VERIFY(s5 > s4); - VERIFY(s5 > s3); - - VERIFY((s1 <=> s2) == 0); - VERIFY((s1 <=> s3) != 0); - VERIFY((s3 <=> s4) > 0); - VERIFY((s5 <=> s4) > 0); - VERIFY((s5 <=> s3) > 0); - } - - { // Test multiset <=> - multiset<int> s1 = {0, 0, 0, 1, 1, 2, 3, 3, 4}; - multiset<int> s2 = {4, 3, 3, 2, 1, 1, 0, 0, 0}; - multiset<int> s3 = {1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9}; - multiset<int> s4 = {1, 1, 2, 2, 3, 4, 5, 5, 6}; - multiset<int> s5 = {9}; - - VERIFY(s1 == s2); - VERIFY(s1 != s3); - VERIFY(s3 > s4); - VERIFY(s5 > s4); - VERIFY(s5 > s3); - - VERIFY((s1 <=> s2) == 0); - VERIFY((s1 <=> s3) != 0); - VERIFY((s3 <=> s4) > 0); - VERIFY((s5 <=> s4) > 0); - VERIFY((s5 <=> s3) > 0); - } -#endif - - { - // user reported regression: ensure container elements are NOT - // moved from during the eastl::set construction process. - eastl::vector<xvalue_test> m1 = {{0}, {1}, {2}, {3}, {4}, {5}}; - eastl::set<xvalue_test> m2{m1.begin(), m1.end()}; - - bool result = eastl::all_of(m1.begin(), m1.end(), - [&](auto& e) { return e.data != xvalue_test::MOVED_FROM; }); - - VERIFY(result); - } - - { - // user reported regression: ensure container elements are moved from during the - // eastl::set construction process when using an eastl::move_iterator. - eastl::vector<xvalue_test> m1 = {{0}, {1}, {2}, {3}, {4}, {5}}; - eastl::set<xvalue_test> m2{eastl::make_move_iterator(m1.begin()), eastl::make_move_iterator(m1.end())}; - - bool result = eastl::all_of(m1.begin(), m1.end(), - [&](auto& e) { return e.data == xvalue_test::MOVED_FROM; }); - - VERIFY(result); - } - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestSet.h b/test/source/TestSet.h deleted file mode 100644 index 16f55c7..0000000 --- a/test/source/TestSet.h +++ /dev/null @@ -1,906 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/vector.h> -#include <EASTL/algorithm.h> -#include <EASTL/type_traits.h> -#include <EASTL/scoped_ptr.h> -#include <EASTL/random.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <algorithm> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - -/////////////////////////////////////////////////////////////////////////////// -// TestSetConstruction -// -// This test compares eastl::set/multiset to std::set/multiset. It could possibly -// work for comparing eastl::hash_set to C++11 std::unordered_set, but we would -// rather move towards making this test be independent of any std comparisons. -// -// Requires a container that can hold at least 1000 items. -// -template <typename T1, typename T2, bool bMultiset> -int TestSetConstruction() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { - eastl::scoped_ptr<T1> pt1A(new T1); // We use a pointers instead of concrete object because it's size may be huge. - eastl::scoped_ptr<T2> pt2A(new T2); - T1& t1A = *pt1A; - T2& t2A = *pt2A; - nErrorCount += CompareContainers(t1A, t2A, "Set ctor", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - VERIFY(t1A.validate()); - - - eastl::scoped_ptr<T1> pt1B(new T1); - eastl::scoped_ptr<T2> pt2B(new T2); - T1& t1B = *pt1B; - T2& t2B = *pt2B; - nErrorCount += CompareContainers(t1B, t2B, "Set ctor", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - eastl::scoped_ptr<T1> pt1C(new T1); - eastl::scoped_ptr<T2> pt2C(new T2); - T1& t1C = *pt1C; - T2& t2C = *pt2C; - for(int i = 0; i < 1000; i++) - { - t1C.insert(typename T1::value_type(typename T1::value_type(i))); - t2C.insert(typename T2::value_type(typename T2::value_type(i))); - VERIFY(t1C.validate()); - nErrorCount += CompareContainers(t1C, t2C, "Set insert", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - } - - - eastl::scoped_ptr<T1> pt1D(new T1); - eastl::scoped_ptr<T2> pt2D(new T2); - T1& t1D = *pt1D; - T2& t2D = *pt2D; - nErrorCount += CompareContainers(t1D, t2D, "Set ctor", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - eastl::scoped_ptr<T1> pt1E(new T1(t1C)); - eastl::scoped_ptr<T2> pt2E(new T2(t2C)); - T1& t1E = *pt1E; - T2& t2E = *pt2E; - VERIFY(t1E.validate()); - nErrorCount += CompareContainers(t1E, t2E, "Set ctor", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - eastl::scoped_ptr<T1> pt1F(new T1(t1C.begin(), t1C.end())); - eastl::scoped_ptr<T2> pt2F(new T2(t2C.begin(), t2C.end())); - T1& t1F = *pt1F; - T2& t2F = *pt2F; - VERIFY(t1F.validate()); - nErrorCount += CompareContainers(t1F, t2F, "Set ctor", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - // operator= - t1E = t1D; - t2E = t2D; - nErrorCount += CompareContainers(t1D, t2D, "Set operator=", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - nErrorCount += CompareContainers(t1E, t2E, "Set operator=", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - // operator=(set&&) - // We test just the EASTL container here. - eastl::scoped_ptr<T1> pT1P(new T1); // We use a pointers instead of concrete object because it's size may be huge. - eastl::scoped_ptr<T1> pT1Q(new T1); - T1& t1P = *pT1P; - T1& t1Q = *pT1Q; - - typename T1::value_type v10(0); - typename T1::value_type v11(1); - typename T1::value_type v12(2); - typename T1::value_type v13(3); - typename T1::value_type v14(4); - typename T1::value_type v15(5); - - t1P.insert(v10); - t1P.insert(v11); - t1P.insert(v12); - - t1Q.insert(v13); - t1Q.insert(v14); - t1Q.insert(v15); - - t1Q = eastl::move(t1P); // We are effectively requesting to swap t1A with t1B. - //EATEST_VERIFY((t1P.size() == 3) && (t1P.find(v13) != t1P.end()) && (t1P.find(v14) != t1P.end()) && (t1P.find(v15) != t1P.end())); // Currently operator=(this_type&& x) clears x instead of swapping with it. - - - // swap - t1E.swap(t1D); - t2E.swap(t2D); - VERIFY(t1D.validate()); - VERIFY(t1E.validate()); - nErrorCount += CompareContainers(t1D, t2D, "Set swap", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - nErrorCount += CompareContainers(t1E, t2E, "Set swap", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - // eastl::swap - eastl::swap(t1E, t1D); - std::swap(t2E, t2D); - VERIFY(t1D.validate()); - VERIFY(t1E.validate()); - nErrorCount += CompareContainers(t1D, t2D, "Global swap", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - nErrorCount += CompareContainers(t1E, t2E, "Global swap", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - // clear - t1A.clear(); - t2A.clear(); - VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Set clear", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - t1B.clear(); - t2B.clear(); - VERIFY(t1B.validate()); - nErrorCount += CompareContainers(t1B, t2B, "Set clear", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - // global operators (==, !=, <, etc.) - t1A.clear(); - t1B.clear(); - // Make t1A equal to t1B - t1A.insert(typename T1::value_type(0)); - t1A.insert(typename T1::value_type(1)); - t1A.insert(typename T1::value_type(2)); - - t1B.insert(typename T1::value_type(0)); - t1B.insert(typename T1::value_type(1)); - t1B.insert(typename T1::value_type(2)); - - VERIFY( (t1A == t1B)); - VERIFY(!(t1A != t1B)); - VERIFY( (t1A <= t1B)); - VERIFY( (t1A >= t1B)); - VERIFY(!(t1A < t1B)); - VERIFY(!(t1A > t1B)); - // Make t1A less than t1B - t1A.insert(typename T1::value_type(3)); - t1B.insert(typename T1::value_type(4)); - - VERIFY(!(t1A == t1B)); - VERIFY( (t1A != t1B)); - VERIFY( (t1A <= t1B)); - VERIFY(!(t1A >= t1B)); - VERIFY( (t1A < t1B)); - VERIFY(!(t1A > t1B)); - } - - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} - - - - -/////////////////////////////////////////////////////////////////////////////// -// TestSetMutation -// -// Requires a container that can hold at least 1000 items. -// -EA_DISABLE_VC_WARNING(6262) -template <typename T1, typename T2, bool bMultiset> -int TestSetMutation() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { - eastl::scoped_ptr<T1> pt1A(new T1); // We use a pointers instead of concrete object because it's size may be huge. - eastl::scoped_ptr<T2> pt2A(new T2); - T1& t1A = *pt1A; - T2& t2A = *pt2A; - int i, iEnd, p; - - // Set up an array of values to randomize / permute. - eastl::vector<typename T1::value_type> valueArrayInsert; - - if(gEASTL_TestLevel >= kEASTL_TestLevelLow) - { - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - - valueArrayInsert.clear(); - - for(i = 0; i < 1000; i++) - { - valueArrayInsert.push_back(typename T1::value_type(i)); - - // Occasionally attempt to duplicate an element, both for set and multiset. - if(((i + 1) < 1000) && (rng.RandLimit(4) == 0)) - { - valueArrayInsert.push_back(typename T1::value_type(i)); - i++; - } - } - - for(p = 0; p < gEASTL_TestLevel * 100; p++) // For each permutation... - { - eastl::random_shuffle(valueArrayInsert.begin(), valueArrayInsert.end(), rng); - - // insert - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::value_type& k = valueArrayInsert[i]; - - t1A.insert(typename T1::value_type(k)); // We expect that both arguments are the same. - t2A.insert(typename T2::value_type(k)); - - VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Set insert", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - } - - - // reverse iteration - typename T1::reverse_iterator r1 = t1A.rbegin(); - typename T2::reverse_iterator r2 = t2A.rbegin(); - - while(r1 != t1A.rend()) - { - typename T1::value_type k1 = *r1; - typename T2::value_type k2 = *r2; - VERIFY(k1 == k2); - } - - - // erase - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::value_type& k = valueArrayInsert[i]; - - typename T1::size_type n1 = t1A.erase(k); - typename T2::size_type n2 = t2A.erase(k); - - VERIFY(n1 == n2); - VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Set erase", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - } - - VERIFY((TestObject::sTOCount == 0) || (TestObject::sTOCount == (int64_t)valueArrayInsert.size())); // This test will only have meaning when T1 contains TestObject. - } - } - - - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - // Possibly do extended testing. - if(gEASTL_TestLevel > 6) - { - valueArrayInsert.clear(); - - for(i = 0; i < 9; i++) // Much more than this count would take too long to test all permutations. - valueArrayInsert.push_back(typename T1::value_type(i)); - - // Insert these values into the set in every existing permutation. - for(p = 0; std::next_permutation(valueArrayInsert.begin(), valueArrayInsert.end()); p++) // For each permutation... - { - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::value_type& k = valueArrayInsert[i]; - - t1A.insert(typename T1::value_type(k)); // We expect that both arguments are the same. - t2A.insert(typename T2::value_type(k)); - - VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Set insert", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - } - - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::value_type& k = valueArrayInsert[i]; - - t1A.erase(k); - t2A.erase(k); - - VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Set erase", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - } - - VERIFY((TestObject::sTOCount == 0) || (TestObject::sTOCount == (int64_t)valueArrayInsert.size())); // This test will only have meaning when T1 contains TestObject. - } - } - } - - - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - - { // Other insert and erase operations - - eastl::scoped_ptr<T1> pt1A(new T1); // We use a pointers instead of concrete object because it's size may be huge. - eastl::scoped_ptr<T2> pt2A(new T2); - T1& t1A = *pt1A; - T2& t2A = *pt2A; - int i; - - // Set up an array of values to randomize / permute. - eastl::vector<typename T1::value_type> valueArrayInsert1; - eastl::vector<typename T2::value_type> valueArrayInsert2; - - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - - for(i = 0; i < 100; i++) - { - valueArrayInsert1.push_back(typename T1::value_type(i)); - valueArrayInsert2.push_back(typename T2::value_type(i)); - - if(rng.RandLimit(3) == 0) - { - valueArrayInsert1.push_back(typename T1::value_type(i)); - valueArrayInsert2.push_back(typename T2::value_type(i)); - } - } - - - // insert(InputIterator first, InputIterator last) - t1A.insert(valueArrayInsert1.begin(), valueArrayInsert1.end()); - t2A.insert(valueArrayInsert2.begin(), valueArrayInsert2.end()); - VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Set insert", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - // iterator insert(iterator position, const value_type& value); - // - // If bMultiset == true, then the insertions below should fail due to the - // item being present. But they should return the correct iterator value. - typename T1::iterator it1 = t1A.insert(t1A.find(typename T1::value_type(2)), typename T1::value_type(1)); - typename T2::iterator it2 = t2A.insert(t2A.find(typename T2::value_type(2)), typename T2::value_type(1)); - VERIFY(t1A.validate()); - VERIFY(*it1 == typename T1::value_type(1)); - VERIFY(*it2 == typename T2::value_type(1)); - nErrorCount += CompareContainers(t1A, t2A, "Set insert", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - it1 = t1A.insert(t1A.end(), typename T1::value_type(5)); - it2 = t2A.insert(t2A.end(), typename T2::value_type(5)); - VERIFY(t1A.validate()); - VERIFY(*it1 == typename T1::value_type(5)); - VERIFY(*it2 == typename T2::value_type(5)); - nErrorCount += CompareContainers(t1A, t2A, "Set insert", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - // Now we remove these items so that the insertions above can succeed. - t1A.erase(t1A.find(typename T1::value_type(1))); - t2A.erase(t2A.find(typename T2::value_type(1))); - it1 = t1A.insert(t1A.find(typename T1::value_type(2)), typename T1::value_type(1)); - it2 = t2A.insert(t2A.find(typename T2::value_type(2)), typename T2::value_type(1)); - VERIFY(t1A.validate()); - VERIFY(*it1 == typename T1::value_type(1)); - VERIFY(*it2 == typename T2::value_type(1)); - nErrorCount += CompareContainers(t1A, t2A, "Set insert", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - t1A.erase(t1A.find(typename T1::value_type(5))); - t2A.erase(t2A.find(typename T2::value_type(5))); - it1 = t1A.insert(t1A.end(), typename T1::value_type(5)); - it2 = t2A.insert(t2A.end(), typename T2::value_type(5)); - VERIFY(t1A.validate()); - VERIFY(*it1 == typename T1::value_type(5)); - VERIFY(*it2 == typename T2::value_type(5)); - nErrorCount += CompareContainers(t1A, t2A, "Set insert", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - // iterator erase(iterator first, iterator last); - typename T1::iterator it11 = t1A.find(typename T1::value_type(17)); - typename T1::iterator it12 = t1A.find(typename T2::value_type(37)); - t1A.erase(it11, it12); - - typename T2::iterator it21 = t2A.find(typename T1::value_type(17)); - typename T2::iterator it22 = t2A.find(typename T2::value_type(37)); - t2A.erase(it21, it22); - - VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Set erase(first, last)", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - // iterator erase(iterator position); - t1A.erase(t1A.find(typename T1::value_type(60))); - t2A.erase(t2A.find(typename T1::value_type(60))); - VERIFY(t1A.validate()); - nErrorCount += CompareContainers(t1A, t2A, "Set erase(first, last)", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - - - // Disabled because this function isn't exposed outside the rbtree yet. - // void erase(const value_type* first, const value_type* last); - //typename T1::value_type keyArray1[3] = { typename T1::value_type(70), typename T1::value_type(71), typename T1::value_type(72) }; - //typename T2::value_type keyArray2[3] = { typename T2::value_type(70), typename T2::value_type(71), typename T2::value_type(72) }; - //t1A.erase(keyArray1 + 0, keyArray1 + 3); - //t2A.erase(keyArray2 + 0, keyArray2 + 3); - //VERIFY(t1A.validate()); - //nErrorCount += CompareContainers(t1A, t2A, "Set erase(first, last)", eastl::use_self<typename T1::value_type>(), eastl::use_self<typename T2::value_type>()); - } - - { - // set(std::initializer_list<value_type> ilist, const Compare& compare = Compare(), const allocator_type& allocator = EASTL_MAP_DEFAULT_ALLOCATOR); - // this_type& operator=(std::initializer_list<T> ilist); - // void insert(std::initializer_list<value_type> ilist); - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - T1 mySet = { typename T1::value_type(10), typename T1::value_type(11) }; - EATEST_VERIFY(mySet.size() == 2); - typename T1::iterator it = mySet.begin(); - EATEST_VERIFY(*it == typename T1::value_type(10)); - it = mySet.rbegin().base(); - EATEST_VERIFY(*--it == typename T1::value_type(11)); - - mySet = {typename T1::value_type(20), typename T1::value_type(21) }; - EATEST_VERIFY(mySet.size() == 2); - EATEST_VERIFY(*mySet.begin() == typename T1::value_type(20)); - it = mySet.rbegin().base(); - EATEST_VERIFY(*--it == typename T1::value_type(21)); - - mySet.insert({ typename T1::value_type(40), typename T1::value_type(41) }); - EATEST_VERIFY(mySet.size() == 4); - it = mySet.rbegin().base(); - EATEST_VERIFY(*--it == typename T1::value_type(41)); - #endif - } - - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} -EA_RESTORE_VC_WARNING() - - -#endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - - - -template <typename T1> -int TestSetSpecific(T1& /*t1A*/, eastl::false_type) // false_type means this is a map and not a multimap. -{ - return 0; -} - - -template <typename T1> -int TestSetSpecific(T1& t1A, eastl::true_type) // true_type means this is a multimap and not a map. -{ - int nErrorCount = 0; - - // equal_range_small (multiset only) - eastl::pair<typename T1::iterator, typename T1::iterator> er = t1A.equal_range_small(typename T1::value_type(499)); - VERIFY(*er.first == typename T1::value_type(499)); - VERIFY(*er.second == typename T1::value_type(501)); - - er = t1A.equal_range_small(typename T1::value_type(-1)); - VERIFY(er.first == er.second); - VERIFY(er.first == t1A.begin()); - - return nErrorCount; -} - - -// Just for the purposes of the map::find_as test below, we declare the following. -// The map::find_as function searches a container of X for a type Y, where the user -// defines the equality of X to Y. The purpose of TSetComparable is to be a generic type Y -// that can be used for any X. We need to make this generic because the whole TestMapSearch -// function below is templated on type T1 and so we don't know what T1 is ahead of time. - -template <typename T> -struct TSetComparable -{ - T b; - - TSetComparable() : b() { } - TSetComparable(const T& a) : b(a){ } - const TSetComparable& operator=(const T& a) { b = a; return *this; } - const TSetComparable& operator=(const TSetComparable& x) { b = x.b; return *this; } - operator const T&() const { return b; } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// TestSetSearch -// -// This function is designed to work with set, fixed_set (and not hash containers). -// Requires a container that can hold at least 1000 items. -// -template <typename T1, bool bMultimap> -int TestSetSearch() -{ - int nErrorCount = 0; - - TestObject::Reset(); - - { // Test find, lower_bound, upper_bound, etc.. - eastl::scoped_ptr<T1> pt1A(new T1); // We use a pointers instead of concrete object because it's size may be huge. - T1& t1A = *pt1A; - int i, iEnd; - typename T1::iterator it; - - // Set up an array of values to randomize / permute. - eastl::vector<typename T1::value_type> valueArrayInsert; - - for(i = 0; i < 1000; i++) - valueArrayInsert.push_back(typename T1::value_type(i)); - - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - eastl::random_shuffle(valueArrayInsert.begin(), valueArrayInsert.end(), rng); - - - // insert - for(i = 0, iEnd = (int)valueArrayInsert.size(); i < iEnd; i++) - { - typename T1::value_type k(i); - t1A.insert(typename T1::value_type(k)); - - it = t1A.find(k); - VERIFY(it != t1A.end()); - } - - - // find - for(i = 0; i < 1000; i++) - { - typename T1::value_type k(i); - it = t1A.find(k); - - VERIFY(it != t1A.end()); - VERIFY(*it == k); - } - - it = t1A.find(typename T1::value_type(-1)); - VERIFY(it == t1A.end()); - - it = t1A.find(typename T1::value_type(1001)); - VERIFY(it == t1A.end()); - - - // find_as - typedef TSetComparable<typename T1::key_type> TC; - - // Normally we use find_as to find via a different type, but we can test it here like this. - for(i = 0; i < 1000; i++) - { - TC k = typename T1::key_type(i); - it = t1A.find_as(k, eastl::less_2<typename T1::key_type, TC>()); - - VERIFY(it != t1A.end()); - VERIFY(*it == k); - } - - it = t1A.find_as(TC(typename T1::key_type(-1)), eastl::less_2<typename T1::key_type, TC>()); - VERIFY(it == t1A.end()); - - it = t1A.find_as(TC(typename T1::key_type(1001)), eastl::less_2<typename T1::key_type, TC>()); - VERIFY(it == t1A.end()); - - - // lower_bound - it = t1A.lower_bound(typename T1::value_type(0)); - VERIFY(it == t1A.begin()); - - it = t1A.lower_bound(typename T1::value_type(-1)); - VERIFY(it == t1A.begin()); - - it = t1A.lower_bound(typename T1::value_type(1001)); - VERIFY(it == t1A.end()); - - t1A.erase(typename T1::value_type(500)); - it = t1A.lower_bound(typename T1::value_type(500)); - VERIFY(*it == typename T1::value_type(501)); - - - // upper_bound - it = t1A.upper_bound(typename T1::value_type(-1)); - VERIFY(it == t1A.begin()); - - it = t1A.upper_bound(typename T1::value_type(499)); - VERIFY(*it == typename T1::value_type(501)); - - it = t1A.upper_bound(typename T1::value_type(-1)); - VERIFY(*it == typename T1::value_type(0)); - - it = t1A.upper_bound(typename T1::value_type(1000)); - VERIFY(it == t1A.end()); - - - // count - typename T1::size_type n = t1A.count(typename T1::value_type(-1)); - VERIFY(n == 0); - - n = t1A.count(typename T1::value_type(0)); - VERIFY(n == 1); - - n = t1A.count(typename T1::value_type(500)); // We removed 500 above. - VERIFY(n == 0); - - n = t1A.count(typename T1::value_type(1001)); - VERIFY(n == 0); - - - // equal_range - eastl::pair<typename T1::iterator, typename T1::iterator> er = t1A.equal_range(typename T1::value_type(200)); - VERIFY(*er.first == typename T1::value_type(200)); - - er = t1A.equal_range(typename T1::value_type(499)); - VERIFY(*er.first == typename T1::value_type(499)); - VERIFY(*er.second == typename T1::value_type(501)); - - er = t1A.equal_range(typename T1::value_type(-1)); - VERIFY(er.first == er.second); - VERIFY(er.first == t1A.begin()); - - - // Some tests need to be differently between map and multimap. - nErrorCount += TestSetSpecific(t1A, eastl::integral_constant<bool, bMultimap>()); - } - - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// TestSetCpp11 -// -// This function is designed to work with set, fixed_set, hash_set, fixed_hash_set -// -template <typename T1> -int TestSetCpp11() -{ - int nErrorCount = 0; - - // template <class... Args> - // insert_return_type emplace(Args&&... args); - // - // template <class... Args> - // iterator emplace_hint(const_iterator position, Args&&... args); - // - // insert_return_type insert(value_type&& value); - // iterator insert(const_iterator position, value_type&& value); - TestObject::Reset(); - - typedef T1 TOSet; - typename TOSet::insert_return_type toSetInsertResult; - typename TOSet::iterator toSetIterator; - - TOSet toSet; - TestObject to0(0); - TestObject to1(1); - - toSetInsertResult = toSet.emplace(to0); - EATEST_VERIFY(toSetInsertResult.second == true); - //EATEST_VERIFY((TestObject::sTOCopyCtorCount == 2) && (TestObject::sTOMoveCtorCount == 1)); // Disabled until we can guarantee its behavior and deal with how it's different between compilers of differing C++11 support. - - toSetInsertResult = toSet.emplace(eastl::move(to1)); - EATEST_VERIFY(toSetInsertResult.second == true); - - // insert_return_type t1A.emplace(value_type&& value); - TestObject to40(4); - EATEST_VERIFY(toSet.find(to40) == toSet.end()); - EATEST_VERIFY(to40.mX == 4); // It should change to 0 below during the move swap. - toSetInsertResult = toSet.emplace(eastl::move(to40)); - EATEST_VERIFY(toSetInsertResult.second == true); - EATEST_VERIFY(toSet.find(to40) != toSet.end()); - EATEST_VERIFY(to40.mX == 0); - - TestObject to41(4); - toSetInsertResult = toSet.emplace(eastl::move(to41)); - EATEST_VERIFY(toSetInsertResult.second == false); - EATEST_VERIFY(toSet.find(to41) != toSet.end()); - - // iterator t1A.emplace_hint(const_iterator position, value_type&& value); - TestObject to50(5); - toSetInsertResult = toSet.emplace(eastl::move(to50)); - EATEST_VERIFY(toSetInsertResult.second == true); - EATEST_VERIFY(toSet.find(to50) != toSet.end()); - - TestObject to51(5); - toSetIterator = toSet.emplace_hint(toSetInsertResult.first, eastl::move(to51)); - EATEST_VERIFY(*toSetIterator == TestObject(5)); - EATEST_VERIFY(toSet.find(to51) != toSet.end()); - - TestObject to6(6); - toSetIterator = toSet.emplace_hint(toSet.begin(), eastl::move(to6)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(*toSetIterator == TestObject(6)); - EATEST_VERIFY(toSet.find(to6) != toSet.end()); - - TestObject to2(2); - EATEST_VERIFY(toSet.find(to2) == toSet.end()); - toSetInsertResult = toSet.emplace(to2); - EATEST_VERIFY(toSetInsertResult.second == true); - EATEST_VERIFY(toSet.find(to2) != toSet.end()); - toSetInsertResult = toSet.emplace(to2); - EATEST_VERIFY(toSetInsertResult.second == false); - EATEST_VERIFY(toSet.find(to2) != toSet.end()); - - // iterator t1A.emplace_hint(const_iterator position, const value_type& value); - TestObject to70(7); - toSetInsertResult = toSet.emplace(to70); - EATEST_VERIFY(toSetInsertResult.second == true); - EATEST_VERIFY(toSet.find(to70) != toSet.end()); - - TestObject to71(7); - toSetIterator = toSet.emplace_hint(toSetInsertResult.first, to71); - EATEST_VERIFY(*toSetIterator == to71); - EATEST_VERIFY(toSet.find(to71) != toSet.end()); - - TestObject to8(8); - toSetIterator = toSet.emplace_hint(toSet.begin(), to8); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(*toSetIterator == to8); - EATEST_VERIFY(toSet.find(to8) != toSet.end()); - - //pair<iterator,bool> t1A.insert(value_type&& value); - TestObject to3(3); - EATEST_VERIFY(toSet.find(to3) == toSet.end()); - toSetInsertResult = toSet.insert(TestObject(to3)); - EATEST_VERIFY(toSetInsertResult.second == true); - EATEST_VERIFY(toSet.find(to3) != toSet.end()); - toSetInsertResult = toSet.insert(TestObject(to3)); - EATEST_VERIFY(toSetInsertResult.second == false); - EATEST_VERIFY(toSet.find(to3) != toSet.end()); - - - // iterator t1A.insert(const_iterator position, value_type&& value); - TestObject to90(9); - toSetInsertResult = toSet.emplace(eastl::move(to90)); - EATEST_VERIFY(toSetInsertResult.second == true); - EATEST_VERIFY(toSet.find(to90) != toSet.end()); - - TestObject to91(9); - toSetIterator = toSet.emplace_hint(toSetInsertResult.first, eastl::move(to91)); - EATEST_VERIFY(*toSetIterator == TestObject(9)); - EATEST_VERIFY(toSet.find(to91) != toSet.end()); - - TestObject to10(10); - toSetIterator = toSet.emplace_hint(toSet.begin(), eastl::move(to10)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(*toSetIterator == TestObject(10)); - EATEST_VERIFY(toSet.find(to10) != toSet.end()); - - return nErrorCount; -} - - - - - - -/////////////////////////////////////////////////////////////////////////////// -// TestMultisetCpp11 -// -// This function is designed to work with multiset, fixed_multiset, hash_multiset, fixed_hash_multiset -// -// This is similar to the TestSetCpp11 function, with some differences related -// to handling of duplicate entries. -// -template <typename T1> -int TestMultisetCpp11() -{ - int nErrorCount = 0; - - // template <class... Args> - // insert_return_type emplace(Args&&... args); - // - // template <class... Args> - // iterator emplace_hint(const_iterator position, Args&&... args); - // - // insert_return_type insert(value_type&& value); - // iterator insert(const_iterator position, value_type&& value); - TestObject::Reset(); - - typedef T1 TOSet; - typename TOSet::iterator toSetIterator; - - TOSet toSet; - TestObject to0(0); - TestObject to1(1); - - toSetIterator = toSet.emplace(to0); - EATEST_VERIFY(*toSetIterator == TestObject(0)); - //EATEST_VERIFY((TestObject::sTOCopyCtorCount == 2) && (TestObject::sTOMoveCtorCount == 1)); // Disabled until we can guarantee its behavior and deal with how it's different between compilers of differing C++11 support. - - toSetIterator = toSet.emplace(eastl::move(to1)); - EATEST_VERIFY(*toSetIterator == TestObject(1)); - - // insert_return_type t1A.emplace(value_type&& value); - TestObject to40(4); - EATEST_VERIFY(toSet.find(to40) == toSet.end()); - EATEST_VERIFY(to40.mX == 4); // It should change to 0 below during the move swap. - toSetIterator = toSet.emplace(eastl::move(to40)); - EATEST_VERIFY(*toSetIterator == TestObject(4)); - EATEST_VERIFY(toSet.find(to40) != toSet.end()); - EATEST_VERIFY(to40.mX == 0); - - TestObject to41(4); - toSetIterator = toSet.emplace(eastl::move(to41)); // multiset can insert another of these. - EATEST_VERIFY(*toSetIterator == TestObject(4)); - EATEST_VERIFY(toSet.find(to41) != toSet.end()); - - // iterator t1A.emplace_hint(const_iterator position, value_type&& value); - TestObject to50(5); - toSetIterator = toSet.emplace(eastl::move(to50)); - EATEST_VERIFY(*toSetIterator == TestObject(5)); - EATEST_VERIFY(toSet.find(to50) != toSet.end()); - - TestObject to51(5); - toSetIterator = toSet.emplace_hint(toSetIterator, eastl::move(to51)); - EATEST_VERIFY(*toSetIterator == TestObject(5)); - EATEST_VERIFY(toSet.find(to51) != toSet.end()); - - TestObject to6(6); - toSetIterator = toSet.emplace_hint(toSet.begin(), eastl::move(to6)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(*toSetIterator == TestObject(6)); - EATEST_VERIFY(toSet.find(to6) != toSet.end()); - - TestObject to2(2); - EATEST_VERIFY(toSet.find(to2) == toSet.end()); - toSetIterator = toSet.emplace(to2); - EATEST_VERIFY(*toSetIterator == TestObject(2)); - EATEST_VERIFY(toSet.find(to2) != toSet.end()); - toSetIterator = toSet.emplace(to2); - EATEST_VERIFY(*toSetIterator == TestObject(2)); - EATEST_VERIFY(toSet.find(to2) != toSet.end()); - - // iterator t1A.emplace_hint(const_iterator position, const value_type& value); - TestObject to70(7); - toSetIterator = toSet.emplace(to70); - EATEST_VERIFY(*toSetIterator == TestObject(7)); - EATEST_VERIFY(toSet.find(to70) != toSet.end()); - - TestObject to71(7); - toSetIterator = toSet.emplace_hint(toSetIterator, to71); - EATEST_VERIFY(*toSetIterator == to71); - EATEST_VERIFY(toSet.find(to71) != toSet.end()); - - TestObject to8(8); - toSetIterator = toSet.emplace_hint(toSet.begin(), to8); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(*toSetIterator == to8); - EATEST_VERIFY(toSet.find(to8) != toSet.end()); - - // insert_return_type t1A.insert(value_type&& value); - TestObject to3(3); - EATEST_VERIFY(toSet.find(to3) == toSet.end()); - toSetIterator = toSet.insert(TestObject(to3)); - EATEST_VERIFY(*toSetIterator == TestObject(3)); - EATEST_VERIFY(toSet.find(to3) != toSet.end()); - toSetIterator = toSet.insert(TestObject(to3)); - EATEST_VERIFY(*toSetIterator == TestObject(3)); - EATEST_VERIFY(toSet.find(to3) != toSet.end()); - - // iterator t1A.insert(const_iterator position, value_type&& value); - TestObject to90(9); - toSetIterator = toSet.emplace(eastl::move(to90)); - EATEST_VERIFY(*toSetIterator == TestObject(9)); - EATEST_VERIFY(toSet.find(to90) != toSet.end()); - - TestObject to91(9); - toSetIterator = toSet.emplace_hint(toSetIterator, eastl::move(to91)); - EATEST_VERIFY(*toSetIterator == TestObject(9)); - EATEST_VERIFY(toSet.find(to91) != toSet.end()); - - TestObject to10(10); - toSetIterator = toSet.emplace_hint(toSet.begin(), eastl::move(to10)); // specify a bad hint. Insertion should still work. - EATEST_VERIFY(*toSetIterator == TestObject(10)); - EATEST_VERIFY(toSet.find(to10) != toSet.end()); - - return nErrorCount; -} - - - - - - - diff --git a/test/source/TestSmartPtr.cpp b/test/source/TestSmartPtr.cpp deleted file mode 100644 index 8052392..0000000 --- a/test/source/TestSmartPtr.cpp +++ /dev/null @@ -1,2230 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include <EABase/eabase.h> -#include "EASTLTest.h" -#include "GetTypeName.h" -#include <EAStdC/EAString.h> -#include <EAStdC/EAStopwatch.h> -#include <EASTL/atomic.h> -#include <EASTL/core_allocator_adapter.h> -#include <EASTL/core_allocator.h> -#include <EASTL/intrusive_ptr.h> -#include <EASTL/linked_array.h> -#include <EASTL/linked_ptr.h> -#include <EASTL/safe_ptr.h> -#include <EASTL/scoped_array.h> -#include <EASTL/scoped_ptr.h> -#include <EASTL/shared_array.h> -#include <EASTL/shared_ptr.h> -#include <EASTL/unique_ptr.h> -#include <EASTL/weak_ptr.h> -#include <eathread/eathread_thread.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#include <stdio.h> -#include <string.h> -#ifdef EA_PLATFORM_WINDOWS - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - #include <Windows.h> -#elif defined(EA_PLATFORM_ANDROID) - #include <android/log.h> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -EA_DISABLE_VC_WARNING(4702 4800) // 4702: unreachable code - // 4800: forcing value to bool 'true' or 'false' - - - -namespace SmartPtrTest -{ - /// CustomDeleter - /// - /// Used for testing unique_ptr deleter overrides. Otherwise acts the same as the default deleter. - /// - struct CustomDeleter - { - template <typename T> - void operator()(const T* p) const // We use a const argument type in order to be most flexible with what types we accept. - { delete const_cast<T*>(p); } - - CustomDeleter() {} - CustomDeleter(const CustomDeleter&) {} - CustomDeleter(CustomDeleter&&) {} - CustomDeleter& operator=(const CustomDeleter&) { return *this; } - CustomDeleter& operator=(CustomDeleter&&) { return *this; } - }; - - - struct CustomArrayDeleter - { - template <typename T> - void operator()(const T* p) const // We use a const argument type in order to be most flexible with what types we accept. - { delete[] const_cast<T*>(p); } - - CustomArrayDeleter() {} - CustomArrayDeleter(const CustomArrayDeleter&) {} - CustomArrayDeleter(CustomArrayDeleter&&) {} - CustomArrayDeleter& operator=(const CustomArrayDeleter&) { return *this; } - CustomArrayDeleter& operator=(CustomArrayDeleter&&) { return *this; } - }; - - - /// A - /// - /// This is used for various tests. - /// - struct A - { - char mc; - static int mCount; - - A(char c = 0) - : mc(c) { ++mCount; } - - A(const A& x) - : mc(x.mc) { ++mCount; } - - A& operator=(const A& x) - { mc = x.mc; return *this; } - - virtual ~A() // Virtual because we subclass A below. - { --mCount; } - }; - - - int A::mCount = 0; - - - /// B - /// - struct B : public A - { - }; - - - - /// RefCountTest - /// - /// This is used for tests involving intrusive_ptr. - /// - struct RefCountTest - { - int mRefCount; - static int mCount; - - RefCountTest() - : mRefCount(0) { ++mCount; } - - RefCountTest(const RefCountTest&) - : mRefCount(0) { ++mCount; } - - RefCountTest& operator=(const RefCountTest&) - { return *this; } - - virtual ~RefCountTest() - { --mCount; } - - virtual int AddRef() - { return (int)((mRefCount++) + 1); } - - virtual int Release() - { - int rc = (int)((mRefCount--) - 1); - if(rc) - return rc; - mRefCount = 1; - delete this; - return 0; - } - }; - - int RefCountTest::mCount = 0; - - - - /// Test - /// - /// This is used for tests involving intrusive_ptr. - /// - struct Test : public RefCountTest - { - bool* mpBool; - - Test(bool* pBool) - : mpBool(pBool) { *pBool = true; } - - Test(const Test& x): - RefCountTest(x), mpBool(x.mpBool) { } - - Test& operator=(const Test& x) - { mpBool = x.mpBool; return *this; } - - ~Test() - { *mpBool = false; } - }; - - - - /// IntrusiveParent / IntrusiveChild - /// - /// This is used for tests involving intrusive_ptr. - /// - struct IntrusiveParent : public RefCountTest - { - }; - - struct IntrusiveChild : public IntrusiveParent - { - }; - - - /// intrusive_ptr_add_ref / intrusive_ptr_release - /// - /// This is used for tests involving intrusive_ptr. - /// - struct IntrusiveCustom : public RefCountTest - { - static int mAddRefCallCount; - static int mReleaseCallCount; - - virtual int AddRef() - { - ++mAddRefCallCount; - return RefCountTest::AddRef(); - } - - virtual int Release() - { - ++mReleaseCallCount; - return RefCountTest::Release(); - } - }; - - int IntrusiveCustom::mAddRefCallCount = 0; - int IntrusiveCustom::mReleaseCallCount = 0; - - void intrusive_ptr_add_ref(IntrusiveCustom* p) - { - p->AddRef(); - } - - void intrusive_ptr_release(IntrusiveCustom* p) - { - p->Release(); - } - - - /// ParentClass / ChildClass / GrandChildClass - /// - /// This is used for tests involving shared_ptr. - /// - struct ParentClass - { - virtual ~ParentClass() { } - virtual void DoNothingParentClass() { } - }; - - struct ChildClass : public ParentClass - { - virtual void DoNothingChildClass() { } - }; - - struct GrandChildClass : public ChildClass - { - virtual void DoNothingGrandChildClass() { } - }; - - - - /// NamedClass - /// - struct NamedClass - { - const char* mpName; - const char* mpName2; - static int mnCount; - - NamedClass(const char* pName = NULL) - : mpName(pName), mpName2(NULL) { ++mnCount; } - - NamedClass(const char* pName, const char* pName2) - : mpName(pName), mpName2(pName2) { ++mnCount; } - - NamedClass(const NamedClass& x) - : mpName(x.mpName), mpName2(x.mpName2) { ++mnCount; } - - NamedClass& operator=(const NamedClass& x) - { mpName = x.mpName; mpName2 = x.mpName2; return *this; } - - ~NamedClass() - { --mnCount; } - }; - - int NamedClass::mnCount = 0; - - - - /// Y - /// - /// This is used for tests involving shared_ptr and enabled_shared_from_this. - /// - struct Y : public eastl::enable_shared_from_this<Y> - { - static int mnCount; - - Y() { ++mnCount; } - Y(const Y&) { ++mnCount; } - Y& operator=(const Y&) { return *this; } - ~Y() { --mnCount; } - - eastl::shared_ptr<Y> f() - { return shared_from_this(); } - }; - - int Y::mnCount = 0; - - - - /// ACLS / BCLS - /// - /// This is used for tests involving shared_ptr. - /// - class ACLS : public eastl::enable_shared_from_this<ACLS> - { - public: - static int mnCount; - int a; - - ACLS(int _a_ = 0) : a(_a_) { ++mnCount; } - ACLS(const ACLS& x) : a(x.a) { ++mnCount; } - ACLS& operator=(const ACLS& x) { a = x.a; return *this; } - ~ACLS() { --mnCount; } - }; - - int ACLS::mnCount = 0; - - - class BCLS : public ACLS - { - public: - static int mnCount; - int b; - - BCLS(int _b_ = 0) : b(_b_) { ++mnCount; } - BCLS(const BCLS& x) : ACLS(x), b(x.b) { ++mnCount; } - BCLS& operator=(const BCLS& x) { b = x.b; ACLS::operator=(x); return *this; } - ~BCLS() { --mnCount; } - }; - - int BCLS::mnCount = 0; - - - - /// A1 / B1 - /// - /// This is used for tests involving shared_ptr. - /// - struct A1 - { - static int mnCount; - int a; - - A1(int _a_ = 0) : a(_a_) { ++mnCount; } - A1(const A1& x) : a(x.a) { ++mnCount; } - A1& operator=(const A1& x) { a = x.a; return *this; } - ~A1() { --mnCount; } - }; - - int A1::mnCount = 0; - - - - struct B1 : public A1 - { - static int mnCount; - int b; - - B1(int _b_ = 0) : b(_b_) { ++mnCount; } - B1(const B1& x) : A1(x), b(x.b) { ++mnCount; } - B1& operator=(const B1& x) { b = x.b; A1::operator=(x); return *this; } - ~B1() { --mnCount; } - }; - - int B1::mnCount = 0; - - - - class MockObject - { - public: - MockObject(bool* pAlloc) - : mpAlloc(pAlloc){ *mpAlloc = true; } - - ~MockObject() - { *mpAlloc = false; } - - bool IsAllocated() const - { return *mpAlloc; } - - bool* GetAllocPtr() const - { return mpAlloc; } - - private: - bool* mpAlloc; - }; - - class DerivedMockObject : public MockObject - { - public: - DerivedMockObject(bool* pAlloc) - : MockObject(pAlloc) {} - }; - - - struct foo : public eastl::enable_shared_from_this<foo> - { - foo() : mX(0){} - int mX; - }; - - struct CheckUPtrEmptyInDestructor - { - ~CheckUPtrEmptyInDestructor() - { - if(mpUPtr) - mCheckUPtrEmpty = (*mpUPtr == nullptr); - } - - eastl::unique_ptr<CheckUPtrEmptyInDestructor>* mpUPtr{}; - static bool mCheckUPtrEmpty; - }; - - bool CheckUPtrEmptyInDestructor::mCheckUPtrEmpty = false; - - struct CheckUPtrArrayEmptyInDestructor - { - ~CheckUPtrArrayEmptyInDestructor() - { - if(mpUPtr) - mCheckUPtrEmpty = (*mpUPtr == nullptr); - } - - eastl::unique_ptr<CheckUPtrArrayEmptyInDestructor[]>* mpUPtr{}; - static bool mCheckUPtrEmpty; - }; - - bool CheckUPtrArrayEmptyInDestructor::mCheckUPtrEmpty = false; -} // namespace SmartPtrTest - - - - -static int Test_unique_ptr() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount(0); - - { - EATEST_VERIFY(A::mCount == 0); - - // explicit unique_ptr(pointer pValue) noexcept - unique_ptr<int> pT1(new int(5)); - EATEST_VERIFY(*pT1 == 5); - - // (reference) operator*() const - *pT1 = 3; - EATEST_VERIFY(*pT1 == 3); - - // explicit unique_ptr(pointer pValue) noexcept - unique_ptr<A> pT2(new A(1)); - EATEST_VERIFY(pT2->mc == 1); - EATEST_VERIFY(A::mCount == 1); - - // Pointers of derived types are allowed (unlike array unique_ptr) - unique_ptr<A> pT1B(new B); - EATEST_VERIFY(pT1B.get() != NULL); - EATEST_VERIFY(A::mCount == 2); - - A* pA = pT1B.release(); // release simply forgets the owned pointer. - EATEST_VERIFY(pT1B.get() == NULL); - EATEST_VERIFY(A::mCount == 2); - - delete pA; - EATEST_VERIFY(A::mCount == 1); - - // pointer operator->() const noexcept - pT2->mc = 5; - EATEST_VERIFY(pT2.get()->mc == 5); - - // void reset(pointer pValue = pointer()) noexcept - pT2.reset(new A(2)); - EATEST_VERIFY(pT2->mc == 2); - EATEST_VERIFY(A::mCount == 1); - - pT2.reset(0); - EATEST_VERIFY(pT2.get() == (A*)0); - EATEST_VERIFY(A::mCount == 0); - - pT2.reset(new A(3)); - EATEST_VERIFY(pT2->mc == 3); - EATEST_VERIFY(A::mCount == 1); - - unique_ptr<A> pT3(new A(4)); - EATEST_VERIFY(pT3->mc == 4); - EATEST_VERIFY(A::mCount == 2); - - // void swap(this_type& scopedPtr) noexcept - pT2.swap(pT3); - EATEST_VERIFY(pT2->mc == 4); - EATEST_VERIFY(pT3->mc == 3); - EATEST_VERIFY(A::mCount == 2); - - // void swap(unique_ptr<T, D>& scopedPtr1, unique_ptr<T, D>& scopedPtr2) noexcept - swap(pT2, pT3); - EATEST_VERIFY(pT2->mc == 3); - EATEST_VERIFY(pT3->mc == 4); - EATEST_VERIFY((pT2 < pT3) == (pT2.get() < pT3.get())); - EATEST_VERIFY(A::mCount == 2); - - // pointer release() noexcept - unique_ptr<A> pRelease(new A); - EATEST_VERIFY(A::mCount == 3); - pA = pRelease.release(); - delete pA; - EATEST_VERIFY(A::mCount == 2); - - // constexpr unique_ptr() noexcept - unique_ptr<A> pT4; - EATEST_VERIFY(pT4.get() == (A*)0); - if(pT4) - EATEST_VERIFY(pT4.get()); // Will fail - if(!(!pT4)) - EATEST_VERIFY(pT4.get()); // Will fail - - pT4.reset(new A(0)); - if(!pT4) - EATEST_VERIFY(!pT4.get()); // Will fail - - EATEST_VERIFY(A::mCount == 3); - - // unique_ptr(nullptr_t) noexcept - unique_ptr<A> pT5(nullptr); - EATEST_VERIFY(pT5.get() == (A*)0); - - // unique_ptr(pointer pValue, deleter) noexcept - CustomDeleter customADeleter; - unique_ptr<A, CustomDeleter> pT6(new A(17), customADeleter); - EATEST_VERIFY(pT6->mc == 17); - - // unique_ptr(pointer pValue, typename eastl::remove_reference<Deleter>::type&& deleter) noexcept - unique_ptr<A, CustomDeleter> pT7(new A(18), CustomDeleter()); - EATEST_VERIFY(pT7->mc == 18); - - // unique_ptr(this_type&& x) noexcept - unique_ptr<A, CustomDeleter> pT8(eastl::move(pT7)); - EATEST_VERIFY(pT8->mc == 18); - - // unique_ptr(unique_ptr<U, E>&& u, ...) - unique_ptr<A, default_delete<A> > pT9(eastl::move(pT2)); - - // this_type& operator=(this_type&& u) noexcept - // operator=(unique_ptr<U, E>&& u) noexcept - //unique_ptr<void, CustomDeleter> pTVoid; - //unique_ptr<int, CustomDeleter> pTInt(new int(1)); - //pTVoid.operator=<int, CustomDeleter>(eastl::move(pTInt)); // This doesn't work because CustomDeleter doesn't know how to delete void*. Need to rework this test. - - // this_type& operator=(nullptr_t) noexcept - pT6 = nullptr; - EATEST_VERIFY(pT6.get() == (A*)0); - - // user reported regression - // ensure a unique_ptr containing nullptr doesn't call the deleter when its destroyed. - { - static bool sLocalDeleterCalled; - sLocalDeleterCalled = false; - - struct LocalDeleter - { - void operator()(int* p) const - { - sLocalDeleterCalled = true; - delete p; - } - }; - - using local_unique_ptr = eastl::unique_ptr<int, LocalDeleter>; - - local_unique_ptr pEmpty{nullptr}; - - pEmpty = local_unique_ptr{new int(42), LocalDeleter()}; - - EATEST_VERIFY(sLocalDeleterCalled == false); - } - } - - { - // Test that unique_ptr internal pointer is reset before calling the destructor - CheckUPtrEmptyInDestructor::mCheckUPtrEmpty = false; - - unique_ptr<CheckUPtrEmptyInDestructor> uptr(new CheckUPtrEmptyInDestructor); - uptr->mpUPtr = &uptr; - uptr.reset(); - EATEST_VERIFY(CheckUPtrEmptyInDestructor::mCheckUPtrEmpty); - } - - { - // Test that unique_ptr<[]> internal pointer is reset before calling the destructor - CheckUPtrArrayEmptyInDestructor::mCheckUPtrEmpty = false; - - unique_ptr<CheckUPtrArrayEmptyInDestructor[]> uptr(new CheckUPtrArrayEmptyInDestructor[1]); - uptr[0].mpUPtr = &uptr; - uptr.reset(); - EATEST_VERIFY(CheckUPtrArrayEmptyInDestructor::mCheckUPtrEmpty); - } - - { - #if EASTL_CORE_ALLOCATOR_ENABLED - // Test EA::Allocator::EASTLICoreDeleter usage within eastl::shared_ptr. - // http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr - - // Consider the following for standards compliance. - // eastl::shared_ptr<A, EASTLCoreDeleterAdapter> foo(pA, EASTLCoreDeleterAdapter()); - - const int cacheAllocationCount = gEASTLTest_AllocationCount; - - using namespace EA::Allocator; - - EASTLCoreAllocatorAdapter ta; - void* pMem = ta.allocate(sizeof(A)); - - EATEST_VERIFY(pMem != nullptr); - EATEST_VERIFY(gEASTLTest_AllocationCount > cacheAllocationCount); - { - A* pA = new (pMem) A(); - eastl::shared_ptr<A> foo(pA, EASTLCoreDeleterAdapter()); // Not standards complaint code. Update EASTL implementation to provide the type of the deleter. - } - EATEST_VERIFY(gEASTLTest_AllocationCount == cacheAllocationCount); - EATEST_VERIFY(A::mCount == 0); - #endif - } - - { - // Test array specialization of unique_ptr - - EATEST_VERIFY(A::mCount == 0); - - // template <typename P> - // explicit unique_ptr(P pValue) noexcept - unique_ptr<int[]> pT1(new int[5]); - pT1[0] = 5; - EATEST_VERIFY(pT1[0] == 5); - - // Arrays of derived types are not allowed (unlike regular unique_ptr) - // unique_ptr<A[]> pT1B(new B[5]); // Disabled because it should not compile. - - // (reference) operator[]() const - pT1[1] = 1; - EATEST_VERIFY(pT1[1] == 1); - - // explicit unique_ptr(pointer pValue) noexcept - unique_ptr<A[]> pT2(new A[1]); - pT2[0].mc = 1; - EATEST_VERIFY(pT2[0].mc == 1); - EATEST_VERIFY(A::mCount == 1); - - // pointer operator->() const noexcept - pT2[0].mc = 5; - EATEST_VERIFY(pT2[0].mc == 5); - - // void reset(pointer pValue = pointer()) noexcept - pT2.reset(new A[2]); - pT2[0].mc = 2; - EATEST_VERIFY(pT2[0].mc == 2); - - pT2.reset(0); - EATEST_VERIFY(pT2.get() == (A*)0); - - pT2.reset(new A[3]); - pT2[0].mc = 3; - EATEST_VERIFY(pT2[0].mc == 3); - - unique_ptr<A[]> pT3(new A[4]); - pT3[0].mc = 4; - EATEST_VERIFY(pT3[0].mc == 4); - - // void swap(this_type& scopedPtr) noexcept - pT2.swap(pT3); - EATEST_VERIFY(pT2[0].mc == 4); - EATEST_VERIFY(pT3[0].mc == 3); - - // void swap(unique_ptr<T, D>& scopedPtr1, unique_ptr<T, D>& scopedPtr2) noexcept - swap(pT2, pT3); - EATEST_VERIFY(pT2[0].mc == 3); - EATEST_VERIFY(pT3[0].mc == 4); - EATEST_VERIFY((pT2 < pT3) == (pT2.get() < pT3.get())); - - // pointer release() noexcept - unique_ptr<A[]> pRelease(new A[1]); - A* pAArray = pRelease.release(); - delete[] pAArray; - - // constexpr unique_ptr() noexcept - unique_ptr<A[]> pT4; - EATEST_VERIFY(pT4.get() == (A*)0); - if(pT4) - EATEST_VERIFY(pT4.get()); // Will fail - if(!(!pT4)) - EATEST_VERIFY(pT4.get()); // Will fail - - pT4.reset(new A[1]); - if(!pT4) - EATEST_VERIFY(!pT4.get()); // Will fail - - EATEST_VERIFY(A::mCount == 8); // There were a number of array creations and deletions above that make this so. - - // unique_ptr(nullptr_t) noexcept - unique_ptr<A[]> pT5(nullptr); - EATEST_VERIFY(pT5.get() == (A*)0); - - // unique_ptr(pointer pValue, deleter) noexcept - CustomArrayDeleter customADeleter; - unique_ptr<A[], CustomArrayDeleter> pT6(new A[17], customADeleter); - pT6[0].mc = 17; - EATEST_VERIFY(pT6[0].mc == 17); - - // unique_ptr(pointer pValue, typename eastl::remove_reference<Deleter>::type&& deleter) noexcept - unique_ptr<A[], CustomArrayDeleter> pT7(new A[18], CustomArrayDeleter()); - pT7[0].mc = 18; - EATEST_VERIFY(pT7[0].mc == 18); - - // unique_ptr(this_type&& x) noexcept - unique_ptr<A[], CustomArrayDeleter> pT8(eastl::move(pT7)); - EATEST_VERIFY(pT8[0].mc == 18); - - // unique_ptr(unique_ptr<U, E>&& u, ...) - unique_ptr<A[], default_delete<A[]> > pT9(eastl::move(pT2)); - EATEST_VERIFY(pT9[0].mc == 3); - - // this_type& operator=(this_type&& u) noexcept - // operator=(unique_ptr<U, E>&& u) noexcept - //unique_ptr<void, CustomDeleter> pTVoid; - //unique_ptr<int, CustomDeleter> pTInt(new int(1)); - //pTVoid.operator=<int, CustomDeleter>(eastl::move(pTInt)); // This doesn't work because CustomDeleter doesn't know how to delete void*. Need to rework this test. - - // this_type& operator=(nullptr_t) noexcept - pT6 = nullptr; - EATEST_VERIFY(pT6.get() == (A*)0); - - // unique_ptr<> make_unique(Args&&... args); - unique_ptr<NamedClass> p = eastl::make_unique<NamedClass>("test", "test2"); - EATEST_VERIFY(EA::StdC::Strcmp(p->mpName, "test") == 0 && EA::StdC::Strcmp(p->mpName2, "test2") == 0); - - unique_ptr<NamedClass[]> pArray = eastl::make_unique<NamedClass[]>(4); - pArray[0].mpName = "test"; - EATEST_VERIFY(EA::StdC::Strcmp(p->mpName, "test") == 0); - - #ifdef EASTL_TEST_DISABLED_PENDING_SUPPORT - { - const size_t kAlignedStructAlignment = 512; - struct AlignedStruct {} EA_ALIGN(kAlignedStructAlignment); - - unique_ptr<AlignedStruct> pAlignedStruct = eastl::make_unique<AlignedStruct>(); - EATEST_VERIFY_F(intptr_t(pAlignedStruct.get()) % kAlignedStructAlignment == 0, "pAlignedStruct didn't have proper alignment"); - } - #endif - - //Expected to not be valid: - //unique_ptr<NamedClass[4]> p2Array4 = eastl::make_unique<NamedClass[4]>(); - //p2Array4[0].mpName = "test"; - //EATEST_VERIFY(EA::StdC::Strcmp(p2Array4[0].mpName, "test") == 0); - } - - EATEST_VERIFY(A::mCount == 0); // This check verifies that no A instances were lost, which also verifies that the [] version of the deleter was used in all cases. - - // validate unique_ptr's compressed_pair implementation is working. - { - const int ARBITRARY_SIZE = 256; - static_assert(sizeof(unique_ptr<short>) == sizeof(uintptr_t), ""); - static_assert(sizeof(unique_ptr<long>) == sizeof(uintptr_t), ""); - - // unique_ptr should be the same size as a pointer. The deleter object is empty so the - // eastl::compressed_pair implementation will remove that deleter data member from the unique_ptr. - { - auto deleter = [](void* pMem) { free(pMem); }; - unique_ptr<void, decltype(deleter)> sptr(malloc(ARBITRARY_SIZE), deleter); - static_assert(sizeof(sptr) == (sizeof(uintptr_t)), "unexpected unique_ptr size"); - } - - // unique_ptr should be larger than a pointer when the deleter functor is capturing state. This state forces - // the compressed_pair to cached the data in unique_ptr locally. - { - int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0; - auto deleter = [=](void* pMem) { auto result = (a+b+c+d+e+f); EA_UNUSED(result); free(pMem); }; - unique_ptr<void, decltype(deleter)> sptr(malloc(ARBITRARY_SIZE), deleter); - static_assert(sizeof(sptr) == ((6 * sizeof(int)) + (sizeof(uintptr_t))), "unexpected unique_ptr size"); - } - - // Simply test moving the one unique pointer to another. - // Exercising operator=(T&&) - { - { - unique_ptr<int> ptr(new int(3)); - EATEST_VERIFY(ptr.get() && *ptr == 3); - - unique_ptr<int> newPtr(new int(4)); - EATEST_VERIFY(newPtr.get() && *newPtr == 4); - - ptr = eastl::move(newPtr); // Deletes int(3) and assigns mpValue to int(4) - EATEST_VERIFY(ptr.get() && *ptr == 4); - EATEST_VERIFY(newPtr.get() == nullptr); - } - - #if EA_HAVE_CPP11_INITIALIZER_LIST - { - unique_ptr<int[]> ptr(new int[3]{ 0, 1, 2 }); - EATEST_VERIFY(ptr.get() && ptr[0] == 0 && ptr[1] == 1 && ptr[2] == 2); - - unique_ptr<int[]> newPtr(new int[3]{ 3, 4, 5 }); - EATEST_VERIFY(newPtr.get() && newPtr[0] == 3 && newPtr[1] == 4 && newPtr[2] == 5); - - ptr = eastl::move(newPtr); // Deletes int(3) and assigns mpValue to int(4) - EATEST_VERIFY(ptr.get() && ptr[0] == 3 && ptr[1] == 4 && ptr[2] == 5); - EATEST_VERIFY(newPtr.get() == nullptr); - } - #endif - - #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - unique_ptr<int> pT1(new int(5)); - unique_ptr<int> pT2(new int(10)); - unique_ptr<int> pT3(new int(0)); - - EATEST_VERIFY((pT1 <=> pT2) != 0); - EATEST_VERIFY((pT2 <=> pT1) != 0); - - EATEST_VERIFY((pT1 <=> pT2) < 0); - EATEST_VERIFY((pT1 <=> pT2) <= 0); - EATEST_VERIFY((pT2 <=> pT1) > 0); - EATEST_VERIFY((pT2 <=> pT1) >= 0); - - EATEST_VERIFY((pT3 <=> pT1) < 0); - EATEST_VERIFY((pT3 <=> pT2) < 0); - EATEST_VERIFY((pT1 <=> pT3) > 0); - EATEST_VERIFY((pT2 <=> pT3) > 0); - - unique_ptr<A> pT4(new A(5)); - unique_ptr<A> pT5(new A(10)); - - EATEST_VERIFY((pT4 <=> pT5) != 0); - EATEST_VERIFY((pT5 <=> pT4) != 0); - - EATEST_VERIFY((pT4 <=> pT5) < 0); - EATEST_VERIFY((pT4 <=> pT5) <= 0); - EATEST_VERIFY((pT5 <=> pT4) > 0); - EATEST_VERIFY((pT5 <=> pT4) >= 0); - } - #endif - - // ToDo: Test move assignment between two convertible types with an is_assignable deleter_type - //{ - // struct Base {}; - // struct Child : public Base {}; - - // typedef unique_ptr<Base, CustomDeleter> BaseSPtr; - // typedef unique_ptr<Child, CustomDeleter> ChildSPtr; - - // static_assert(!is_array<BaseSPtr::element_type>::value, "This test requires a non-array type"); - // static_assert(is_convertible<ChildSPtr::pointer, BaseSPtr::pointer>::value, "UniquePtr ptr types must be convertible for this test"); - // static_assert(is_assignable<BaseSPtr::deleter_type&, ChildSPtr::deleter_type&&>::value, "Deleter types must be assignable to one another"); - - // BaseSPtr ptr(new Base); - // EATEST_VERIFY(ptr.get()); - - // unique_ptr<Child> newPtr(new Child); - // EATEST_VERIFY(newPtr.get()); - - // ptr = eastl::move(newPtr); - // EATEST_VERIFY(ptr); - // EATEST_VERIFY(newPtr.get() == nullptr); - //} - } - } - - return nErrorCount; -} - - -static int Test_scoped_ptr() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount(0); - - { - EATEST_VERIFY(A::mCount == 0); - - scoped_ptr<int> pT1(new int(5)); - EATEST_VERIFY(*pT1 == 5); - - *pT1 = 3; - EATEST_VERIFY(*pT1 == 3); - EATEST_VERIFY(pT1.get() == get_pointer(pT1)); - - scoped_ptr<A> pT2(new A(1)); - EATEST_VERIFY(pT2->mc == 1); - EATEST_VERIFY(A::mCount == 1); - - pT2.reset(new A(2)); - EATEST_VERIFY(pT2->mc == 2); - - pT2.reset(0); - EATEST_VERIFY(pT2.get() == (A*)0); - EATEST_VERIFY(pT2.get() == get_pointer(pT2)); - - pT2.reset(new A(3)); - EATEST_VERIFY(pT2->mc == 3); - - scoped_ptr<A> pT3(new A(4)); - EATEST_VERIFY(pT3->mc == 4); - - pT2.swap(pT3); - EATEST_VERIFY(pT2->mc == 4); - EATEST_VERIFY(pT3->mc == 3); - - swap(pT2, pT3); - EATEST_VERIFY(pT2->mc == 3); - EATEST_VERIFY(pT3->mc == 4); - EATEST_VERIFY((pT2 < pT3) == (pT2.get() < pT3.get())); - - scoped_ptr<A> pT4; - EATEST_VERIFY(pT4.get() == (A*)0); - if(pT4) - EATEST_VERIFY(pT4.get()); // Will fail - if(!(!pT4)) - EATEST_VERIFY(pT4.get()); // Will fail - - pT4.reset(new A(0)); - if(!pT4) - EATEST_VERIFY(!pT4.get()); // Will fail - - EATEST_VERIFY(A::mCount == 3); - } - - { // Test the detach function. - scoped_ptr<A> ptr(new A); - A* pA = ptr.detach(); - delete pA; - } - - { - scoped_ptr<void> ptr(new int); - (void)ptr; - } - - EATEST_VERIFY(A::mCount == 0); - - return nErrorCount; -} - - - -static int Test_scoped_array() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount(0); - - { - scoped_array<int> pT1(new int[5]); - pT1[0] = 5; - EATEST_VERIFY(pT1[0] == 5); - EATEST_VERIFY(pT1.get()[0] == 5); - - scoped_array<A> pT2(new A[2]); - EATEST_VERIFY(A::mCount == 2); - EATEST_VERIFY(pT2[0].mc == 0); - EATEST_VERIFY(pT2.get()[0].mc == 0); - EATEST_VERIFY(get_pointer(pT2)[0].mc == 0); - - pT2.reset(new A[4]); - EATEST_VERIFY(A::mCount == 4); - if(!pT2) - EATEST_VERIFY(!pT2.get()); // Will fail - - pT2.reset(0); - EATEST_VERIFY(A::mCount == 0); - if(pT2) - EATEST_VERIFY(pT2.get()); // Will fail - if(!(!pT2)) - EATEST_VERIFY(pT2.get()); // Will fail - - scoped_array<A> pT3(new A[3]); - EATEST_VERIFY(A::mCount == 3); - - pT2.swap(pT3); - EATEST_VERIFY(A::mCount == 3); - - swap(pT2, pT3); - EATEST_VERIFY(A::mCount == 3); - EATEST_VERIFY((pT2 < pT3) == (pT2.get() < pT3.get())); - - EATEST_VERIFY(A::mCount == 3); - } - - { // Test the detach function. - scoped_array<A> ptr(new A[6]); - A* pArray = ptr.detach(); - delete[] pArray; - } - - { - scoped_array<void> ptr(new int[6]); - (void)ptr; - } - - EATEST_VERIFY(A::mCount == 0); - - return nErrorCount; -} - - -static int Test_shared_ptr() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount(0); - - // Name test. - #if EASTLTEST_GETTYPENAME_AVAILABLE - //eastl::string sTypeName = GetTypeName<typename eastl::unique_ptr<int>::pointer>(); - //EA::UnitTest::Report("type name of (typename shared_ptr<int>::pointer): %s", sTypeName.c_str()); - - //sTypeName = GetTypeName<typename eastl::common_type<int*, int*>::type>(); - //EA::UnitTest::Report("type name of (typename eastl::common_type<int*, int*>::type): %s", sTypeName.c_str()); - #endif - - { - shared_ptr<int> pT1; - EATEST_VERIFY(pT1.get() == NULL); - } - - { - shared_ptr<int> pT1(new int(5)); - EATEST_VERIFY(*pT1 == 5); - EATEST_VERIFY(pT1.get() == get_pointer(pT1)); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1.unique() ); - - shared_ptr<int> pT2; - EATEST_VERIFY(pT1 != pT2); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1.unique()); - - pT2 = pT1; - EATEST_VERIFY(pT1.use_count() == 2); - EATEST_VERIFY(pT2.use_count() == 2); - EATEST_VERIFY(!pT1.unique()); - EATEST_VERIFY(!(pT1 < pT2)); // They should be equal - EATEST_VERIFY(pT1 == pT2); - - *pT1 = 3; - EATEST_VERIFY(*pT1 == 3); - EATEST_VERIFY(*pT1 == 3); - EATEST_VERIFY(*pT2 == 3); - - pT2.reset((int*)NULL); - EATEST_VERIFY(pT2.unique()); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT1.unique()); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1 != pT2); - } - - { - EATEST_VERIFY(A::mCount == 0); - - shared_ptr<A> pT2(new A(0)); - EATEST_VERIFY(A::mCount == 1); - EATEST_VERIFY(pT2->mc == 0); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - - pT2.reset(new A(1)); - EATEST_VERIFY(pT2->mc == 1); - EATEST_VERIFY(A::mCount == 1); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - - shared_ptr<A> pT3(new A(2)); - EATEST_VERIFY(A::mCount == 2); - - pT2.swap(pT3); - EATEST_VERIFY(pT2->mc == 2); - EATEST_VERIFY(pT3->mc == 1); - EATEST_VERIFY(A::mCount == 2); - - swap(pT2, pT3); - EATEST_VERIFY(pT2->mc == 1); - EATEST_VERIFY(pT3->mc == 2); - EATEST_VERIFY(A::mCount == 2); - if(!pT2) - EATEST_VERIFY(!pT2.get()); // Will fail - - shared_ptr<A> pT4; - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - EATEST_VERIFY(A::mCount == 2); - if(pT4) - EATEST_VERIFY(pT4.get()); // Will fail - if(!(!pT4)) - EATEST_VERIFY(pT4.get()); // Will fail - - pT4 = pT2; - EATEST_VERIFY(pT2.use_count() == 2); - EATEST_VERIFY(pT4.use_count() == 2); - EATEST_VERIFY(!pT2.unique()); - EATEST_VERIFY(!pT4.unique()); - EATEST_VERIFY(A::mCount == 2); - EATEST_VERIFY(pT2 == pT4); - EATEST_VERIFY(pT2 != pT3); - EATEST_VERIFY(!(pT2 < pT4)); // They should be equal - - shared_ptr<A> pT5(pT4); - EATEST_VERIFY(pT4 == pT5); - EATEST_VERIFY(pT2.use_count() == 3); - EATEST_VERIFY(pT4.use_count() == 3); - EATEST_VERIFY(pT5.use_count() == 3); - EATEST_VERIFY(!pT5.unique()); - - pT4 = shared_ptr<A>((A*)NULL); - EATEST_VERIFY(pT4.unique()); - EATEST_VERIFY(pT4.use_count() == 1); - EATEST_VERIFY(pT2.use_count() == 2); - - EATEST_VERIFY(A::mCount == 2); - } - - - // Regression test reported by a user. - // typename eastl::enable_if<!eastl::is_array<U>::value && eastl::is_convertible<U*, element_type*>::value, this_type&>::type - // operator=(unique_ptr<U, Deleter> && uniquePtr) - { - { - shared_ptr<A> rT1(new A(42)); - unique_ptr<B> rT2(new B); // default ctor uses 0 - rT2->mc = 115; - - EATEST_VERIFY(rT1->mc == 42); - EATEST_VERIFY(rT2->mc == 115); - - rT1 = eastl::move(rT2); - - EATEST_VERIFY(rT1->mc == 115); - // EATEST_VERIFY(rT2->mc == 115); // state of object post-move is undefined. - } - - // test the state of the shared_ptr::operator= return - { - shared_ptr<A> rT1(new A(42)); - unique_ptr<B> rT2(new B); // default ctor uses 0 - rT2->mc = 115; - - shared_ptr<A> operatorReturn = (rT1 = eastl::move(rT2)); - - EATEST_VERIFY(operatorReturn == rT1); - - EATEST_VERIFY(operatorReturn->mc == 115); - // EATEST_VERIFY(rT1->mc == 115); // implied as both are pointing to the same address - } - } - - - { // Test member template functions. - shared_ptr<ChildClass> pCC(new GrandChildClass); - shared_ptr<ParentClass> pPC(pCC); - shared_ptr<GrandChildClass> pGCC(static_pointer_cast<GrandChildClass>(pPC)); - } - - - { // Test enable_shared_from_this - shared_ptr<Y> p(new Y); - shared_ptr<Y> q = p->f(); - - EATEST_VERIFY(p == q); - EATEST_VERIFY(!(p < q || q < p)); // p and q must share ownership - - shared_ptr<BCLS> bctrlp = shared_ptr<BCLS>(new BCLS); - } - - - { // Test static_pointer_cast, etc. - shared_ptr<GrandChildClass> pGCC(new GrandChildClass); - shared_ptr<ParentClass> pPC = static_pointer_cast<ParentClass>(pGCC); - - EATEST_VERIFY(pPC == pGCC); - - #if EASTL_RTTI_ENABLED - shared_ptr<ChildClass> pCC = dynamic_pointer_cast<ChildClass>(pPC); - EATEST_VERIFY(pCC == pGCC); - #endif - - #if !defined(__GNUC__) || (__GNUC__ >= 3) // If not using old GCC (GCC 2.x is broken)... - eastl::shared_ptr<const void> pVoidPtr = shared_ptr<ParentClass>(new ParentClass); - shared_ptr<ParentClass> ap = const_pointer_cast<ParentClass>(static_pointer_cast<const ParentClass>(pVoidPtr)); - #endif - - //typedef shared_ptr<void const> ASPtr; - //shared_ptr<void const> pVoidPtr = ASPtr(new ParentClass); - //ASPtr ap = const_pointer_cast<ParentClass>(static_pointer_cast<const ParentClass>(pVoidPtr)); - } - - - { // Test static_shared_pointer_cast, etc. - shared_ptr<GrandChildClass> pGCC(new GrandChildClass); - shared_ptr<ParentClass> pPC = static_shared_pointer_cast<ParentClass /*, EASTLAllocatorType, smart_ptr_deleter<ParentClass>*/ >(pGCC); - - EATEST_VERIFY(pPC == pGCC); - - #if EASTL_RTTI_ENABLED - shared_ptr<ChildClass> pCC = dynamic_shared_pointer_cast<ChildClass /*, EASTLAllocatorType, smart_ptr_deleter<ParentClass>*/ >(pPC); - EATEST_VERIFY(pCC == pGCC); - #endif - } - - - { // Test smart_ptr_deleter - shared_ptr<void> pVoid(new ParentClass, smart_ptr_deleter<ParentClass>()); - EATEST_VERIFY(pVoid.get() != NULL); - - pVoid = shared_ptr<ParentClass>(new ParentClass, smart_ptr_deleter<ParentClass>()); - EATEST_VERIFY(pVoid.get() != NULL); - } - - - { // Test shared_ptr lambda deleter - auto deleter = [](int*) {}; - eastl::shared_ptr<int> ptr(nullptr, deleter); - - EATEST_VERIFY(!ptr); - EATEST_VERIFY(ptr.get() == nullptr); - } - - - { // Test of shared_ptr<void const> - #if !defined(__GNUC__) || (__GNUC__ >= 3) // If not using old GCC (GCC 2.x is broken)... - shared_ptr<void const> voidPtr = shared_ptr<A1>(new A1); - shared_ptr<A1> a1Ptr = const_pointer_cast<A1>(static_pointer_cast<const A1>(voidPtr)); - #endif - } - - - { // Test of static_pointer_cast - shared_ptr<B1> bPtr = shared_ptr<B1>(new B1); - shared_ptr<A1> aPtr = static_pointer_cast<A1, B1>(bPtr); - } - - - { // Test shared_ptr<void> - { - #if !defined(__GNUC__) || (__GNUC__ >= 3) // If not using old GCC (GCC 2.x is broken)... - const char* const pName = "NamedClassTest"; - - NamedClass* const pNamedClass0 = new NamedClass(pName); - EATEST_VERIFY(pNamedClass0->mpName == pName); - - //shared_ptr<void const, EASTLAllocatorType, smart_ptr_deleter<NamedClass> > voidPtr(pNamedClass0); - shared_ptr<void const> voidPtr(pNamedClass0); - EATEST_VERIFY(voidPtr.get() == pNamedClass0); - - NamedClass* const pNamedClass1 = (NamedClass*)voidPtr.get(); - EATEST_VERIFY(pNamedClass1->mpName == pName); - #endif - } - - { - #if !defined(__GNUC__) || (__GNUC__ >= 3) // If not using old GCC (GCC 2.x is broken)... - const char* const pName = "NamedClassTest"; - - NamedClass* const pNamedClass0 = new NamedClass(pName); - EATEST_VERIFY(pNamedClass0->mpName == pName); - - shared_ptr<void const> voidPtr(pNamedClass0, smart_ptr_deleter<NamedClass>()); - EATEST_VERIFY(voidPtr.get() == pNamedClass0); - - NamedClass* const pNamedClass1 = (NamedClass*)voidPtr.get(); - EATEST_VERIFY(pNamedClass1->mpName == pName); - #endif - } - } - - - { - const char* const pName1 = "NamedClassTest1"; - const char* const pName2 = "NamedClassTest2"; - - shared_ptr<NamedClass> sp(new NamedClass(pName1)); - EATEST_VERIFY(!sp == false); - EATEST_VERIFY(sp.unique()); - EATEST_VERIFY(sp->mpName == pName1); - - shared_ptr<NamedClass> sp2 = sp; - EATEST_VERIFY(sp2.use_count() == 2); - - sp2.reset(new NamedClass(pName2)); - EATEST_VERIFY(sp2.use_count() == 1); - EATEST_VERIFY(sp.unique()); - EATEST_VERIFY(sp2->mpName == pName2); - - sp.reset(); - EATEST_VERIFY(!sp == true); - } - - { - // Exception handling tests - #if EASTL_EXCEPTIONS_ENABLED - try { - weak_ptr<A> pWeakA; // leave uninitalized - shared_ptr<A> pSharedA(pWeakA); // This should throw eastl::bad_weak_ptr - EATEST_VERIFY(false); - } - catch(eastl::bad_weak_ptr&) - { - EATEST_VERIFY(true); // This pathway should be taken. - } - catch(...) - { - EATEST_VERIFY(false); - } - - - ThrowingAllocator<true> throwingAllocator; // Throw on first attempt to allocate. - shared_ptr<A> pA0; - - try { - A::mCount = 0; - pA0 = eastl::allocate_shared<A, ThrowingAllocator<true> >(throwingAllocator, 'a'); - EATEST_VERIFY(false); - } - catch(std::bad_alloc&) - { - EATEST_VERIFY(true); // This pathway should be taken. - EATEST_VERIFY(pA0.get() == NULL); // The C++11 Standard doesn't seem to require this, but that's how we currently do it until we learn it should be otherwise. - EATEST_VERIFY(pA0.use_count() == 0); - EATEST_VERIFY(A::mCount == 0); // Verify that there were no surviving A instances since the exception. - } - catch(...) - { - EATEST_VERIFY(false); - } - - - try { - shared_ptr<A> pA1(new A('a'), default_delete<A>(), throwingAllocator); - EATEST_VERIFY(false); - } - catch(std::bad_alloc&) - { - EATEST_VERIFY(true); // This pathway should be taken. - EATEST_VERIFY(A::mCount == 0); - } - catch(...) - { - EATEST_VERIFY(false); - } - - #endif - - } - - #if EASTL_RTTI_ENABLED - { - // template <typename U, typename A, typename D> - // shared_ptr(const shared_ptr<U, A, D>& sharedPtr, dynamic_cast_tag); - // To do. - - // template <typename U, typename A, typename D, typename UDeleter> - // shared_ptr(const shared_ptr<U, A, D>& sharedPtr, dynamic_cast_tag, const UDeleter&); - // To do. - } - #endif - - EATEST_VERIFY(A::mCount == 0); - - return nErrorCount; -} - - - - -#if EASTL_THREAD_SUPPORT_AVAILABLE - // C++ Standard section 20.7.2.5 -- shared_ptr atomic access - // shared_ptr thread safety is about safe use of the pointer itself and not about what it points to. shared_ptr thread safety - // allows you to safely use shared_ptr from different threads, but if the object shared_ptr holds requires thread safety then - // you need to separately handle that in a thread-safe way. A good way to think about it is this: "shared_ptr is as thread-safe as a raw pointer." - // - // Some helper links: - // http://stackoverflow.com/questions/9127816/stdshared-ptr-thread-safety-explained - // http://stackoverflow.com/questions/14482830/stdshared-ptr-thread-safety - // http://cppwisdom.quora.com/shared_ptr-is-almost-thread-safe - // - - // Test the ability of Futex to report the callstack of another thread holding a futex. - struct SharedPtrTestThread : public EA::Thread::IRunnable - { - EA::Thread::ThreadParameters mThreadParams; - EA::Thread::Thread mThread; - eastl::atomic<bool> mbShouldContinue; - int mnErrorCount; - eastl::shared_ptr<TestObject>* mpSPTO; - eastl::weak_ptr<TestObject>* mpWPTO; - - SharedPtrTestThread() : mThreadParams(), mThread(), mbShouldContinue(true), mnErrorCount(0), mpSPTO(NULL), mpWPTO(NULL) {} - SharedPtrTestThread(const SharedPtrTestThread&){} - void operator=(const SharedPtrTestThread&){} - - intptr_t Run(void*) - { - int& nErrorCount = mnErrorCount; // declare nErrorCount so that EATEST_VERIFY can work, as it depends on it being declared. - - while(mbShouldContinue.load(eastl::memory_order_relaxed)) - { - EA::UnitTest::ThreadSleepRandom(1, 10); - - EATEST_VERIFY(mpSPTO->get()->mX == 99); - - eastl::shared_ptr<TestObject> temp(mpWPTO->lock()); - EATEST_VERIFY(temp->mX == 99); - - eastl::shared_ptr<TestObject> spTO2(*mpSPTO); - EATEST_VERIFY(spTO2->mX == 99); - EATEST_VERIFY(spTO2.use_count() >= 2); - - eastl::weak_ptr<TestObject> wpTO2(spTO2); - temp = mpWPTO->lock(); - EATEST_VERIFY(temp->mX == 99); - - temp = spTO2; - spTO2.reset(); - EATEST_VERIFY(mpSPTO->get()->mX == 99); - } - - return nErrorCount; - } - }; -#endif - - -static int Test_shared_ptr_thread() -{ - using namespace SmartPtrTest; - using namespace eastl; - using namespace EA::Thread; - - int nErrorCount(0); - - #if EASTL_THREAD_SUPPORT_AVAILABLE - { - SharedPtrTestThread thread[4]; - shared_ptr<TestObject> spTO(new TestObject(99)); - weak_ptr<TestObject> wpTO(spTO); - - for(size_t i = 0; i < EAArrayCount(thread); i++) - { - thread[i].mpSPTO = &spTO; - thread[i].mpWPTO = &wpTO; - thread[i].mThreadParams.mpName = "SharedPtrTestThread"; - } - - for(size_t i = 0; i < EAArrayCount(thread); i++) - thread[i].mThread.Begin(&thread[0], NULL, &thread[0].mThreadParams); - - EA::UnitTest::ThreadSleep(2000); - - for(size_t i = 0; i < EAArrayCount(thread); i++) - thread[i].mbShouldContinue.store(false, eastl::memory_order_relaxed); - - for(size_t i = 0; i < EAArrayCount(thread); i++) - { - thread[i].mThread.WaitForEnd(); - nErrorCount += thread[i].mnErrorCount; - } - } - #endif - - #if EASTL_THREAD_SUPPORT_AVAILABLE - { - // We currently do light testing of the atomic functions. It would take a bit of work to fully test - // the memory behavior of these in a rigorous way. Also, as of this writing we don't have a portable - // way to use the std::memory_order functionality. - - shared_ptr<TestObject> spTO(new TestObject(55)); - - // bool atomic_is_lock_free(const shared_ptr<T>*); - EATEST_VERIFY(!atomic_is_lock_free(&spTO)); - - // shared_ptr<T> atomic_load(const shared_ptr<T>* pSharedPtr); - // shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* pSharedPtr, ... /*std::memory_order memoryOrder*/); - shared_ptr<TestObject> spTO2 = atomic_load(&spTO); - EATEST_VERIFY(spTO->mX == 55); - EATEST_VERIFY(spTO2->mX == 55); - - // void atomic_store(shared_ptr<T>* pSharedPtrA, shared_ptr<T> sharedPtrB); - // void atomic_store_explicit(shared_ptr<T>* pSharedPtrA, shared_ptr<T> sharedPtrB, ... /*std::memory_order memoryOrder*/); - spTO2->mX = 56; - EATEST_VERIFY(spTO->mX == 56); - EATEST_VERIFY(spTO2->mX == 56); - - atomic_store(&spTO, shared_ptr<TestObject>(new TestObject(77))); - EATEST_VERIFY(spTO->mX == 77); - EATEST_VERIFY(spTO2->mX == 56); - - // shared_ptr<T> atomic_exchange(shared_ptr<T>* pSharedPtrA, shared_ptr<T> sharedPtrB); - // shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* pSharedPtrA, shared_ptr<T> sharedPtrB, ... /*std::memory_order memoryOrder*/); - spTO = atomic_exchange(&spTO2, spTO); - EATEST_VERIFY(spTO->mX == 56); - EATEST_VERIFY(spTO2->mX == 77); - - spTO = atomic_exchange_explicit(&spTO2, spTO); - EATEST_VERIFY(spTO->mX == 77); - EATEST_VERIFY(spTO2->mX == 56); - - // bool atomic_compare_exchange_strong(shared_ptr<T>* pSharedPtr, shared_ptr<T>* pSharedPtrCondition, shared_ptr<T> sharedPtrNew); - // bool atomic_compare_exchange_weak(shared_ptr<T>* pSharedPtr, shared_ptr<T>* pSharedPtrCondition, shared_ptr<T> sharedPtrNew); - // bool atomic_compare_exchange_strong_explicit(shared_ptr<T>* pSharedPtr, shared_ptr<T>* pSharedPtrCondition, shared_ptr<T> sharedPtrNew, ... /*memory_order memoryOrderSuccess, memory_order memoryOrderFailure*/); - // bool atomic_compare_exchange_weak_explicit(shared_ptr<T>* pSharedPtr, shared_ptr<T>* pSharedPtrCondition, shared_ptr<T> sharedPtrNew, ... /*memory_order memoryOrderSuccess, memory_order memoryOrderFailure*/); - shared_ptr<TestObject> spTO3 = atomic_load(&spTO2); - bool result = atomic_compare_exchange_strong(&spTO3, &spTO, make_shared<TestObject>(88)); // spTO3 != spTO, so this should do no exchange and return false. - EATEST_VERIFY(!result); - EATEST_VERIFY(spTO3->mX == 56); - EATEST_VERIFY(spTO->mX == 56); - - result = atomic_compare_exchange_strong(&spTO3, &spTO2, make_shared<TestObject>(88)); // spTO3 == spTO2, so this should succeed. - EATEST_VERIFY(result); - EATEST_VERIFY(spTO2->mX == 56); - EATEST_VERIFY(spTO3->mX == 88); - } - #endif - - EATEST_VERIFY(A::mCount == 0); - TestObject::Reset(); - - return nErrorCount; -} - - -static int Test_weak_ptr() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount(0); - - { - weak_ptr<int> pW0; - shared_ptr<int> pS0(new int(0)); - shared_ptr<int> pS1(new int(1)); - weak_ptr<int> pW1(pS1); - weak_ptr<int> pW2; - weak_ptr<int> pW3(pW2); - - EATEST_VERIFY(pS1.use_count() == 1); - EATEST_VERIFY(pW1.use_count() == 1); - EATEST_VERIFY(pW2.use_count() == 0); - EATEST_VERIFY(pW3.use_count() == 0); - EATEST_VERIFY(pW1.expired() == false); - EATEST_VERIFY(pW2.expired() == true); - EATEST_VERIFY(pW3.expired() == true); - pS1.reset(); - EATEST_VERIFY(pW1.expired() == true); - pW1 = pS0; - EATEST_VERIFY(pW1.expired() == false); - pW1.swap(pW2); - EATEST_VERIFY(pW1.expired() == true); - EATEST_VERIFY(pW2.expired() == false); - pW1 = pW2; - EATEST_VERIFY(pW1.expired() == false); - pW3 = pW1; - EATEST_VERIFY(pW3.expired() == false); - EATEST_VERIFY(pS1.use_count() == 0); - pW3.reset(); - EATEST_VERIFY(pW3.expired() == true); - pS1.reset(new int(3)); - EATEST_VERIFY(pS1.use_count() == 1); - pW3 = pS1; - EATEST_VERIFY(pS1.use_count() == 1); - EATEST_VERIFY(pS1.use_count() == pW3.use_count()); - - shared_ptr<int> pShared2(pW2.lock()); - shared_ptr<int> pShared3(pW3.lock()); - - EATEST_VERIFY(pShared2.use_count() == 2); - EATEST_VERIFY(pShared3.use_count() == 2); - swap(pW2, pW3); - EATEST_VERIFY(pW2.use_count() == 2); - EATEST_VERIFY(pW3.use_count() == 2); - pW1 = pW3; - EATEST_VERIFY(pW3.use_count() == 2); - - EATEST_VERIFY((pW2 < pW3) || (pW3 < pW2)); - - EATEST_VERIFY(pS0.use_count() == 2); - pW0 = pS0; // This tests the deletion of a weak_ptr after its associated shared_ptr has destructed. - EATEST_VERIFY(pS0.use_count() == 2); - } - - - { - weak_ptr<NamedClass> wp; - - EATEST_VERIFY(wp.use_count() == 0); - EATEST_VERIFY(wp.expired() == true); - - { - shared_ptr<NamedClass> sp(new NamedClass("NamedClass")); - wp = sp; - - EATEST_VERIFY(wp.use_count() == 1); - EATEST_VERIFY(wp.expired() == false); - } - - EATEST_VERIFY(wp.use_count() == 0); - EATEST_VERIFY(wp.expired() == true); - } - - { // shared_from_this - // This example is taken from the C++11 Standard doc. - shared_ptr<const foo> pFoo(new foo); - shared_ptr<const foo> qFoo = pFoo->shared_from_this(); - - EATEST_VERIFY(pFoo == qFoo); - EATEST_VERIFY(!(pFoo < qFoo) && !(qFoo < pFoo)); // p and q share ownership - } - - { // weak_from_this const - shared_ptr<const foo> pFoo(new foo); - weak_ptr<const foo> qFoo = pFoo->weak_from_this(); - - EATEST_VERIFY(pFoo == qFoo.lock()); - EATEST_VERIFY(!(pFoo < qFoo.lock()) && !(qFoo.lock() < pFoo)); // p and q share ownership - } - - { // weak_from_this - shared_ptr<foo> pFoo(new foo); - weak_ptr<foo> qFoo = pFoo->weak_from_this(); - - EATEST_VERIFY(pFoo == qFoo.lock()); - EATEST_VERIFY(!(pFoo < qFoo.lock()) && !(qFoo.lock() < pFoo)); // p and q share ownership - } - - return nErrorCount; -} - - -static int Test_shared_array() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount(0); - - { - shared_array<int> pT1(new int[5]); - pT1[0] = 5; - EATEST_VERIFY(pT1[0] == 5); - EATEST_VERIFY(pT1.get() == get_pointer(pT1)); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1.unique()); - - shared_array<int> pT2; - EATEST_VERIFY(pT1 != pT2); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1.unique()); - - pT2 = pT1; - EATEST_VERIFY(pT1.use_count() == 2); - EATEST_VERIFY(pT2.use_count() == 2); - EATEST_VERIFY(!pT1.unique()); - EATEST_VERIFY(!(pT1 < pT2)); // They should be equal - EATEST_VERIFY(pT1 == pT2); - - *pT1 = 3; - EATEST_VERIFY(*pT1 == 3); - EATEST_VERIFY(*pT1 == 3); - EATEST_VERIFY(*pT2 == 3); - - pT2.reset(0); - EATEST_VERIFY(pT2.unique()); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT1.unique()); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1 != pT2); - } - - { - EATEST_VERIFY(A::mCount == 0); - - shared_array<A> pT2(new A[5]); - EATEST_VERIFY(A::mCount == 5); - EATEST_VERIFY(pT2->mc == 0); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - - pT2.reset(new A[1]); - pT2[0].mc = 1; - EATEST_VERIFY(pT2->mc == 1); - EATEST_VERIFY(A::mCount == 1); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - - shared_array<A> pT3(new A[2]); - EATEST_VERIFY(A::mCount == 3); - - pT2.swap(pT3); - pT2[0].mc = 2; - EATEST_VERIFY(pT2->mc == 2); - EATEST_VERIFY(pT3->mc == 1); - EATEST_VERIFY(A::mCount == 3); - - swap(pT2, pT3); - EATEST_VERIFY(pT2->mc == 1); - EATEST_VERIFY(pT3->mc == 2); - EATEST_VERIFY(A::mCount == 3); - if(!pT2) - EATEST_VERIFY(!pT2.get()); // Will fail - - shared_array<A> pT4; - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - EATEST_VERIFY(A::mCount == 3); - if(pT4) - EATEST_VERIFY(pT4.get()); // Will fail - if(!(!pT4)) - EATEST_VERIFY(pT4.get()); // Will fail - - pT4 = pT2; - EATEST_VERIFY(pT2.use_count() == 2); - EATEST_VERIFY(pT4.use_count() == 2); - EATEST_VERIFY(!pT2.unique()); - EATEST_VERIFY(!pT4.unique()); - EATEST_VERIFY(A::mCount == 3); - EATEST_VERIFY(pT2 == pT4); - EATEST_VERIFY(pT2 != pT3); - EATEST_VERIFY(!(pT2 < pT4)); // They should be equal - - shared_array<A> pT5(pT4); - EATEST_VERIFY(pT4 == pT5); - EATEST_VERIFY(pT2.use_count() == 3); - EATEST_VERIFY(pT4.use_count() == 3); - EATEST_VERIFY(pT5.use_count() == 3); - EATEST_VERIFY(!pT5.unique()); - - pT4 = shared_array<A>(0); - EATEST_VERIFY(pT4.unique()); - EATEST_VERIFY(pT4.use_count() == 1); - EATEST_VERIFY(pT2.use_count() == 2); - - EATEST_VERIFY(A::mCount == 3); - } - - EATEST_VERIFY(A::mCount == 0); - - return nErrorCount; -} - - - -static int Test_linked_ptr() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount(0); - - { - linked_ptr<int> pT1(new int(5)); - EATEST_VERIFY(*pT1.get() == 5); - EATEST_VERIFY(pT1.get() == get_pointer(pT1)); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1.unique()); - - linked_ptr<int> pT2; - EATEST_VERIFY(pT1 != pT2); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1.unique()); - - pT2 = pT1; - EATEST_VERIFY(pT1.use_count() == 2); - EATEST_VERIFY(pT2.use_count() == 2); - EATEST_VERIFY(!pT1.unique()); - EATEST_VERIFY(!(pT1 < pT2)); // They should be equal - EATEST_VERIFY(pT1 == pT2); - - *pT1 = 3; - EATEST_VERIFY(*pT1.get() == 3); - EATEST_VERIFY(*pT1 == 3); - EATEST_VERIFY(*pT2 == 3); - - pT2.reset((int*)NULL); - EATEST_VERIFY(pT2.unique()); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT1.unique()); - EATEST_VERIFY(pT1.use_count() == 1); - EATEST_VERIFY(pT1 != pT2); - } - - { - EATEST_VERIFY(A::mCount == 0); - - linked_ptr<A> pT2(new A(0)); - EATEST_VERIFY(A::mCount == 1); - EATEST_VERIFY(pT2->mc == 0); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - - pT2.reset(new A(1)); - EATEST_VERIFY(pT2->mc == 1); - EATEST_VERIFY(A::mCount == 1); - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - - linked_ptr<A> pT3(new A(2)); - EATEST_VERIFY(A::mCount == 2); - - linked_ptr<A> pT4; - EATEST_VERIFY(pT2.use_count() == 1); - EATEST_VERIFY(pT2.unique()); - EATEST_VERIFY(A::mCount == 2); - if(pT4) - EATEST_VERIFY(pT4.get()); // Will fail - if(!(!pT4)) - EATEST_VERIFY(pT4.get()); // Will fail - - pT4 = pT2; - EATEST_VERIFY(pT2.use_count() == 2); - EATEST_VERIFY(pT4.use_count() == 2); - EATEST_VERIFY(!pT2.unique()); - EATEST_VERIFY(!pT4.unique()); - EATEST_VERIFY(A::mCount == 2); - EATEST_VERIFY(pT2 == pT4); - EATEST_VERIFY(pT2 != pT3); - EATEST_VERIFY(!(pT2 < pT4)); // They should be equal - - linked_ptr<A> pT5(pT4); - EATEST_VERIFY(pT4 == pT5); - EATEST_VERIFY(pT2.use_count() == 3); - EATEST_VERIFY(pT4.use_count() == 3); - EATEST_VERIFY(pT5.use_count() == 3); - EATEST_VERIFY(!pT5.unique()); - - pT4 = linked_ptr<A>((A*)NULL); - EATEST_VERIFY(pT4.unique()); - EATEST_VERIFY(pT4.use_count() == 1); - EATEST_VERIFY(pT2.use_count() == 2); - - EATEST_VERIFY(A::mCount == 2); - } - - { // Do some force_delete tests. - linked_ptr<A> pT2(new A(0)); - linked_ptr<A> pT3(pT2); - pT2.force_delete(); - pT3.force_delete(); - } - - EATEST_VERIFY(A::mCount == 0); - - - { // Verify that subclasses are usable. - bool bAlloc = false; - - eastl::linked_ptr<DerivedMockObject> pDMO(new DerivedMockObject(&bAlloc)); - eastl::linked_ptr<MockObject> a1(pDMO); - eastl::linked_ptr<MockObject> a2; - - a2 = pDMO; - } - - { // Test regression for a bug. - linked_ptr<A> pT2; - linked_ptr<A> pT3(pT2); // In the bug linked_ptr::mpPrev and mpNext were not initialized via this ctor. - pT3.reset(new A); // In the bug this would crash due to unintialized mpPrev/mpNext. - - linked_ptr<B> pT4; - linked_ptr<A> pT5(pT4); - pT5.reset(new A); - - linked_array<A> pT6; - linked_array<A> pT7(pT6); - pT7.reset(new A[1]); - } - - return nErrorCount; -} - - - -static int Test_linked_array() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount(0); - - { - // Tests go here. - } - - { // Do some force_delete tests. - linked_array<A> pT2(new A[2]); - linked_array<A> pT3(pT2); - pT2.force_delete(); - pT3.force_delete(); - } - - EATEST_VERIFY(A::mCount == 0); - - - return nErrorCount; -} - - - -static int Test_intrusive_ptr() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount = 0; - - { // Test ctor/dtor - intrusive_ptr<RefCountTest> ip1; - intrusive_ptr<RefCountTest> ip2(NULL, false); - intrusive_ptr<RefCountTest> ip3(NULL, true); - intrusive_ptr<RefCountTest> ip4(new RefCountTest, true); - intrusive_ptr<RefCountTest> ip5(new RefCountTest, false); - intrusive_ptr<RefCountTest> ip6(ip1); - intrusive_ptr<RefCountTest> ip7(ip4); - - EATEST_VERIFY(ip1.get() == NULL); - EATEST_VERIFY(!ip1); - - EATEST_VERIFY(ip2.get() == NULL); - EATEST_VERIFY(!ip2); - - EATEST_VERIFY(ip3.get() == NULL); - EATEST_VERIFY(!ip3); - - EATEST_VERIFY(ip4.get() != NULL); - EATEST_VERIFY(ip4.get()->mRefCount == 2); - EATEST_VERIFY(ip4); - - EATEST_VERIFY(ip5.get() != NULL); - EATEST_VERIFY(ip5.get()->mRefCount == 0); - ip5.get()->AddRef(); - EATEST_VERIFY(ip5.get()->mRefCount == 1); - EATEST_VERIFY(ip5); - - EATEST_VERIFY(ip6.get() == NULL); - EATEST_VERIFY(!ip6); - - EATEST_VERIFY(ip7.get() != NULL); - EATEST_VERIFY(ip7.get()->mRefCount == 2); - EATEST_VERIFY(ip7); - } - - { - // Test move-ctor - { - VERIFY(RefCountTest::mCount == 0); - intrusive_ptr<RefCountTest> ip1(new RefCountTest); - VERIFY(RefCountTest::mCount == 1); - VERIFY(ip1->mRefCount == 1); - { - intrusive_ptr<RefCountTest> ip2(eastl::move(ip1)); - VERIFY(ip1.get() != ip2.get()); - VERIFY(ip2->mRefCount == 1); - VERIFY(RefCountTest::mCount == 1); - } - VERIFY(ip1.get() == nullptr); - VERIFY(RefCountTest::mCount == 0); - } - - // Test move-assignment - { - VERIFY(RefCountTest::mCount == 0); - intrusive_ptr<RefCountTest> ip1(new RefCountTest); - VERIFY(RefCountTest::mCount == 1); - VERIFY(ip1->mRefCount == 1); - { - intrusive_ptr<RefCountTest> ip2; - ip2 = eastl::move(ip1); - VERIFY(ip1.get() != ip2.get()); - VERIFY(ip2->mRefCount == 1); - VERIFY(RefCountTest::mCount == 1); - } - VERIFY(ip1.get() == nullptr); - VERIFY(RefCountTest::mCount == 0); - } - } - - { // Test modifiers (assign, attach, detach, reset, swap) - RefCountTest* const p1 = new RefCountTest; - RefCountTest* const p2 = new RefCountTest; - intrusive_ptr<RefCountTest> ip1; - intrusive_ptr<RefCountTest> ip2; - - ip1 = p1; - ip2 = p2; - EATEST_VERIFY(ip1.get() == p1); - EATEST_VERIFY((*ip1).mRefCount == 1); - EATEST_VERIFY(ip1->mRefCount == 1); - ip1.detach(); - EATEST_VERIFY(ip1.get() == NULL); - ip1.attach(p1); - EATEST_VERIFY(ip1.get() == p1); - EATEST_VERIFY(ip1->mRefCount == 1); - ip1.swap(ip2); - EATEST_VERIFY(ip1.get() == p2); - EATEST_VERIFY(ip2.get() == p1); - ip1.swap(ip2); - ip1 = ip2; - EATEST_VERIFY(ip1 == p2); - ip1.reset(); - EATEST_VERIFY(ip1.get() == NULL); - EATEST_VERIFY(ip2.get() == p2); - ip2.reset(); - EATEST_VERIFY(ip2.get() == NULL); - } - - { // Test external functions - intrusive_ptr<RefCountTest> ip1; - intrusive_ptr<RefCountTest> ip2(new RefCountTest); - intrusive_ptr<RefCountTest> ip3(ip1); - intrusive_ptr<RefCountTest> ip4(ip2); - - // The VC++ code scanner crashes when it scans this code. - EATEST_VERIFY(get_pointer(ip1) == NULL); - EATEST_VERIFY(get_pointer(ip2) != NULL); - EATEST_VERIFY(get_pointer(ip3) == get_pointer(ip1)); - EATEST_VERIFY(get_pointer(ip4) == get_pointer(ip2)); - - EATEST_VERIFY(ip3 == ip1); - EATEST_VERIFY(ip4 == ip2); - EATEST_VERIFY(ip1 == ip3); - EATEST_VERIFY(ip2 == ip4); - - EATEST_VERIFY(ip1 != ip2); - EATEST_VERIFY(ip3 != ip4); - EATEST_VERIFY(ip2 != ip1); - EATEST_VERIFY(ip4 != ip3); - - EATEST_VERIFY(ip3 == ip1.get()); - EATEST_VERIFY(ip4 == ip2.get()); - EATEST_VERIFY(ip1 == ip3.get()); - EATEST_VERIFY(ip2 == ip4.get()); - - EATEST_VERIFY(ip1 != ip2.get()); - EATEST_VERIFY(ip3 != ip4.get()); - EATEST_VERIFY(ip2 != ip1.get()); - EATEST_VERIFY(ip4 != ip3.get()); - - EATEST_VERIFY(ip3.get() == ip1); - EATEST_VERIFY(ip4.get() == ip2); - EATEST_VERIFY(ip1.get() == ip3); - EATEST_VERIFY(ip2.get() == ip4); - - EATEST_VERIFY(ip1.get() != ip2); - EATEST_VERIFY(ip3.get() != ip4); - EATEST_VERIFY(ip2.get() != ip1); - EATEST_VERIFY(ip4.get() != ip3); - - EATEST_VERIFY((ip4 < ip3) || (ip3 < ip4)); - - swap(ip1, ip3); - EATEST_VERIFY(get_pointer(ip3) == get_pointer(ip1)); - - swap(ip2, ip4); - EATEST_VERIFY(get_pointer(ip2) == get_pointer(ip4)); - - swap(ip1, ip2); - EATEST_VERIFY(get_pointer(ip1) != NULL); - EATEST_VERIFY(get_pointer(ip2) == NULL); - EATEST_VERIFY(get_pointer(ip1) == get_pointer(ip4)); - EATEST_VERIFY(get_pointer(ip2) == get_pointer(ip3)); - } - - { // Misc tests. - intrusive_ptr<Test> ip; - EATEST_VERIFY(ip.get() == NULL); - - ip.reset(); - EATEST_VERIFY(ip.get() == NULL); - - intrusive_ptr<Test> ip2(NULL, false); - EATEST_VERIFY(ip.get() == NULL); - - bool boolValue = false; - Test* pTest = new Test(&boolValue); - EATEST_VERIFY(boolValue); - pTest->AddRef(); - intrusive_ptr<Test> ip3(pTest, false); - EATEST_VERIFY(ip3.get() == pTest); - ip3.reset(); - EATEST_VERIFY(!boolValue); - } - - { // Misc tests. - bool boolArray[3]; - memset(boolArray, 0, sizeof(boolArray)); - - Test* p1 = new Test(boolArray + 0); - EATEST_VERIFY(boolArray[0] && !boolArray[1] && !boolArray[2]); - intrusive_ptr<Test> arc1(p1); - EATEST_VERIFY(boolArray[0] && !boolArray[1] && !boolArray[2]); - - Test* p2 = new Test(boolArray + 1); - EATEST_VERIFY(boolArray[0] && boolArray[1] && !boolArray[2]); - arc1 = p2; - EATEST_VERIFY(!boolArray[0] && boolArray[1] && !boolArray[2]); - - Test* p3 = new Test(boolArray + 2); - EATEST_VERIFY(!boolArray[0] && boolArray[1] && boolArray[2]); - arc1 = p3; - EATEST_VERIFY(!boolArray[0] && !boolArray[1] && boolArray[2]); - arc1 = NULL; - - EATEST_VERIFY(!boolArray[0] && !boolArray[1] && !boolArray[2]); - } - - { // Test intrusive_ptr_add_ref() / intrusive_ptr_release() - IntrusiveCustom* const pIC = new IntrusiveCustom; - - { - intrusive_ptr<IntrusiveCustom> bp = intrusive_ptr<IntrusiveCustom>(pIC); - intrusive_ptr<IntrusiveCustom> ap = bp; - } - - EATEST_VERIFY((IntrusiveCustom::mAddRefCallCount > 0) && (IntrusiveCustom::mReleaseCallCount == IntrusiveCustom::mAddRefCallCount)); - } - - { // Regression - intrusive_ptr<IntrusiveChild> bp = intrusive_ptr<IntrusiveChild>(new IntrusiveChild); - intrusive_ptr<IntrusiveParent> ap = bp; - } - - return nErrorCount; -} - - -struct RandomLifetimeObject : public eastl::safe_object -{ - void DoSomething() const { } -}; - - - -static int Test_safe_ptr() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount = 0; - - { // non-const RandomLifetimeObject - RandomLifetimeObject* pObject = new RandomLifetimeObject; - eastl::safe_ptr<RandomLifetimeObject> pSafePtr(pObject); - - eastl::safe_ptr<RandomLifetimeObject> pSafePtrCopy1 = pSafePtr; - eastl::safe_ptr<RandomLifetimeObject> pSafePtrCopy2(pSafePtr); - - pSafePtr->DoSomething(); - - eastl::safe_ptr<RandomLifetimeObject>* pSafePtrCopy3 = new eastl::safe_ptr<RandomLifetimeObject>(pSafePtr); - eastl::safe_ptr<RandomLifetimeObject>* pSafePtrCopy4 = new eastl::safe_ptr<RandomLifetimeObject>(pSafePtr); - EATEST_VERIFY(pSafePtrCopy3->get() == pObject); - EATEST_VERIFY(pSafePtrCopy4->get() == pObject); - delete pSafePtrCopy3; - delete pSafePtrCopy4; - - delete pSafePtr; - - EATEST_VERIFY(pSafePtrCopy1.get() == NULL); - EATEST_VERIFY(pSafePtrCopy2.get() == NULL); - } - - { // const RandomLifetimeObject - RandomLifetimeObject* pObject = new RandomLifetimeObject; - eastl::safe_ptr<const RandomLifetimeObject> pSafePtr(pObject); - - eastl::safe_ptr<const RandomLifetimeObject> pSafePtrCopy1(pSafePtr); - eastl::safe_ptr<const RandomLifetimeObject> pSafePtrCopy2 = pSafePtr; - - pSafePtr->DoSomething(); - - eastl::safe_ptr<const RandomLifetimeObject>* pSafePtrCopy3 = new eastl::safe_ptr<const RandomLifetimeObject>(pSafePtr); - eastl::safe_ptr<const RandomLifetimeObject>* pSafePtrCopy4 = new eastl::safe_ptr<const RandomLifetimeObject>(pSafePtr); - EATEST_VERIFY(pSafePtrCopy3->get() == pObject); - EATEST_VERIFY(pSafePtrCopy4->get() == pObject); - delete pSafePtrCopy3; - delete pSafePtrCopy4; - - delete pSafePtr; - - EATEST_VERIFY(pSafePtrCopy1.get() == NULL); - EATEST_VERIFY(pSafePtrCopy2.get() == NULL); - } - - return nErrorCount; -} - - -int TestSmartPtr() -{ - using namespace SmartPtrTest; - using namespace eastl; - - int nErrorCount = 0; - - nErrorCount += Test_unique_ptr(); - nErrorCount += Test_scoped_ptr(); - nErrorCount += Test_scoped_array(); - nErrorCount += Test_shared_ptr(); - nErrorCount += Test_shared_ptr_thread(); - nErrorCount += Test_weak_ptr(); - nErrorCount += Test_shared_array(); - nErrorCount += Test_linked_ptr(); - nErrorCount += Test_linked_array(); - nErrorCount += Test_intrusive_ptr(); - nErrorCount += Test_safe_ptr(); - - EATEST_VERIFY(A::mCount == 0); - EATEST_VERIFY(RefCountTest::mCount == 0); - EATEST_VERIFY(NamedClass::mnCount == 0); - EATEST_VERIFY(Y::mnCount == 0); - EATEST_VERIFY(ACLS::mnCount == 0); - EATEST_VERIFY(BCLS::mnCount == 0); - EATEST_VERIFY(A1::mnCount == 0); - EATEST_VERIFY(B1::mnCount == 0); - - return nErrorCount; -} - -EA_RESTORE_VC_WARNING() // 4702 - - - - - - - diff --git a/test/source/TestSort.cpp b/test/source/TestSort.cpp deleted file mode 100644 index 114a73b..0000000 --- a/test/source/TestSort.cpp +++ /dev/null @@ -1,961 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include <EABase/eabase.h> - -// Some versions of GCC generate an array bounds warning in opt builds which -// doesn't say what line below it comes from and doesn't appear to be a valid -// warning. In researching this on the Internet it appears that this is a -// known problem with GCC. -#if defined(EA_DISABLE_GCC_WARNING) - EA_DISABLE_GCC_WARNING(-Warray-bounds) -#endif - -#include "EASTLTest.h" -#include <EASTL/sort.h> -#include <EASTL/bonus/sort_extra.h> -#include <EASTL/vector.h> -#include <EASTL/list.h> -#include <EASTL/deque.h> -#include <EASTL/algorithm.h> -#include <EASTL/allocator.h> -#include <EASTL/numeric.h> -#include <EASTL/random.h> -#include <EABase/eahave.h> -#include <cmath> - - -namespace eastl -{ - namespace Internal - { - typedef eastl::vector<int> IntArray; - typedef eastl::vector<IntArray> IntArrayArray; - - - // IntArrayCompare - // Used to compare IntArray objects. - struct IntArrayCompare - { - bool operator()(const IntArray& a, const IntArray& b) - { return a.front() < b.front(); } - }; - - - // SafeFloatCompare - // - // Float comparison has a problem for the case that either of the floats are a NaN. - // If you use a NaN in a sort function that uses default floating point comparison then - // you will get undefined behavior, as all NaNs compare false. This compare function - // class sorts floats such that all negative NaNs sort lower than all integers, and all - // positive NaNs sort higher than all integers. - // - // Example usage: - // eastl::sort(floatArray.begin(), floatArray.end(), SafeFloatCompare()); - // - struct SafeFloatCompare - { - union FloatInt32{ float f; int32_t i; }; - - bool operator()(float a, float b) const - { - #if defined(EA_HAVE_ISNAN) - bool aNan = (EA_HAVE_ISNAN(a) != 0); - bool bNan = (EA_HAVE_ISNAN(b) != 0); - #else - bool aNan = (a != a); // This works as long as the compiler doesn't do any tricks to optimize it away. - bool bNan = (b != b); - #endif - - if(!aNan && !bNan) - return (a < b); - - FloatInt32 fia = { a }; - FloatInt32 fib = { b }; - - if(aNan) - { - if(bNan) - return (fia.i < fib.i); // Both are NaNs, so do a binary compare. - else - return (fia.i < 0); // All negative NaNs are assumed to be less than all non-NaNs. - } - else - return (0 < fib.i); // All negative NaNs are assumed to be less than all non-NaNs. - } - }; - - - - // StatefulCompare - // Used to verify that sort<int, StatefulCompare&>() respects the - // fact that StatefulCompare is passed by reference instead of by value. - // All existing commercial STL implementations fail to do what the user - // wants and instead pass around the compare object by value, even if - // the user specifically asks to use it by reference. EASTL doesn't - // have this problem. - struct StatefulCompare - { - static int nCtorCount; - static int nDtorCount; - static int nCopyCount; - - StatefulCompare() - { nCtorCount++; } - - StatefulCompare(StatefulCompare&) - { nCopyCount++; } - - ~StatefulCompare() - { nDtorCount++; } - - StatefulCompare& operator=(const StatefulCompare&) - { nCopyCount++; return *this; } - - bool operator()(int a, int b) - { return a < b; } - - static void Reset() - { nCtorCount = 0; nDtorCount = 0; nCopyCount = 0; } - }; - - int StatefulCompare::nCtorCount = 0; - int StatefulCompare::nDtorCount = 0; - int StatefulCompare::nCopyCount = 0; - - - // TestObjectPtrCompare - // Used to compare sorted objects by pointer instead of value. - struct TestObjectPtrCompare - { - bool operator()(TestObject* a, TestObject* b) - { return a->mX < b->mX; } - }; - - - // TestObjectIndexCompare - // Used to compare sorted objects by array index instead of value. - struct TestObjectIndexCompare - { - vector<TestObject>* mpArray; - - TestObjectIndexCompare(vector<TestObject>* pArray) : mpArray(pArray) { } - TestObjectIndexCompare(const TestObjectIndexCompare& x) : mpArray(x.mpArray){ } - TestObjectIndexCompare& operator=(const TestObjectIndexCompare& x) { mpArray = x.mpArray; return *this; } - - bool operator()(eastl_size_t a, eastl_size_t b) - { return (*mpArray)[a] < (*mpArray)[b]; } - }; - - // Radix sort elements - template <typename Key> - struct RadixSortElement - { - typedef Key radix_type; - Key mKey; - uint16_t mData; - - bool operator<(const RadixSortElement<Key> &other) const - { - return mKey < other.mKey; - } - }; - - typedef RadixSortElement<uint8_t> RadixSortElement8; - typedef RadixSortElement<uint16_t> RadixSortElement16; - typedef RadixSortElement<uint32_t> RadixSortElement32; - - template <typename integer_type> - struct identity_extract_radix_key - { - typedef integer_type radix_type; - - const radix_type operator()(const integer_type& x) const - { - return x; - } - }; - - struct TestNoLessOperator - { - int i {}; - }; - } // namespace Internal - - template <> - struct less<Internal::TestNoLessOperator> - { - bool operator()(const Internal::TestNoLessOperator& lhs, const Internal::TestNoLessOperator& rhs) const noexcept - { - return lhs.i < rhs.i; - } - }; - -} // namespace eastl - -int TestSort() -{ - using namespace eastl; - using namespace Internal; - - int nErrorCount = 0; - - EASTLTest_Rand rng(EA::UnitTest::GetRandSeed()); - - { - // is_sorted - int array[] = { 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 1, 0 }; - - EATEST_VERIFY( is_sorted(array + 0, array + 0)); - EATEST_VERIFY( is_sorted(array + 2, array + 4)); - EATEST_VERIFY( is_sorted(array + 0, array + 10)); - EATEST_VERIFY(!is_sorted(array + 0, array + 14)); - EATEST_VERIFY( is_sorted(array + 11, array + 23, eastl::greater<int>())); - } - - { - // is_sorted_until - int sorted[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - int notsorted[] = { 0, 1, 2, 3, 4, 42, 6, 7, 8, 9 }; - - EATEST_VERIFY( is_sorted_until(sorted + EAArrayCount(sorted), sorted + EAArrayCount(sorted)) == sorted + EAArrayCount(sorted) ); - EATEST_VERIFY( is_sorted_until(sorted , sorted + EAArrayCount(sorted)) == sorted + EAArrayCount(sorted) ); - - EATEST_VERIFY( is_sorted_until(sorted + 0, sorted + 0) == sorted ); - EATEST_VERIFY( is_sorted_until(sorted + 2, sorted + 8) == sorted + 8 ); - - EATEST_VERIFY( is_sorted_until(notsorted + 2, notsorted + 8) == notsorted + 6 ); - - // is_sorted_until (with compare function) - EATEST_VERIFY( is_sorted_until(sorted + EAArrayCount(sorted), sorted + EAArrayCount(sorted), eastl::less<int>()) == sorted + EAArrayCount(sorted) ); - EATEST_VERIFY( is_sorted_until(notsorted + 2, notsorted + 8, eastl::less<int>()) == notsorted + 6 ); - } - - // Sort arrays of size 0 - N. Sort M random permutations of each. - { - vector<int64_t> intArray, intArraySaved; - - for(int i = 0; i < (150 + (gEASTL_TestLevel * 200)); i += (i < 5) ? 1 : 37) // array sizes of 0 to 300 - 2100, depending on test level. - { - // intArraySaved.clear(); // Do we want to do this? - - for(int n = 0; n < i; n++) - { - intArraySaved.push_back(n); - - if(rng.RandLimit(10) == 0) - { - intArraySaved.push_back(n); - - if(rng.RandLimit(5) == 0) - intArraySaved.push_back(n); - } - } - const int64_t expectedSum = eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)); - - for(int j = 0; j < 300 + (gEASTL_TestLevel * 50); j++) - { - eastl::random_shuffle(intArraySaved.begin(), intArraySaved.end(), rng); - - intArray = intArraySaved; - bubble_sort(intArray.begin(), intArray.end()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - shaker_sort(intArray.begin(), intArray.end()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - insertion_sort(intArray.begin(), intArray.end()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - selection_sort(intArray.begin(), intArray.end()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - shell_sort(intArray.begin(), intArray.end()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - comb_sort(intArray.begin(), intArray.end()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - heap_sort(intArray.begin(), intArray.end()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - merge_sort(intArray.begin(), intArray.end(), *get_default_allocator((EASTLAllocatorType*)NULL)); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - vector<int64_t> buffer(intArray.size()); - merge_sort_buffer(intArray.begin(), intArray.end(), buffer.data()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - quick_sort(intArray.begin(), intArray.end()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - - intArray = intArraySaved; - buffer.resize(intArray.size()/2); - tim_sort_buffer(intArray.begin(), intArray.end(), buffer.data()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - EATEST_VERIFY(eastl::accumulate(begin(intArraySaved), end(intArraySaved), int64_t(0)) == expectedSum); - } - } - } - - // Test tim sort with a specific array size and seed that caused a crash - { - vector<int64_t> intArray; - int i = 1000000; - { - EASTLTest_Rand testRng(232526); - - for (int n = 0; n < i; n++) - { - intArray.push_back(testRng.Rand()); - } - vector<int64_t> buffer(intArray.size() / 2); - tim_sort_buffer(intArray.begin(), intArray.end(), buffer.data()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - } - } - - // Test insertion_sort() does not invalidate a BidirectionalIterator by doing --BidirectionalIterator.begin() - { - // Test Passes if the Test doesn't crash - eastl::deque<int> deque; - deque.push_back(1); - - insertion_sort(deque.begin(), deque.end()); - - insertion_sort(deque.begin(), deque.end(), eastl::less<int>{}); - } - - - // TestObject sorting - TestObject::Reset(); - { - vector<TestObject> toArray, toArraySaved; - - for(int i = 0; i < (150 + (gEASTL_TestLevel * 200)); i += (i < 5) ? 1 : 37) // array sizes of 0 to 300 - 2100, depending on test level. - { - for(int n = 0; n < i; n++) - { - toArraySaved.push_back(TestObject(n)); - - if(rng.RandLimit(10) == 0) - { - toArraySaved.push_back(TestObject(n)); - - if(rng.RandLimit(5) == 0) - toArraySaved.push_back(TestObject(n)); - } - } - - for(int j = 0; j < 300 + (gEASTL_TestLevel * 50); j++) - { - eastl::random_shuffle(toArraySaved.begin(), toArraySaved.end(), rng); - - toArray = toArraySaved; - bubble_sort(toArray.begin(), toArray.end()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - toArray = toArraySaved; - shaker_sort(toArray.begin(), toArray.end()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - toArray = toArraySaved; - insertion_sort(toArray.begin(), toArray.end()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - toArray = toArraySaved; - selection_sort(toArray.begin(), toArray.end()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - toArray = toArraySaved; - shell_sort(toArray.begin(), toArray.end()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - toArray = toArraySaved; - comb_sort(toArray.begin(), toArray.end()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - toArray = toArraySaved; - heap_sort(toArray.begin(), toArray.end()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - // Not ready yet: - toArray = toArraySaved; - merge_sort(toArray.begin(), toArray.end(), *get_default_allocator((EASTLAllocatorType*)NULL)); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - toArray = toArraySaved; - quick_sort(toArray.begin(), toArray.end()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - - toArray = toArraySaved; - vector<TestObject> buffer(toArray.size()/2); - tim_sort_buffer(toArray.begin(), toArray.end(), buffer.data()); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end())); - } - } - } - - // Test that stable sorting algorithms are actually stable - { - struct StableSortTestObj - { - StableSortTestObj() - { - } - - StableSortTestObj(int value) - :value(value) - ,initialPositionIndex(0) - { - } - - int value; - size_t initialPositionIndex; - }; - - // During the test this comparison is used to sort elements based on value. - struct StableSortCompare - { - bool operator()(const StableSortTestObj& a, const StableSortTestObj& b) - { - return a.value < b.value; - } - }; - - // During the test this comparison is used to verify the sort was a stable sort. i.e. if values are the same then - // their relative position should be maintained. - struct StableSortCompareForStability - { - bool operator()(const StableSortTestObj& a, const StableSortTestObj& b) - { - if (a.value != b.value) - { - return a.value < b.value; - } - else - { - return a.initialPositionIndex < b.initialPositionIndex; - } - } - }; - - vector<StableSortTestObj> toArray, toArraySaved; - StableSortCompare compare; - StableSortCompareForStability compareForStability; - - for (int i = 0; i < (150 + (gEASTL_TestLevel * 200)); i += (i < 5) ? 1 : 37) // array sizes of 0 to 300 - 2100, depending on test level. - { - for (int n = 0; n < i; n++) - { - toArraySaved.push_back(StableSortTestObj(n)); - - if (rng.RandLimit(10) == 0) - { - toArraySaved.push_back(StableSortTestObj(n)); - - if (rng.RandLimit(5) == 0) - toArraySaved.push_back(StableSortTestObj(n)); - } - } - vector<StableSortTestObj> tempBuffer; - tempBuffer.resize(toArraySaved.size()); - - for (int j = 0; j < 300 + (gEASTL_TestLevel * 50); j++) - { - eastl::random_shuffle(toArraySaved.begin(), toArraySaved.end(), rng); - // Store the intial position of each element in the array before sorting. This position can then be used to verify that the sorting operation is stable. - for (vector<StableSortTestObj>::size_type k = 0; k < toArraySaved.size(); k++) - { - toArraySaved[k].initialPositionIndex = k; - } - - toArray = toArraySaved; - bubble_sort(toArray.begin(), toArray.end(), compare); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end(), compareForStability)); - - toArray = toArraySaved; - shaker_sort(toArray.begin(), toArray.end(), compare); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end(), compareForStability)); - - toArray = toArraySaved; - insertion_sort(toArray.begin(), toArray.end(), compare); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end(), compareForStability)); - - toArray = toArraySaved; - tim_sort_buffer(toArray.begin(), toArray.end(), tempBuffer.data(), compare); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end(), compareForStability)); - - toArray = toArraySaved; - merge_sort(toArray.begin(), toArray.end(), *get_default_allocator((EASTLAllocatorType*)NULL), compare); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end(), compareForStability)); - - toArray = toArraySaved; - merge_sort_buffer(toArray.begin(), toArray.end(), tempBuffer.data(), compare); - EATEST_VERIFY(is_sorted(toArray.begin(), toArray.end(), compareForStability)); - } - } - } - - { - // OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) - // This is tested by merge_sort. - } - - - { - // void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last) - // This is tested by quick_sort. - } - - - { - // void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last) - // void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare compare) - const int intArrayInit[16] = { 4, 2, 8, 6, 9, 1, 1, 4, 0, 5, 5, 7, 8, 9, 3, 3 }; - int intArraySorted[16]; // Same as intArrayInit but sorted - int intArray[16]; - size_t i, j; - - // We test many combinations of nth_element on the int array. - for(i = 1; i < 16; i++) - { - for(j = 0; j < i; j++) - { - eastl::copy(intArrayInit, intArrayInit + i, intArraySorted); - eastl::sort(intArraySorted, intArraySorted + i); - - eastl::copy(intArrayInit, intArrayInit + i, intArray); - nth_element(intArray, intArray + j, intArray + i); - EATEST_VERIFY(intArray[j] == intArraySorted[j]); - } - } - - for(i = 1; i < 16; i++) - { - for(j = 0; j < i; j++) - { - eastl::copy(intArrayInit, intArrayInit + i, intArraySorted); - eastl::sort(intArraySorted, intArraySorted + i); - - eastl::copy(intArrayInit, intArrayInit + 16, intArray); - nth_element(intArray, intArray + j, intArray + i, eastl::less<int>()); - EATEST_VERIFY(intArray[j] == intArraySorted[j]); - } - } - } - - - { - // void radix_sort(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator buffer); - const uint32_t kCount = 100; - - { - RadixSortElement32* pRadixSortElementArray32 = new RadixSortElement32[kCount]; - RadixSortElement32* pRadixSortElementArrayTemp32 = new RadixSortElement32[kCount]; - for(uint32_t i = 0; i < kCount; i++) - { - pRadixSortElementArray32[i].mKey = (uint16_t)(kCount - i); - pRadixSortElementArray32[i].mData = (uint16_t)i; - } - radix_sort<RadixSortElement32*, extract_radix_key<RadixSortElement32> >(pRadixSortElementArray32, pRadixSortElementArray32 + kCount, pRadixSortElementArrayTemp32); - EATEST_VERIFY(is_sorted(pRadixSortElementArray32, pRadixSortElementArray32 + kCount)); - delete[] pRadixSortElementArray32; - delete[] pRadixSortElementArrayTemp32; - } - - { - RadixSortElement16* pRadixSortElementArray16 = new RadixSortElement16[kCount]; - RadixSortElement16* pRadixSortElementArrayTemp16 = new RadixSortElement16[kCount]; - for(uint32_t i = 0; i < kCount; i++) - { - pRadixSortElementArray16[i].mKey = (uint16_t)(kCount - i); - pRadixSortElementArray16[i].mData = (uint16_t)i; - } - radix_sort<RadixSortElement16*, extract_radix_key<RadixSortElement16> >(pRadixSortElementArray16, pRadixSortElementArray16 + kCount, pRadixSortElementArrayTemp16); - EATEST_VERIFY(is_sorted(pRadixSortElementArray16, pRadixSortElementArray16 + kCount)); - delete[] pRadixSortElementArray16; - delete[] pRadixSortElementArrayTemp16; - } - - { - RadixSortElement8* pRadixSortElementArray8 = new RadixSortElement8[kCount]; - RadixSortElement8* pRadixSortElementArrayTemp8 = new RadixSortElement8[kCount]; - for(uint32_t i = 0; i < kCount; i++) - { - pRadixSortElementArray8[i].mKey = (uint8_t)(kCount - i); - pRadixSortElementArray8[i].mData = (uint8_t)i; - } - radix_sort<RadixSortElement8*, extract_radix_key<RadixSortElement8> >(pRadixSortElementArray8, pRadixSortElementArray8 + kCount, pRadixSortElementArrayTemp8); - EATEST_VERIFY(is_sorted(pRadixSortElementArray8, pRadixSortElementArray8 + kCount)); - delete[] pRadixSortElementArray8; - delete[] pRadixSortElementArrayTemp8; - } - } - - { - // Do some white-box testing of radix sort to verify internal optimizations work properly for some edge cases. - - { - uint32_t input[] = { 123, 15, 76, 2, 74, 12, 62, 91 }; - uint32_t buffer[EAArrayCount(input)]; - radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - { - // Test values where some digit positions have identical values - uint32_t input[] = { 0x75000017, 0x74000003, 0x73000045, 0x76000024, 0x78000033, 0x76000099, 0x78000043, 0x75000010 }; - uint32_t buffer[EAArrayCount(input)]; - radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - { - // Test values where some digit positions have identical values - uint32_t input[] = { 0x00750017, 0x00740003, 0x00730045, 0x00760024, 0x00780033, 0x00760099, 0x00780043, 0x00750010 }; - uint32_t buffer[EAArrayCount(input)]; - radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - { - // Test values where an odd number of scatter operations will be done during sorting (which forces a copy operation to move values back to the input buffer). - uint32_t input[] = { 0x00000017, 0x00000003, 0x00000045, 0x00000024, 0x00000033, 0x00000099, 0x00000043, 0x00000010 }; - uint32_t buffer[EAArrayCount(input)]; - radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - { - // Test case for bug where the last histogram bucket was not being cleared to zero - uint32_t input[] = { 0xff00, 0xff }; - uint32_t buffer[EAArrayCount(input)]; - radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - } - - { - // Test different values for DigitBits - - { - uint32_t input[] = {2514513, 6278225, 2726217, 963245656, 35667326, 2625624562, 3562562562, 1556256252}; - uint32_t buffer[EAArrayCount(input)]; - radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>, 1>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - { - uint32_t input[] = { 2514513, 6278225, 2726217, 963245656, 35667326, 2625624562, 3562562562, 1556256252 }; - uint32_t buffer[EAArrayCount(input)]; - radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>, 3>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - { - uint32_t input[] = { 2514513, 6278225, 2726217, 963245656, 35667326, 2625624562, 3562562562, 1556256252 }; - uint32_t buffer[EAArrayCount(input)]; - radix_sort<uint32_t*, identity_extract_radix_key<uint32_t>, 6>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - { - // Test a value for DigitBits that is more than half the size of the type. - uint16_t input[] = { 14513, 58225, 26217, 34656, 63326, 24562, 35562, 15652 }; - uint16_t buffer[EAArrayCount(input)]; - radix_sort<uint16_t*, identity_extract_radix_key<uint16_t>, 11>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - { - // Test a value for DigitBits that is the size of the type itself. - uint8_t input[] = { 113, 225, 217, 56, 26, 162, 62, 152 }; - uint8_t buffer[EAArrayCount(input)]; - radix_sort<uint8_t*, identity_extract_radix_key<uint8_t>, 8>(begin(input), end(input), buffer); - EATEST_VERIFY(is_sorted(begin(input), end(input))); - } - - } - - { - // void bucket_sort(ForwardIterator first, ForwardIterator last, ContainerArray& bucketArray, HashFunction hash) - - const size_t kElementRange = 32; - vector<int> intArray(1000); - - for(int i = 0; i < 1000; i++) - intArray[i] = rng() % kElementRange; - - vector< vector<int> > bucketArray(kElementRange); - bucket_sort(intArray.begin(), intArray.end(), bucketArray, eastl::hash_use_self<int>()); - EATEST_VERIFY(is_sorted(intArray.begin(), intArray.end())); - } - - - { - // stable_sort general test - typedef eastl::less<int> IntCompare; - - int intArray[2] = { 0, 1 }; - - stable_sort(intArray, intArray + 2); - stable_sort(intArray, intArray + 2, IntCompare()); - stable_sort<int*>(intArray, intArray + 2); - stable_sort<int*, IntCompare>(intArray, intArray + 2, IntCompare()); - - MallocAllocator mallocAllocator; - - //stable_sort(intArray, intArray + 2, mallocAllocator); - stable_sort(intArray, intArray + 2, mallocAllocator, IntCompare()); - //stable_sort<int*, MallocAllocator>(intArray, intArray + 2, mallocAllocator); - stable_sort<int*, MallocAllocator, IntCompare>(intArray, intArray + 2, mallocAllocator, IntCompare()); - } - - { - // stable_sort special test - IntArrayArray intArrayArray(2); - IntArrayCompare compare; - - intArrayArray[0].push_back(0); - intArrayArray[1].push_back(1); - - stable_sort(intArrayArray.begin(), intArrayArray.end(), compare); - } - - - { - // Test to verify that Compare object references are preserved. - typedef deque<int> IntDeque; - typedef IntDeque::iterator IntDequeIterator; - - IntDeque intDeque, intDequeSaved; - StatefulCompare compare; - - // Set up intDequeSaved with random data. - for(int n = 0; n < 500; n++) - { - intDequeSaved.push_back(n); - - if(rng.RandLimit(10) == 0) - { - intDequeSaved.push_back(n); - - if(rng.RandLimit(5) == 0) - intDequeSaved.push_back(n); - } - } - - eastl::random_shuffle(intDequeSaved.begin(), intDequeSaved.end(), rng); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - bubble_sort<IntDequeIterator, StatefulCompare&>(intDeque.begin(), intDeque.end(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - shaker_sort<IntDequeIterator, StatefulCompare&>(intDeque.begin(), intDeque.end(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - insertion_sort<IntDequeIterator, StatefulCompare&>(intDeque.begin(), intDeque.end(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - selection_sort<IntDequeIterator, StatefulCompare&>(intDeque.begin(), intDeque.end(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - shell_sort<IntDequeIterator, StatefulCompare&>(intDeque.begin(), intDeque.end(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - comb_sort<IntDequeIterator, StatefulCompare&>(intDeque.begin(), intDeque.end(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - heap_sort<IntDequeIterator, StatefulCompare&>(intDeque.begin(), intDeque.end(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - merge_sort<IntDequeIterator, EASTLAllocatorType, StatefulCompare&>(intDeque.begin(), intDeque.end(), *get_default_allocator((EASTLAllocatorType*)NULL), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - intDeque = intDequeSaved; - quick_sort<IntDequeIterator, StatefulCompare&>(intDeque.begin(), intDeque.end(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - - StatefulCompare::Reset(); - vector<int> buffer(intDeque.size()/2); - intDeque = intDequeSaved; - tim_sort_buffer<IntDequeIterator, int, StatefulCompare&>(intDeque.begin(), intDeque.end(), buffer.data(), compare); - EATEST_VERIFY((StatefulCompare::nCtorCount == 0) && (StatefulCompare::nDtorCount == 0) && (StatefulCompare::nCopyCount == 0)); - } - - { - // Test checking that deque sorting can compile. - deque<int> intDeque; - vector<int> intVector; - - stable_sort(intDeque.begin(), intDeque.end()); - stable_sort(intVector.begin(), intVector.end()); - } - - { - // Test checking that sorting containers having elements of a type without an operator< compiles correctly - - vector<TestNoLessOperator> noLessVector; - - stable_sort(noLessVector.begin(), noLessVector.end()); - bubble_sort(noLessVector.begin(), noLessVector.end()); - shaker_sort(noLessVector.begin(), noLessVector.end()); - insertion_sort(noLessVector.begin(), noLessVector.end()); - selection_sort(noLessVector.begin(), noLessVector.end()); - shell_sort(noLessVector.begin(), noLessVector.end()); - comb_sort(noLessVector.begin(), noLessVector.end()); - heap_sort(noLessVector.begin(), noLessVector.end()); - merge_sort(noLessVector.begin(), noLessVector.end(), *get_default_allocator(nullptr)); - quick_sort(noLessVector.begin(), noLessVector.end()); - - vector<TestNoLessOperator> buffer; - tim_sort_buffer(noLessVector.begin(), noLessVector.end(), buffer.data()); -} - - { - // Test sorting of a container of pointers to objects as opposed to a container of objects themselves. - vector<TestObject> toArray; - vector<TestObject*> topArray; - - for(eastl_size_t i = 0; i < 32; i++) - toArray.push_back(TestObject((int)rng.RandLimit(20))); - for(eastl_size_t i = 0; i < 32; i++) // This needs to be a second loop because the addresses might change in the first loop due to container resizing. - topArray.push_back(&toArray[i]); - - quick_sort(topArray.begin(), topArray.end(), TestObjectPtrCompare()); - EATEST_VERIFY(is_sorted(topArray.begin(), topArray.end(), TestObjectPtrCompare())); - } - - - { - // Test sorting of a container of array indexes to objects as opposed to a container of objects themselves. - - vector<TestObject> toArray; - vector<eastl_size_t> toiArray; - - for(eastl_size_t i = 0; i < 32; i++) - { - toArray.push_back(TestObject((int)rng.RandLimit(20))); - toiArray.push_back(i); - } - - quick_sort(toiArray.begin(), toiArray.end(), TestObjectIndexCompare(&toArray)); - EATEST_VERIFY(is_sorted(toiArray.begin(), toiArray.end(), TestObjectIndexCompare(&toArray))); - } - - - { - // Test of special floating point sort in the presence of NaNs. - vector<float> floatArray; - union FloatInt32{ float f; int32_t i; } fi; - - for(int i = 0; i < 1000; i++) - { - fi.i = (int32_t)rng.Rand(); - floatArray.push_back(fi.f); - } - - // Without SafeFloatCompare, the following quick_sort will crash, hang, or generate inconsistent results. - quick_sort(floatArray.begin(), floatArray.end(), SafeFloatCompare()); - EATEST_VERIFY(is_sorted(floatArray.begin(), floatArray.end(), SafeFloatCompare())); - } - - { - auto test_stable_sort = [&](auto testArray, size_t count) - { - auto isEven = [](auto val) { return (val % 2) == 0; }; - auto isOdd = [](auto val) { return (val % 2) != 0; }; - - for (size_t i = 0; i < count; i++) - testArray.push_back((uint16_t)rng.Rand()); - - vector<uint16_t> evenArray; - vector<uint16_t> oddArray; - - eastl::copy_if(testArray.begin(), testArray.end(), eastl::back_inserter(evenArray), isEven); - eastl::copy_if(testArray.begin(), testArray.end(), eastl::back_inserter(oddArray), isOdd); - - const auto boundary = eastl::stable_partition(testArray.begin(), testArray.end(), isEven); - - const auto evenCount = eastl::distance(testArray.begin(), boundary); - const auto oddCount = eastl::distance(boundary, testArray.end()); - - const auto evenExpectedCount = (ptrdiff_t)evenArray.size(); - const auto oddExpectedCount = (ptrdiff_t)oddArray.size(); - - EATEST_VERIFY(evenCount == evenExpectedCount); - EATEST_VERIFY(oddCount == oddExpectedCount); - EATEST_VERIFY(eastl::equal(testArray.begin(), boundary, evenArray.begin())); - EATEST_VERIFY(eastl::equal(boundary, testArray.end(), oddArray.begin())); - }; - - test_stable_sort(vector<uint16_t>(), 1000); // Test stable_partition - test_stable_sort(vector<uint16_t>(), 0); // Test stable_partition on empty container - test_stable_sort(vector<uint16_t>(), 1); // Test stable_partition on container of one element - test_stable_sort(vector<uint16_t>(), 2); // Test stable_partition on container of two element - test_stable_sort(list<uint16_t>(), 0); // Test stable_partition on bidirectional iterator (not random access) - } - - #if 0 // Disabled because it takes a long time and thus far seems to show no bug in quick_sort. - { - // Regression of Coverity report for Madden 2014 that quick_sort is reading beyond an array bounds within insertion_sort_simple. - // The Madden code was sorting the 11 players on the field for a team by some criteria. We write - vector<int> intArray(11); - for(eastl_size_t i = 0; i < intArray.size(); i++) - intArray[i] = i; - - do { - vector<int> intArrayCopy(intArray); - - // We need to verify that intArray[12] is never accessed. We could do that with a stomp allocator, - // which we don't currently have set up for the EASTL unit tests, or we could put a breakpoint in - // the debugger. Until we get a stomp allocator installed, do the breakpoint solution. - quick_sort(intArrayCopy.begin(), intArrayCopy.end()); - } while(next_permutation(intArray.begin(), intArray.end())); - } - #endif - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - return nErrorCount; -} - - - - - - - - - diff --git a/test/source/TestSpan.cpp b/test/source/TestSpan.cpp deleted file mode 100644 index 5a0ec07..0000000 --- a/test/source/TestSpan.cpp +++ /dev/null @@ -1,481 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EASTL/array.h> -#include <EASTL/span.h> -#include <EASTL/vector.h> - -void TestSpanCtor(int& nErrorCount) -{ - using namespace eastl; - - { - span<int> s; - VERIFY(s.empty()); - VERIFY(s.size() == 0); - VERIFY(s.data() == nullptr); - } - { - span<float> s; - VERIFY(s.empty()); - VERIFY(s.size() == 0); - VERIFY(s.data() == nullptr); - } - { - span<TestObject> s; - VERIFY(s.empty()); - VERIFY(s.size() == 0); - VERIFY(s.data() == nullptr); - } - - { - int arr[5] = {0, 1, 2, 3, 4}; - span<int> s(eastl::begin(arr), 5); - VERIFY(s.data() == eastl::begin(arr)); - VERIFY(s.size() == 5); - VERIFY(!s.empty()); - } - - { - int arr[5] = {0, 1, 2, 3, 4}; - span<int> s(eastl::begin(arr), eastl::end(arr)); - VERIFY(s.data() == eastl::begin(arr)); - VERIFY(s.size() == 5); - VERIFY(!s.empty()); - } - - { - int arr[5] = {0, 1, 2, 3, 4}; - span<int> s(arr); - VERIFY(s.data() == eastl::begin(arr)); - VERIFY(s.size() == 5); - VERIFY(s.data()[2] == arr[2]); - VERIFY(!s.empty()); - } - - { - eastl::array<int, 5> arr = {{0, 1, 2, 3, 4}}; - span<int> s(arr); - VERIFY(s.data() == eastl::begin(arr)); - VERIFY(s.size() == 5); - VERIFY(s.data()[2] == arr.data()[2]); - VERIFY(!s.empty()); - } - - { - const eastl::array<int, 5> arr = {{0, 1, 2, 3, 4}}; - span<const int> s(arr); - VERIFY(s.data() == eastl::begin(arr)); - VERIFY(s.size() == 5); - VERIFY(s.data()[2] == arr.data()[2]); - VERIFY(!s.empty()); - } - - { - const eastl::array<int, 5> arr = {{0, 1, 2, 3, 4}}; - const span<const int> s(arr); - VERIFY(s.data() == eastl::begin(arr)); - VERIFY(s.size() == 5); - VERIFY(s.data()[2] == arr.data()[2]); - } - - { - class foo {}; - - foo* pFoo = nullptr; - - auto f = [](eastl::span<const foo*>) {}; - - eastl::array<const foo*, 1> foos = {{pFoo}}; - - f(foos); - } -} - -void TestSpanSizeBytes(int& nErrorCount) -{ - using namespace eastl; - - { - int arr[5] = {0, 1, 2, 3, 4}; - span<int> s(arr); - VERIFY(s.size_bytes() == sizeof(arr)); - VERIFY(s.size_bytes() == (5 * sizeof(int))); - } - - { - float arr[8] = {0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f}; - span<float> s(arr); - VERIFY(s.size_bytes() == sizeof(arr)); - VERIFY(s.size_bytes() == (8 * sizeof(float))); - } - - { - int64_t arr[5] = {0, 1, 2, 3, 4}; - span<int64_t> s(arr); - VERIFY(s.size_bytes() == sizeof(arr)); - VERIFY(s.size_bytes() == (5 * sizeof(int64_t))); - } -} - -void TestSpanElementAccess(int& nErrorCount) -{ - using namespace eastl; - - { - int arr[5] = {0, 1, 2, 3, 4}; - span<int> s(arr); - - VERIFY(s.front() == 0); - VERIFY(s.back() == 4); - - VERIFY(s[0] == 0); - VERIFY(s[1] == 1); - VERIFY(s[2] == 2); - VERIFY(s[3] == 3); - VERIFY(s[4] == 4); - - VERIFY(s(0) == 0); - VERIFY(s(1) == 1); - VERIFY(s(2) == 2); - VERIFY(s(3) == 3); - VERIFY(s(4) == 4); - } -} - -void TestSpanIterators(int& nErrorCount) -{ - using namespace eastl; - - int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - span<int> s(arr); - - // ranged-for test - { - int* pBegin = arr; - for(auto& e : arr) - { - VERIFY(e == *pBegin++); - } - } - - { - auto testIteratorBegin = [&](auto p) - { - VERIFY(*p++ == 0); - VERIFY(*p++ == 1); - VERIFY(*p++ == 2); - VERIFY(*p++ == 3); - VERIFY(*p++ == 4); - VERIFY(*p++ == 5); - VERIFY(*p++ == 6); - VERIFY(*p++ == 7); - VERIFY(*p++ == 8); - VERIFY(*p++ == 9); - }; - - auto testIteratorEnd = [&](auto p) - { - p--; // move pointer to a valid element - - VERIFY(*p-- == 9); - VERIFY(*p-- == 8); - VERIFY(*p-- == 7); - VERIFY(*p-- == 6); - VERIFY(*p-- == 5); - VERIFY(*p-- == 4); - VERIFY(*p-- == 3); - VERIFY(*p-- == 2); - VERIFY(*p-- == 1); - VERIFY(*p-- == 0); - }; - - testIteratorBegin(s.begin()); - testIteratorBegin(s.cbegin()); - testIteratorEnd(s.end()); - testIteratorEnd(s.cend()); - } - - { - auto testReverseIteratorBegin = [&](auto p) - { - VERIFY(*p++ == 9); - VERIFY(*p++ == 8); - VERIFY(*p++ == 7); - VERIFY(*p++ == 6); - VERIFY(*p++ == 5); - VERIFY(*p++ == 4); - VERIFY(*p++ == 3); - VERIFY(*p++ == 2); - VERIFY(*p++ == 1); - VERIFY(*p++ == 0); - }; - - auto testReverseIteratorEnd = [&](auto p) - { - p--; // move pointer to a valid element - - VERIFY(*p-- == 0); - VERIFY(*p-- == 1); - VERIFY(*p-- == 2); - VERIFY(*p-- == 3); - VERIFY(*p-- == 4); - VERIFY(*p-- == 5); - VERIFY(*p-- == 6); - VERIFY(*p-- == 7); - VERIFY(*p-- == 8); - VERIFY(*p-- == 9); - }; - - testReverseIteratorBegin(s.rbegin()); - testReverseIteratorBegin(s.crbegin()); - testReverseIteratorEnd(s.rend()); - testReverseIteratorEnd(s.crend()); - } -} - -void TestSpanCopyAssignment(int& nErrorCount) -{ - using namespace eastl; - - { - int arr[5] = {0, 1, 2, 3, 4}; - span<int> s(arr); - span<int> sc = s; - - VERIFY(s[0] == sc[0]); - VERIFY(s[1] == sc[1]); - VERIFY(s[2] == sc[2]); - VERIFY(s[3] == sc[3]); - VERIFY(s[4] == sc[4]); - - VERIFY(s(0) == sc(0)); - VERIFY(s(1) == sc(1)); - VERIFY(s(2) == sc(2)); - VERIFY(s(3) == sc(3)); - VERIFY(s(4) == sc(4)); - } -} - -void TestSpanContainerConversion(int& nErrorCount) -{ - using namespace eastl; - - { - vector<int> v = {0, 1, 2, 3, 4, 5}; - span<const int> s(v); - - VERIFY(s.size() == static_cast<span<int>::index_type>(eastl::size(v))); - VERIFY(s.data() == eastl::data(v)); - - VERIFY(s[0] == v[0]); - VERIFY(s[1] == v[1]); - VERIFY(s[2] == v[2]); - VERIFY(s[3] == v[3]); - VERIFY(s[4] == v[4]); - VERIFY(s[5] == v[5]); - } - - { - const vector<int> v = {0, 1, 2, 3, 4, 5}; - span<const int> s(v); - - VERIFY(s.size() == static_cast<span<int>::index_type>(eastl::size(v))); - VERIFY(s.data() == eastl::data(v)); - - VERIFY(s[0] == v[0]); - VERIFY(s[1] == v[1]); - VERIFY(s[2] == v[2]); - VERIFY(s[3] == v[3]); - VERIFY(s[4] == v[4]); - VERIFY(s[5] == v[5]); - } - - { - vector<int> v = {0, 1, 2, 3, 4, 5}; - span<const int, 6> s1(v); - span<const int> s2(s1); - - VERIFY(s2.size() == (span<const int>::index_type)v.size()); - VERIFY(s2[0] == v[0]); - VERIFY(s2[1] == v[1]); - - VERIFY(s1.data() == v.data()); - VERIFY(s1.data() == s2.data()); - } - - { // user reported regression for calling non-const span overload with a vector. - auto f1 = [](span<int> s) { return s.size(); }; - auto f2 = [](span<const int> s) { return s.size(); }; - - { - vector<int> v = {0, 1, 2, 3, 4, 5}; - - VERIFY(f1(v) == v.size()); - VERIFY(f2(v) == v.size()); - } - - { - int a[] = {0, 1, 2, 3, 4, 5}; - - VERIFY(f1(a) == EAArrayCount(a)); - VERIFY(f2(a) == EAArrayCount(a)); - } - } -} - -void TestSpanComparison(int& nErrorCount) -{ - using namespace eastl; - - int arr1[5] = {0, 1, 2, 3, 4}; - int arr2[8] = {0, 1, 2, 3, 4, 5, 6, 7}; - { - span<int> s1 = arr1; - span<int> s2 = arr2; - span<int> s3 = arr2; - VERIFY(s2 == s3); - VERIFY(s1 != s2); - VERIFY(s1 < s2); - VERIFY(s1 <= s2); - VERIFY(s2 > s1); - VERIFY(s2 >= s1); - } -} - -void TestSpanSubViews(int& nErrorCount) -{ - using namespace eastl; - - int arr1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - { - span<int> s = arr1; - auto first_span = s.first<4>(); - VERIFY(first_span.size() == 4); - VERIFY(first_span[0] == 0); - VERIFY(first_span[1] == 1); - VERIFY(first_span[2] == 2); - VERIFY(first_span[3] == 3); - } - - { - span<int> s = arr1; - auto first_span = s.first(4); - VERIFY(first_span.size() == 4); - VERIFY(first_span[0] == 0); - VERIFY(first_span[1] == 1); - VERIFY(first_span[2] == 2); - VERIFY(first_span[3] == 3); - } - - { - span<int> s = arr1; - auto first_span = s.last<4>(); - VERIFY(first_span.size() == 4); - VERIFY(first_span[0] == 6); - VERIFY(first_span[1] == 7); - VERIFY(first_span[2] == 8); - VERIFY(first_span[3] == 9); - } - - { - span<int> s = arr1; - auto first_span = s.last(4); - VERIFY(first_span.size() == 4); - VERIFY(first_span[0] == 6); - VERIFY(first_span[1] == 7); - VERIFY(first_span[2] == 8); - VERIFY(first_span[3] == 9); - } - - { // empty range - span<int, 0> s{}; - - auto fixed_span = s.subspan<0, 0>(); - VERIFY(fixed_span.empty()); - fixed_span = s.first<0>(); - VERIFY(fixed_span.empty()); - fixed_span = s.last<0>(); - VERIFY(fixed_span.empty()); - - span<int> dynamic_span; - VERIFY(dynamic_span.empty()); - dynamic_span = s.first(0); - VERIFY(dynamic_span.empty()); - dynamic_span = s.last(0); - VERIFY(dynamic_span.empty()); - } - - { // subspan: full range - span<int, 10> s = arr1; - - auto fixed_span = s.subspan<0, 10>(); - VERIFY(fixed_span.size() == 10); - VERIFY(fixed_span[0] == 0); - VERIFY(fixed_span[1] == 1); - VERIFY(fixed_span[8] == 8); - VERIFY(fixed_span[9] == 9); - - auto dynamic_span = s.subspan(0, s.size()); - VERIFY(dynamic_span.size() == 10); - VERIFY(dynamic_span[0] == 0); - VERIFY(dynamic_span[1] == 1); - VERIFY(dynamic_span[8] == 8); - VERIFY(dynamic_span[9] == 9); - } - - { // subspan: subrange - span<int, 10> s = arr1; - - auto fixed_span = s.subspan<3, 4>(); - VERIFY(fixed_span.size() == 4); - VERIFY(fixed_span[0] == 3); - VERIFY(fixed_span[1] == 4); - VERIFY(fixed_span[2] == 5); - VERIFY(fixed_span[3] == 6); - - auto dynamic_span = s.subspan(3, 4); - VERIFY(dynamic_span.size() == 4); - VERIFY(dynamic_span[0] == 3); - VERIFY(dynamic_span[1] == 4); - VERIFY(dynamic_span[2] == 5); - VERIFY(dynamic_span[3] == 6); - } - - { // subspan: default count - span<int, 10> s = arr1; - - auto fixed_span = s.subspan<3>(); - VERIFY(fixed_span.size() == 7); - VERIFY(fixed_span[0] == 3); - VERIFY(fixed_span[1] == 4); - VERIFY(fixed_span[5] == 8); - VERIFY(fixed_span[6] == 9); - - auto dynamic_span = s.subspan(3); - VERIFY(dynamic_span.size() == 7); - VERIFY(dynamic_span[0] == 3); - VERIFY(dynamic_span[1] == 4); - VERIFY(dynamic_span[5] == 8); - VERIFY(dynamic_span[6] == 9); - } -} - -int TestSpan() -{ - int nErrorCount = 0; - - TestSpanCtor(nErrorCount); - TestSpanSizeBytes(nErrorCount); - TestSpanElementAccess(nErrorCount); - TestSpanIterators(nErrorCount); - TestSpanCopyAssignment(nErrorCount); - TestSpanContainerConversion(nErrorCount); - TestSpanComparison(nErrorCount); - TestSpanSubViews(nErrorCount); - - return nErrorCount; -} diff --git a/test/source/TestString.cpp b/test/source/TestString.cpp deleted file mode 100644 index 1bd06e7..0000000 --- a/test/source/TestString.cpp +++ /dev/null @@ -1,142 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EABase/eabase.h> -#include <EAStdC/EAMemory.h> -#include <EAStdC/EAString.h> -#include <EASTL/string.h> -#include <EASTL/algorithm.h> -#include <EASTL/allocator_malloc.h> - -using namespace eastl; - -// Verify char8_t support is present if the test build requested it. -#if defined(EASTL_EXPECT_CHAR8T_SUPPORT) && !EA_CHAR8_UNIQUE -static_assert(false, "Building with char8_t tests enabled, but EA_CHAR8_UNIQUE evaluates to false."); -#endif - - -// inject string literal string conversion macros into the unit tests -#define TEST_STRING_NAME TestBasicString -#define LITERAL(x) x -#include "TestString.inl" - -#define TEST_STRING_NAME TestBasicStringW -#define LITERAL(x) EA_WCHAR(x) -#include "TestString.inl" - -#define TEST_STRING_NAME TestBasicString8 -#define LITERAL(x) EA_CHAR8(x) -#include "TestString.inl" - -#define TEST_STRING_NAME TestBasicString16 -#define LITERAL(x) EA_CHAR16(x) -#include "TestString.inl" - -#define TEST_STRING_NAME TestBasicString32 -#define LITERAL(x) EA_CHAR32(x) -#include "TestString.inl" - -int TestString() -{ - int nErrorCount = 0; - - nErrorCount += TestBasicString<eastl::basic_string<char, StompDetectAllocator>>(); - nErrorCount += TestBasicString<eastl::string>(); - - nErrorCount += TestBasicStringW<eastl::basic_string<wchar_t, StompDetectAllocator>>(); - nErrorCount += TestBasicStringW<eastl::wstring>(); - -#if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE - nErrorCount += TestBasicString8<eastl::basic_string<char8_t, StompDetectAllocator>>(); - nErrorCount += TestBasicString8<eastl::u8string>(); -#endif - - nErrorCount += TestBasicString16<eastl::basic_string<char16_t, StompDetectAllocator>>(); - nErrorCount += TestBasicString16<eastl::u16string>(); - -#if defined(EA_CHAR32_NATIVE) && EA_CHAR32_NATIVE - nErrorCount += TestBasicString32<eastl::basic_string<char32_t, StompDetectAllocator>>(); - nErrorCount += TestBasicString32<eastl::u32string>(); -#endif - - // Check for memory leaks by using the 'CountingAllocator' to ensure no active allocation after tests have completed. - CountingAllocator::resetCount(); - nErrorCount += TestBasicString<eastl::basic_string<char, CountingAllocator>>(); - VERIFY(CountingAllocator::getActiveAllocationCount() == 0); - - nErrorCount += TestBasicStringW<eastl::basic_string<wchar_t, CountingAllocator>>(); - VERIFY(CountingAllocator::getActiveAllocationCount() == 0); - -#if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE - nErrorCount += TestBasicString8<eastl::basic_string<char8_t, CountingAllocator>>(); - VERIFY(CountingAllocator::getActiveAllocationCount() == 0); -#endif - - nErrorCount += TestBasicString16<eastl::basic_string<char16_t, CountingAllocator>>(); - VERIFY(CountingAllocator::getActiveAllocationCount() == 0); - -#if defined(EA_CHAR32_NATIVE) && EA_CHAR32_NATIVE - nErrorCount += TestBasicString32<eastl::basic_string<char32_t, CountingAllocator>>(); - VERIFY(CountingAllocator::getActiveAllocationCount() == 0); -#endif - - // to_string - { - VERIFY(eastl::to_string(42) == "42"); - VERIFY(eastl::to_string(42l) == "42"); - VERIFY(eastl::to_string(42ll) == "42"); - VERIFY(eastl::to_string(42u) == "42"); - VERIFY(eastl::to_string(42ul) == "42"); - VERIFY(eastl::to_string(42ull) == "42"); - VERIFY(eastl::to_string(42.f) == "42.000000"); - VERIFY(eastl::to_string(42.0) == "42.000000"); - #if !defined(EA_COMPILER_GNUC) && !defined(EA_PLATFORM_MINGW) - // todo: long double sprintf functionality is unrealiable on unix-gcc, requires further debugging. - VERIFY(eastl::to_string(42.0l) == "42.000000"); - #endif - } - - // to_wstring - { - VERIFY(eastl::to_wstring(42) == L"42"); - VERIFY(eastl::to_wstring(42l) == L"42"); - VERIFY(eastl::to_wstring(42ll) == L"42"); - VERIFY(eastl::to_wstring(42u) == L"42"); - VERIFY(eastl::to_wstring(42ul) == L"42"); - VERIFY(eastl::to_wstring(42ull) == L"42"); - VERIFY(eastl::to_wstring(42.f) == L"42.000000"); - VERIFY(eastl::to_wstring(42.0) == L"42.000000"); - #if !defined(EA_COMPILER_GNUC) && !defined(EA_PLATFORM_MINGW) - // todo: long double sprintf functionality is unrealiable on unix-gcc, requires further debugging. - VERIFY(eastl::to_wstring(42.0l) == L"42.000000"); - #endif - } - - #if EASTL_USER_LITERALS_ENABLED - { - VERIFY("cplusplus"s == "cplusplus"); - VERIFY(L"cplusplus"s == L"cplusplus"); - VERIFY(u"cplusplus"s == u"cplusplus"); - VERIFY(U"cplusplus"s == U"cplusplus"); - VERIFY(u8"cplusplus"s == u8"cplusplus"); - } - #endif - - - { - // CustomAllocator has no data members which reduces the size of an eastl::basic_string via the empty base class optimization. - using EboString = eastl::basic_string<char, CustomAllocator>; - - // this must match the eastl::basic_string heap memory layout struct which is a pointer and 2 eastl_size_t. - const int expectedSize = sizeof(EboString::pointer) + (2 * sizeof(EboString::size_type)); - - static_assert(sizeof(EboString) == expectedSize, "unexpected layout size of basic_string"); - } - - return nErrorCount; -} - - diff --git a/test/source/TestString.inl b/test/source/TestString.inl deleted file mode 100644 index 3a59e68..0000000 --- a/test/source/TestString.inl +++ /dev/null @@ -1,2101 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -// todo: -// Test Encoding -// Test StringHash -// Test exceptions - -#if EASTL_OPENSOURCE - #define EASTL_SNPRINTF_TESTS_ENABLED 0 -#else - #define EASTL_SNPRINTF_TESTS_ENABLED 1 -#endif - - -template<typename StringType> -int TEST_STRING_NAME() -{ - int nErrorCount = 0; - - struct Failocator - { - Failocator() = default; - Failocator(const char*) {} - - void* allocate(size_t) { EA_FAIL(); return nullptr; } - void deallocate(void*, size_t) { EA_FAIL(); } - }; - - #if defined(EA_PLATFORM_ANDROID) - EA_DISABLE_CLANG_WARNING(-Wunknown-warning-option) // warning: disable unknown warning suppression pragmas - EA_DISABLE_CLANG_WARNING(-Wunknown-pragmas) // warning: disable unknown warning suppression pragmas - EA_DISABLE_CLANG_WARNING(-Winherited-variadic-ctor) // warning: inheriting constructor does not inherit ellipsis - #endif - - struct SSOStringType : public StringType - { - using StringType::StringType; - using StringType::IsSSO; - }; - - // Use custom string type that always fails to allocate memory to highlight when SSO is not functioning correctly. - struct SSOFailocatorString : public eastl::basic_string<typename StringType::value_type, Failocator> - { - using eastl::basic_string<typename StringType::value_type, Failocator>::basic_string; - using eastl::basic_string<typename StringType::value_type, Failocator>::IsSSO; - }; - - #if defined(EA_PLATFORM_ANDROID) - EA_RESTORE_CLANG_WARNING() - EA_RESTORE_CLANG_WARNING() - EA_RESTORE_CLANG_WARNING() - #endif - - // SSO (short string optimization) tests - { - { - SSOFailocatorString str; - VERIFY(str.validate()); - VERIFY(str.empty()); - VERIFY(str.IsSSO()); - } - - EA_CONSTEXPR_IF(EA_PLATFORM_WORD_SIZE == 8 && EASTL_SIZE_T_32BIT == 0) - { - // test SSO size on 64 bit platforms - EA_CONSTEXPR_IF(sizeof(typename StringType::value_type) == 1) - { - // we can fit 23 characters on 64bit system with 1 byte chars - const auto* pLiteral = LITERAL("aaaaaaaaaaaaaaaaaaaaaaa"); - SSOFailocatorString str(pLiteral); - - VERIFY(EA::StdC::Strlen(pLiteral) == 23); - VERIFY(str == pLiteral); - VERIFY(str.validate()); - VERIFY(str.IsSSO()); - } - - EA_CONSTEXPR_IF(sizeof(typename StringType::value_type) == 2) - { - // we can fit 11 characters on 64 bit system with 2 byte chars - const auto* pLiteral = LITERAL("aaaaaaaaaaa"); - SSOFailocatorString str(pLiteral); - - VERIFY(EA::StdC::Strlen(pLiteral) == 11); - VERIFY(str == pLiteral); - VERIFY(str.validate()); - VERIFY(str.IsSSO()); - } - - EA_CONSTEXPR_IF(sizeof(typename StringType::value_type) == 4) - { - // we can fit 5 characters on 64 bit system with 4 byte chars - const auto* pLiteral = LITERAL("aaaaa"); - SSOFailocatorString str(pLiteral); - - VERIFY(EA::StdC::Strlen(pLiteral) == 5); - VERIFY(str == pLiteral); - VERIFY(str.validate()); - VERIFY(str.IsSSO()); - } - } - - EA_CONSTEXPR_IF(EA_PLATFORM_WORD_SIZE == 4) - { - // test SSO size on 32 bit platforms - EA_CONSTEXPR_IF(sizeof(typename StringType::value_type) == 1) - { - // we can fit 11 characters on 32bit system with 1 byte chars - const auto* pLiteral = LITERAL("aaaaaaaaaaa"); - SSOFailocatorString str(pLiteral); - - VERIFY(EA::StdC::Strlen(pLiteral) == 11); - VERIFY(str == pLiteral); - VERIFY(str.validate()); - VERIFY(str.IsSSO()); - } - - EA_CONSTEXPR_IF(sizeof(typename StringType::value_type) == 2) - { - // we can fit 5 characters on 32 bit system with 2 byte chars - const auto* pLiteral = LITERAL("aaaaa"); - SSOFailocatorString str(pLiteral); - - VERIFY(EA::StdC::Strlen(pLiteral) == 5); - VERIFY(str == pLiteral); - VERIFY(str.validate()); - VERIFY(str.IsSSO()); - } - - EA_CONSTEXPR_IF(sizeof(typename StringType::value_type) == 4) - { - // we can fit 2 characters on 32 bit system with 4 byte chars - const auto* pLiteral = LITERAL("aa"); - SSOFailocatorString str(pLiteral); - - VERIFY(EA::StdC::Strlen(pLiteral) == 2); - VERIFY(str == pLiteral); - VERIFY(str.validate()); - VERIFY(str.IsSSO()); - } - } - } - - // basic_string(); - { - StringType str; - VERIFY(str.empty()); - VERIFY(str.length() == 0); - VERIFY(str.validate()); - } - - // explicit basic_string(const allocator_type& allocator); - { - typename StringType::allocator_type alloc; - StringType str(alloc); - VERIFY(str.validate()); - } - - // basic_string(const value_type* p, size_type n, const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR); - { - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz"), 26); - VERIFY(str[5] == LITERAL('f')); - VERIFY(!str.empty()); - VERIFY(str.length() == 26); - VERIFY(str.validate()); - } - - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(str[5] == LITERAL('f')); - VERIFY(!str.empty()); - VERIFY(str.length() == 26); - VERIFY(str.validate()); - } - } - - // basic_string(const this_type& x, size_type position, size_type n = npos); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - StringType str2(str1, 3, 3); - VERIFY(str2 == LITERAL("def")); - VERIFY(str2.size() == 3); - VERIFY(str2.length() == 3); - VERIFY(str2.capacity() >= 3); // SSO buffer size - - StringType str3(str1, 25, 3); - VERIFY(str3 == LITERAL("z")); - VERIFY(str3.size() == 1); - VERIFY(str3.length() == 1); - VERIFY(str3.capacity() >= 1); // SSO buffer size - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - VERIFY(str3.validate()); - } - - // EASTL_STRING_EXPLICIT basic_string(const value_type* p, const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR); - { - auto* pLiteral = LITERAL("abcdefghijklmnopqrstuvwxyz"); - StringType str(pLiteral); - VERIFY(str == pLiteral); - } - - // basic_string(size_type n, value_type c, const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR); - { - StringType str(32, LITERAL('a')); - VERIFY(!str.empty()); - VERIFY(str.size() == 32); - VERIFY(str.length() == 32); - VERIFY(str == LITERAL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); - - VERIFY(str.validate()); - } - - // basic_string(const this_type& x); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str2(str1); - - VERIFY(str1 == str2); - VERIFY(str1.size() == str2.size()); - VERIFY(str1.empty() == str2.empty()); - VERIFY(str1.length() == str2.length()); - VERIFY(EA::StdC::Memcmp(str1.data(), str2.data(), str1.size()) == 0); - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - - // basic_string(const value_type* pBegin, const value_type* pEnd, const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - auto* pStart = str1.data() + 5; - auto* pEnd = str1.data() + 20; - - StringType str(pStart, pEnd); - VERIFY(str == LITERAL("fghijklmnopqrst")); - VERIFY(!str.empty()); - VERIFY(str.size() == 15); - } - - // basic_string(CtorDoNotInitialize, size_type n, const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR); - { - StringType str(typename StringType::CtorDoNotInitialize(), 42); - VERIFY(str.size() == 0); - VERIFY(str.length() == 0); - VERIFY(str.capacity() == 42); - } - - // basic_string(CtorSprintf, const value_type* pFormat, ...); - { - #if EASTL_SNPRINTF_TESTS_ENABLED - { - StringType str(typename StringType::CtorSprintf(), LITERAL("Hello, %d"), 42); - VERIFY(str == LITERAL("Hello, 42")); - VERIFY(str.validate()); - } - - { - StringType str(typename StringType::CtorSprintf(), LITERAL("Hello, %d %d %d %d %d %d %d %d %d"), 42, 42, 42, 42, 42, 42, 42, 42, 42); - VERIFY(str == LITERAL("Hello, 42 42 42 42 42 42 42 42 42")); - VERIFY(str.validate()); - } - #endif - } - - // basic_string(std::initializer_list<value_type> init, const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR); - { - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - StringType str({'a','b','c','d','e','f'}); - VERIFY(str == LITERAL("abcdef")); - VERIFY(!str.empty()); - VERIFY(str.length() == 6); - VERIFY(str.size() == 6); - VERIFY(str.validate()); - #endif - } - - // basic_string(this_type&& x); - // basic_string(this_type&& x, const allocator_type& allocator); - { // test heap string - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str2(eastl::move(str1)); - - VERIFY(str1 != LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(str2 == LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str1.empty()); - VERIFY(!str2.empty()); - - VERIFY(str1.length() == 0); - VERIFY(str2.length() == 26); - - VERIFY(str1.size() == 0); - VERIFY(str2.size() == 26); - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - { // test sso string - StringType str1(LITERAL("a")); - StringType str2(eastl::move(str1)); - - VERIFY(str1 != LITERAL("a")); - VERIFY(str2 == LITERAL("a")); - - VERIFY(str1.empty()); - VERIFY(!str2.empty()); - - VERIFY(str1.length() == 0); - VERIFY(str2.length() == 1); - - VERIFY(str1.size() == 0); - VERIFY(str2.size() == 1); - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - - // basic_string(const view_type& sv, const allocator_type& allocator); - // basic_string(const view_type& sv, size_type position, size_type n, const allocator_type& allocator); - { - { // test string_view - typename StringType::view_type sv(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str(sv); - - VERIFY(str == LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(!str.empty()); - VERIFY(str.length() == 26); - VERIFY(str.size() == 26); - VERIFY(str.validate()); - } - - { // test string_view substring - typename StringType::view_type sv(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str(sv, 2, 22); - - VERIFY(str == LITERAL("cdefghijklmnopqrstuvwx")); - VERIFY(!str.empty()); - VERIFY(str.length() == 22); - VERIFY(str.size() == 22); - VERIFY(str.validate()); - } - } - - // template <typename OtherCharType> - // basic_string(CtorConvert, const OtherCharType* p, const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR); - { - { - #if defined(EA_CHAR8) - StringType str(typename StringType::CtorConvert(), EA_CHAR8("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str(typename StringType::CtorConvert(), EA_CHAR16("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str(typename StringType::CtorConvert(), EA_CHAR32("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str(typename StringType::CtorConvert(), EA_WCHAR("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - } - - // template <typename OtherCharType> - // basic_string(CtorConvert, const OtherCharType* p, size_type n, const allocator_type& allocator = EASTL_BASIC_STRING_DEFAULT_ALLOCATOR); - { - { - #if defined(EA_CHAR8) - StringType str(typename StringType::CtorConvert(), EA_CHAR8("123456789"), 4); - VERIFY(str == LITERAL("1234")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str(typename StringType::CtorConvert(), EA_CHAR16("123456789"), 4); - VERIFY(str == LITERAL("1234")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str(typename StringType::CtorConvert(), EA_CHAR32("123456789"), 4); - VERIFY(str == LITERAL("1234")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str(typename StringType::CtorConvert(), EA_WCHAR("123456789"), 4); - VERIFY(str == LITERAL("1234")); - VERIFY(str.validate()); - #endif - } - } - - // template <typename OtherStringType> - // basic_string(CtorConvert, const OtherStringType& x); - { - { - #if defined(EA_CHAR8) - StringType str(typename StringType::CtorConvert(), eastl::basic_string<char8_t, typename StringType::allocator_type>(EA_CHAR8("123456789"))); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str(typename StringType::CtorConvert(), eastl::basic_string<char16_t, typename StringType::allocator_type>(EA_CHAR16("123456789"))); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str(typename StringType::CtorConvert(), eastl::basic_string<char32_t, typename StringType::allocator_type>(EA_CHAR32("123456789"))); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str(typename StringType::CtorConvert(), eastl::basic_string<wchar_t, typename StringType::allocator_type>(EA_WCHAR("123456789"))); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - } - - // const allocator_type& get_allocator() const EA_NOEXCEPT; - // allocator_type& get_allocator() EA_NOEXCEPT; - // void set_allocator(const allocator_type& allocator); - { - } - - // this_type& operator=(const this_type& x); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str1_copy(LITERAL("")); - - VERIFY(str1_copy.empty()); - - str1_copy = str1; - - VERIFY(str1 == str1_copy); - VERIFY(!str1_copy.empty()); - VERIFY(str1.validate()); - VERIFY(str1_copy.validate()); - } - - // this_type& operator=(const value_type* p); - { - StringType str; - str = LITERAL("abcdefghijklmnopqrstuvwxyz"); - - VERIFY(str[5] == LITERAL('f')); - VERIFY(str == LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(!str.empty()); - VERIFY(str.length() == 26); - VERIFY(str.validate()); - } - - // this_type& operator=(value_type c); - { - StringType str; - str = LITERAL('a'); - - VERIFY(str == LITERAL("a")); - VERIFY(!str.empty()); - VERIFY(str.length() == 1); - VERIFY(str.size() == 1); - VERIFY(str.validate()); - } - - // this_type& operator=(std::initializer_list<value_type> ilist); - { - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - StringType str = {'a','b','c','d','e','f'}; - - VERIFY(str == LITERAL("abcdef")); - VERIFY(!str.empty()); - VERIFY(str.length() == 6); - VERIFY(str.size() == 6); - VERIFY(str.validate()); - #endif - } - - // this_type& operator=(this_type&& x); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str2 = eastl::move(str1); - - VERIFY(str1 != LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(str2 == LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str1.empty()); - VERIFY(!str2.empty()); - - VERIFY(str1.length() == 0); - VERIFY(str2.length() == 26); - - VERIFY(str1.size() == 0); - VERIFY(str2.size() == 26); - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - { - StringType str1(LITERAL("a")); - StringType str2 = eastl::move(str1); - - VERIFY(str1 != LITERAL("a")); - VERIFY(str2 == LITERAL("a")); - - VERIFY(str1.empty()); - VERIFY(!str2.empty()); - - VERIFY(str1.length() == 0); - VERIFY(str2.length() == 1); - - VERIFY(str1.size() == 0); - VERIFY(str2.size() == 1); - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - - // this_type& operator=(value_type* p); - // - // template <typename OtherCharType> - // this_type& operator=(const OtherCharType* p); - // - // template <typename OtherStringType> - // this_type& operator=(const OtherStringType& x); - { - #if EASTL_OPERATOR_EQUALS_OTHER_ENABLED - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = LITERAL("123456789"); - VERIFY(str == LITERAL("123456789"); - VERIFY(str.validate()); - } - { - { - #if defined(EA_CHAR8) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = EA_CHAR8("123456789"); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = EA_CHAR16("123456789"); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = EA_CHAR32("123456789"); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = EA_WCHAR("123456789"); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - } - { - { - #if defined(EA_CHAR8) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = eastl::basic_string<char8_t>(EA_CHAR8("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = eastl::basic_string<char16_t>(EA_CHAR16("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = eastl::basic_string<char32_t>(EA_CHAR32("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str = eastl::basic_string<wchar_t>(EA_WCHAR("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - } - #endif - } - - // void swap(this_type& x); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str2; - - str1.swap(str2); - - VERIFY(str1 != LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(str2 == LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str1.empty()); - VERIFY(!str2.empty()); - - VERIFY(str1.length() == 0); - VERIFY(str2.length() == 26); - VERIFY(str1.size() == 0); - VERIFY(str2.size() == 26); - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - - // this_type& assign(const this_type& x); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str2; - - str2.assign(str1); - - VERIFY(str1 == LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(str2 == LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(!str1.empty()); - VERIFY(!str2.empty()); - - VERIFY(str1.length() == 26); - VERIFY(str2.length() == 26); - VERIFY(str1.size() == 26); - VERIFY(str2.size() == 26); - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - - // this_type& assign(const this_type& x, size_type position, size_type n); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str2(LITERAL("123456789")); - - str1.assign(str2, 3, 3); - - VERIFY(str1 == LITERAL("456")); - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - - // this_type& assign(const value_type* p, size_type n); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign(LITERAL("123456789"), 5); - - VERIFY(str == LITERAL("12345")); - VERIFY(str.validate()); - } - - // this_type& assign(const value_type* p); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign(LITERAL("123")); - - VERIFY(str == LITERAL("123")); - VERIFY(str.validate()); - } - - // this_type& assign(size_type n, value_type c); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign(32, LITERAL('c')); - - VERIFY(str == LITERAL("cccccccccccccccccccccccccccccccc")); - VERIFY(str.validate()); - } - - // this_type& assign(const value_type* pBegin, const value_type* pEnd); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - auto* pLiteral = LITERAL("0123456789"); - auto* pBegin = pLiteral + 4; - auto* pEnd = pLiteral + 7; - - str.assign(pBegin, pEnd); - - VERIFY(str == LITERAL("456")); - VERIFY(str.validate()); - } - - // this_type& assign(this_type&& x); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str2; - - str1.assign(eastl::move(str2)); - - VERIFY(str1 != LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(str2 == LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str1.empty()); - VERIFY(!str2.empty()); - - VERIFY(str1.length() == 0); - VERIFY(str2.length() == 26); - VERIFY(str1.size() == 0); - VERIFY(str2.size() == 26); - - VERIFY(str1.validate()); - VERIFY(str2.validate()); - } - - // this_type& assign(std::initializer_list<value_type>); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign({'1','2','3'}); - - VERIFY(str == LITERAL("123")); - VERIFY(str.validate()); - } - - // template <typename OtherCharType> - // this_type& assign_convert(const OtherCharType* p); - { - { - #if defined(EA_CHAR8) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign_convert(EA_CHAR8("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign_convert(EA_CHAR16("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign_convert(EA_CHAR32("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign_convert(EA_WCHAR("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - } - - // template <typename OtherCharType> - // this_type& assign_convert(const OtherCharType* p, size_type n); - { - { - #if defined(EA_CHAR8) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign_convert(EA_CHAR8("123456789"), 3); - VERIFY(str == LITERAL("123")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign_convert(EA_CHAR16("123456789"), 3); - VERIFY(str == LITERAL("123")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign_convert(EA_CHAR32("123456789"), 3); - VERIFY(str == LITERAL("123")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.assign_convert(EA_WCHAR("123456789"), 3); - VERIFY(str == LITERAL("123")); - VERIFY(str.validate()); - #endif - } - } - - // template <typename OtherStringType> - // this_type& assign_convert(const OtherStringType& x); - { - { - #if defined(EA_CHAR8) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - eastl::basic_string<char8_t> str2(EA_CHAR8("123456789")); - - str.assign_convert(str2); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - eastl::basic_string<char16_t> str2(EA_CHAR16("123456789")); - - str.assign_convert(str2); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - eastl::basic_string<char32_t> str2(EA_CHAR32("123456789")); - - str.assign_convert(str2); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - eastl::basic_string<wchar_t> str2(EA_WCHAR("123456789")); - - str.assign_convert(str2); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - } - - // iterator begin() EA_NOEXCEPT; - // const_iterator begin() const EA_NOEXCEPT; - // const_iterator cbegin() const EA_NOEXCEPT; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - auto iBegin = str.begin(); - - VERIFY(*iBegin++ == LITERAL('a')); - VERIFY(*iBegin++ == LITERAL('b')); - VERIFY(*iBegin++ == LITERAL('c')); - VERIFY(*iBegin++ == LITERAL('d')); - VERIFY(*iBegin++ == LITERAL('e')); - VERIFY(*iBegin++ == LITERAL('f')); - VERIFY(*(str.begin() + 25) == LITERAL('z')); - - } - - // iterator end() EA_NOEXCEPT; - // const_iterator end() const EA_NOEXCEPT; - // const_iterator cend() const EA_NOEXCEPT; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - auto iEnd = str.end()-1; - - VERIFY(*iEnd-- == LITERAL('z')); - VERIFY(*iEnd-- == LITERAL('y')); - VERIFY(*iEnd-- == LITERAL('x')); - VERIFY(*iEnd-- == LITERAL('w')); - VERIFY(*iEnd-- == LITERAL('v')); - VERIFY(*iEnd-- == LITERAL('u')); - VERIFY(*(str.end() - 26) == LITERAL('a')); - } - - // reverse_iterator rbegin() EA_NOEXCEPT; - // const_reverse_iterator rbegin() const EA_NOEXCEPT; - // const_reverse_iterator crbegin() const EA_NOEXCEPT; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - auto iRBegin = str.rbegin(); - - VERIFY(*iRBegin++ == LITERAL('z')); - VERIFY(*iRBegin++ == LITERAL('y')); - VERIFY(*iRBegin++ == LITERAL('x')); - VERIFY(*iRBegin++ == LITERAL('w')); - VERIFY(*iRBegin++ == LITERAL('v')); - VERIFY(*iRBegin++ == LITERAL('u')); - VERIFY(*(str.rbegin() + 25) == LITERAL('a')); - } - - // reverse_iterator rend() EA_NOEXCEPT; - // const_reverse_iterator rend() const EA_NOEXCEPT; - // const_reverse_iterator crend() const EA_NOEXCEPT; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - auto iREnd = str.rend() - 1; - - VERIFY(*iREnd-- == LITERAL('a')); - VERIFY(*iREnd-- == LITERAL('b')); - VERIFY(*iREnd-- == LITERAL('c')); - VERIFY(*iREnd-- == LITERAL('d')); - VERIFY(*iREnd-- == LITERAL('e')); - VERIFY(*iREnd-- == LITERAL('f')); - VERIFY(*(str.rend() - 26) == LITERAL('z')); - } - - // bool empty() const EA_NOEXCEPT; - // size_type size() const EA_NOEXCEPT; - // size_type length() const EA_NOEXCEPT; - // size_type capacity() const EA_NOEXCEPT; - // void resize(size_type n, value_type c); - // void resize(size_type n); - // void set_capacity(size_type n = npos); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(!str.empty()); - VERIFY(str.size() == 26); - VERIFY(str.length() == 26); - VERIFY(str.capacity() >= 26); - - str.assign(LITERAL("")); - VERIFY(str.empty()); - VERIFY(str.size() == 0); - VERIFY(str.length() == 0); - VERIFY(str.capacity() >= 26); // should not free existing capacity - - str.resize(0); - VERIFY(str.empty()); - VERIFY(str.size() == 0); - VERIFY(str.length() == 0); - VERIFY(str.capacity() >= 26); // should not free existing capacity - - str.set_capacity(0); - // VERIFY(str.capacity() == 0); // frees existing capacity, but has a minimun of SSO capacity - - str.resize(32, LITERAL('c')); - VERIFY(!str.empty()); - VERIFY(str.size() == 32); - VERIFY(str.length() == 32); - VERIFY(str.capacity() >= 32); - VERIFY(str == LITERAL("cccccccccccccccccccccccccccccccc")); - } - - // void shrink_to_fit - { - SSOStringType str(LITERAL("a")); - str.reserve(100); - VERIFY(str.capacity() == 100); - str.shrink_to_fit(); - // string should shrink to SSO - VERIFY(str.IsSSO()); - - str = LITERAL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); // 32 characters - str.reserve(100); - VERIFY(str.capacity() == 100); - str.shrink_to_fit(); - // string should shrink but still be heap - VERIFY(str.capacity() == 32); - VERIFY(!str.IsSSO()); - } - - // void set_capacity(n) - { - const auto *pLiteral32 = LITERAL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - const auto *pLiteral31 = LITERAL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - const auto *pLiteral1 = LITERAL("a"); - const auto *pLiteral2 = LITERAL("aa"); - - SSOStringType str = pLiteral32; - // set_capacity(0) - deallocate and reset to SSO; - { - // heap -> sso - VERIFY(!str.IsSSO()); - str.set_capacity(0); - VERIFY(str.IsSSO()); - VERIFY(str == LITERAL("")); - } - { - // sso -> sso - str = pLiteral1; - VERIFY(str.IsSSO()); - str.set_capacity(0); - VERIFY(str.IsSSO()); - VERIFY(str == LITERAL("")); - } - - // set_capacity(npos) - set capacity equal to current size - should realloc - { - // heap -> heap - str = pLiteral32; - str.reserve(100); - VERIFY(!str.IsSSO()); - VERIFY(str.capacity() == 100); - str.set_capacity(StringType::npos); - VERIFY(!str.IsSSO()); - VERIFY(str.capacity() == 32); - VERIFY(str == pLiteral32); - } - { - // heap -> sso - str = pLiteral1; - str.reserve(100); - VERIFY(!str.IsSSO()); - VERIFY(str.capacity() == 100); - str.set_capacity(StringType::npos); - VERIFY(str.IsSSO()); - VERIFY(str == pLiteral1); - } - { - // sso -> sso - str = pLiteral1; - VERIFY(str.IsSSO()); - str.set_capacity(StringType::npos); - VERIFY(str.IsSSO()); - VERIFY(str == pLiteral1); - } - - // set_capacity(n > capacity) - set capacity greater than out current capacity - { - // heap -> heap - str = pLiteral32; - VERIFY(!str.IsSSO()); - auto nSavedCap = str.capacity(); - str.set_capacity(nSavedCap + 1); - VERIFY(!str.IsSSO()); - VERIFY(str == pLiteral32); - VERIFY(str.capacity() > nSavedCap); - } - { - // sso -> heap - str.set_capacity(0); // reset to sso - str = pLiteral1; - VERIFY(str.IsSSO()); - auto nSavedCap = str.capacity(); - str.set_capacity(nSavedCap + 1); - VERIFY(!str.IsSSO()); - VERIFY(str == pLiteral1); - VERIFY(str.capacity() > nSavedCap); - } - { - // sso -> sso - str.set_capacity(0); // reset to sso - str = pLiteral1; - VERIFY(str.IsSSO()); - auto nSavedCap = str.capacity(); - str.set_capacity(str.size() + 1); - VERIFY(str.IsSSO()); - VERIFY(str == pLiteral1); - VERIFY(str.capacity() == nSavedCap); - } - - // set_capacity(n < size) - set capacity less than current size, str should truncate - { - // sso -> sso - str = pLiteral2; - VERIFY(str.IsSSO()); - str.set_capacity(1); - VERIFY(str.IsSSO()); - VERIFY(str == pLiteral1); - } - { - // heap -> sso - str = pLiteral32; - VERIFY(!str.IsSSO()); - str.set_capacity(1); - VERIFY(str.IsSSO()); - VERIFY(str == pLiteral1); - } - { - // heap -> heap - str = pLiteral32; - VERIFY(!str.IsSSO()); - str.set_capacity(31); - VERIFY(!str.IsSSO()); - VERIFY(str == pLiteral31); - } - } - - // void reserve(size_type = 0); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(!str.empty()); - VERIFY(str.size() == 26); - VERIFY(str.length() == 26); - VERIFY(str.capacity() >= 26); - - // verifies that we allocate memory - str.reserve(64); - VERIFY(!str.empty()); - VERIFY(str.size() == 26); - VERIFY(str.length() == 26); - VERIFY(str.capacity() >= 64); - - // verifies that we do not free memory - str.reserve(32); - VERIFY(!str.empty()); - VERIFY(str.size() == 26); - VERIFY(str.length() == 26); - VERIFY(str.capacity() >= 64); - } - - // void force_size(size_type n); - { - // force_size does not write terminating null, meant to set size when using external - // string writing mnethods like strcpy or sprintf - StringType str(LITERAL("aaa")); - VERIFY(str.size() == 3); - str.force_size(0); - VERIFY(str.size() == 0); - str.reserve(4); // 32 bit platform with char32_t can only hold 2 characters - str.force_size(4); - VERIFY(str.size() == 4); - str[4] = '0'; - str = LITERAL("aaa"); - VERIFY(str.size() == 3); - } - - // const value_type* data() const EA_NOEXCEPT; - // const value_type* c_str() const EA_NOEXCEPT; - { - const StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - const typename StringType::value_type* pData = str.data(); - const typename StringType::value_type* pCStr = str.c_str(); - - VERIFY(pData != nullptr); - VERIFY(pCStr != nullptr); - VERIFY(pData == pCStr); - VERIFY(EA::StdC::Memcmp(pData, pCStr, str.size()) == 0); - } - - // value_type* data() EA_NOEXCEPT; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - typename StringType::value_type* pData = str.data(); - - VERIFY(pData != nullptr); - VERIFY(EA::StdC::Memcmp(pData, LITERAL("abcdefghijklmnopqrstuvwxyz"), str.size()) == 0); - } - - // reference operator[](size_type n); - // const_reference operator[](size_type n) const; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str[0] == LITERAL('a')); - VERIFY(str[14] == LITERAL('o')); - VERIFY(str[25] == LITERAL('z')); - } - - // reference at(size_type n); - // const_reference at(size_type n) const; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str.at(0) == LITERAL('a')); - VERIFY(str.at(14) == LITERAL('o')); - VERIFY(str.at(25) == LITERAL('z')); - } - - // reference front(); - // const_reference front() const; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(str.front() == LITERAL('a')); - } - - // reference back(); - // const_reference back() const; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(str.back() == LITERAL('z')); - } - - // this_type& operator+=(const this_type& x); - // this_type& operator+=(const value_type* p); - // this_type& operator+=(value_type c); - { - StringType str1(LITERAL("abcdefghijklmnopqrstuvwxyz")); - StringType str2(LITERAL("123")); - str1 += str2; - str1 += LITERAL("456"); - str1 += LITERAL('7'); - - VERIFY(str1 == LITERAL("abcdefghijklmnopqrstuvwxyz1234567")); - } - - // this_type& append(const this_type& x); - // this_type& append(const this_type& x, size_type position, size_type n); - // this_type& append(const value_type* p, size_type n); - // this_type& append(const value_type* p); - // this_type& append(size_type n, value_type c); - // this_type& append(const value_type* pBegin, const value_type* pEnd); - { - const StringType src(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - StringType str; - str.append(StringType(LITERAL("abcd"))); // "abcd" - str.append(src, 4, 4); // "abcdefgh" - str.append(src.data() + 8, 4); // "abcdefghijkl" - str.append(LITERAL("mnop")); // "abcdefghijklmnop" - str.append(1, LITERAL('q')); // "abcdefghijklmnopq" - str.append(src.data() + 17, src.data() + 26); // "abcdefghijklmnopqrstuvwxyz" - - VERIFY(str == src); - } - - // this_type& append_sprintf_va_list(const value_type* pFormat, va_list arguments); - // this_type& append_sprintf(const value_type* pFormat, ...); - { - #if EASTL_SNPRINTF_TESTS_ENABLED - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.append_sprintf(LITERAL("Hello, %d"), 42); - - VERIFY(str == LITERAL("abcdefghijklmnopqrstuvwxyzHello, 42")); - VERIFY(str.validate()); - #endif - } - - // template <typename OtherCharType> - // this_type& append_convert(const OtherCharType* p); - { - { - #if defined(EA_CHAR8) - StringType str; - str.append_convert(EA_CHAR8("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str; - str.append_convert(EA_CHAR16("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str; - str.append_convert(EA_CHAR32("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str; - str.append_convert(EA_WCHAR("123456789")); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - } - - // template <typename OtherCharType> - // this_type& append_convert(const OtherCharType* p, size_type n); - { - { - #if defined(EA_CHAR8) - StringType str; - str.append_convert(EA_CHAR8("123456789"), 5); - VERIFY(str == LITERAL("12345")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str; - str.append_convert(EA_CHAR16("123456789"), 5); - VERIFY(str == LITERAL("12345")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str; - str.append_convert(EA_CHAR32("123456789"), 5); - VERIFY(str == LITERAL("12345")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str; - str.append_convert(EA_WCHAR("123456789"), 5); - VERIFY(str == LITERAL("12345")); - VERIFY(str.validate()); - #endif - } - } - - // template <typename OtherStringType> - // this_type& append_convert(const OtherStringType& x); - { - { - #if defined(EA_CHAR8) - StringType str; - str.append_convert(eastl::u8string(EA_CHAR8("123456789"))); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR16) - StringType str; - str.append_convert(eastl::string16(EA_CHAR16("123456789"))); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_CHAR32) - StringType str; - str.append_convert(eastl::string32(EA_CHAR32("123456789"))); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - { - #if defined(EA_WCHAR) - StringType str; - str.append_convert(eastl::wstring(EA_WCHAR("123456789"))); - VERIFY(str == LITERAL("123456789")); - VERIFY(str.validate()); - #endif - } - } - - // void push_back(value_type c); - { - StringType str; - const StringType src(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - eastl::for_each(eastl::begin(src), eastl::end(src), [&str](const typename StringType::value_type& c) - { str.push_back(c); }); - - VERIFY(str == src); - VERIFY(str.validate()); - } - - // void pop_back(); - { - StringType str(LITERAL("123456789")); - VERIFY(str == LITERAL("123456789")); - - str.pop_back(); VERIFY(str == LITERAL("12345678")); - str.pop_back(); VERIFY(str == LITERAL("1234567")); - str.pop_back(); VERIFY(str == LITERAL("123456")); - str.pop_back(); VERIFY(str == LITERAL("12345")); - str.pop_back(); VERIFY(str == LITERAL("1234")); - str.pop_back(); VERIFY(str == LITERAL("123")); - str.pop_back(); VERIFY(str == LITERAL("12")); - str.pop_back(); VERIFY(str == LITERAL("1")); - str.pop_back(); VERIFY(str == LITERAL("")); - - VERIFY(str.validate()); - } - - // this_type& insert(size_type position, const this_type& x); - // this_type& insert(size_type position, const this_type& x, size_type beg, size_type n); - // this_type& insert(size_type position, const value_type* p, size_type n); - // this_type& insert(size_type position, const value_type* p); - // this_type& insert(size_type position, size_type n, value_type c); - // iterator insert(const_iterator p, value_type c); - // iterator insert(const_iterator p, size_type n, value_type c); - // iterator insert(const_iterator p, const value_type* pBegin, const value_type* pEnd); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - str.insert((typename StringType::size_type)0, (typename StringType::size_type)1, LITERAL('1')); // todo: elminiate the cast to disambiguate - VERIFY(str == LITERAL("1abcdefghijklmnopqrstuvwxyz")); - - str.insert(2, LITERAL("234")); - VERIFY(str == LITERAL("1a234bcdefghijklmnopqrstuvwxyz")); - - str.insert(15, StringType(LITERAL("567"))); - VERIFY(str == LITERAL("1a234bcdefghijk567lmnopqrstuvwxyz")); - - str.insert(30, StringType(LITERAL(" is an example of a substring")), 1, 14); - VERIFY(str == LITERAL("1a234bcdefghijk567lmnopqrstuvwis an example xyz")); - - { - StringType strSSO; - auto nSSOCap = strSSO.capacity(); - StringType strCheck; - strCheck.append(nSSOCap, LITERAL('a')); - - strSSO.append(nSSOCap - 1, LITERAL('a')); - - strSSO.insert(strSSO.size() - 1, LITERAL("a")); - VERIFY(strSSO.validate()); - VERIFY(strSSO == strCheck); - } - - { - StringType strSSO; - auto nSSOCap = strSSO.capacity(); - - // 32 bit platform with char32_t can only hold 2 characters in SSO - if (nSSOCap - 2 > 0) - { - StringType strCheck; - strCheck.append(nSSOCap, LITERAL('a')); - - strSSO.append(nSSOCap - 2, LITERAL('a')); - - strSSO.insert(strSSO.size() - 1, LITERAL("aa")); - VERIFY(strSSO.validate()); - VERIFY(strSSO == strCheck); - } - } - } - - // iterator insert(const_iterator p, std::initializer_list<value_type>); - { - #if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - StringType str; - str.insert(str.begin(), {'a','b','c'}); - str.insert(str.end(), {'d','e','f'}); - str.insert(str.begin() + 3, {'1','2','3'}); - - VERIFY(str == LITERAL("abc123def")); - VERIFY(str.validate()); - #endif - } - - // insert(const_iterator p, value_type c) - { - StringType str = LITERAL("aaa"); - auto it = str.insert(str.end(), 'b'); - VERIFY(*it == LITERAL('b')); - VERIFY(str == LITERAL("aaab")); - it = str.insert(str.begin(), 'c'); - VERIFY(*it == LITERAL('c')); - VERIFY(str == LITERAL("caaab")); - it = str.insert(str.begin() + 2, 'd'); - VERIFY(*it == LITERAL('d')); - VERIFY(str == LITERAL("cadaab")); - } - - // this_type& erase(size_type position = 0, size_type n = npos); - // iterator erase(const_iterator p); - // iterator erase(const_iterator pBegin, const_iterator pEnd); - // reverse_iterator erase(reverse_iterator position); - // reverse_iterator erase(reverse_iterator first, reverse_iterator last); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - str.erase(0,5); - VERIFY(str == LITERAL("fghijklmnopqrstuvwxyz")); - - str.erase(5,10); - VERIFY(str == LITERAL("fghijuvwxyz")); - - str.erase(str.find(LITERAL('v'))); - VERIFY(str == LITERAL("fghiju")); - - str.erase(str.find(LITERAL('g')), str.find(LITERAL('i'))); - VERIFY(str == LITERAL("fju")); - - typename StringType::const_iterator it = str.begin() + 1; // 'j' - str.erase(it); - VERIFY(str == LITERAL("fu")); - - } - - // void clear() EA_NOEXCEPT; - { - StringType str(LITERAL("123456789")); - VERIFY(str == LITERAL("123456789")); - - str.clear(); - VERIFY(str == LITERAL("")); - VERIFY(str.empty()); - VERIFY(str.validate()); - } - - - // pointer detach() EA_NOEXCEPT; - { - { - // Heap - auto* pLiteral = LITERAL("abcdefghijklmnopqrstuvwxyz"); - StringType str(pLiteral); - const auto sz = str.size() + 1; // +1 for null-terminator - - auto* pDetach = str.detach(); - - VERIFY(pDetach != nullptr); - VERIFY(EA::StdC::Strcmp(pDetach, pLiteral) == 0); - VERIFY(pDetach != pLiteral); - VERIFY(str.empty()); - VERIFY(str.size() == 0); - - str.get_allocator().deallocate(pDetach, sz); - } - - { - // SSO - auto* pLiteral = LITERAL("a"); - StringType str(pLiteral); - const auto sz = str.size() + 1; // +1 for null-terminator - - auto* pDetach = str.detach(); - - VERIFY(pDetach != nullptr); - VERIFY(EA::StdC::Strcmp(pDetach, pLiteral) == 0); - VERIFY(pDetach != pLiteral); - VERIFY(str.empty()); - VERIFY(str.size() == 0); - - str.get_allocator().deallocate(pDetach, sz); - } - - { - // SSO, empty string - auto* pLiteral = LITERAL(""); - StringType str(pLiteral); - const auto sz = str.size() + 1; // +1 for null-terminator - - auto* pDetach = str.detach(); - - VERIFY(pDetach != nullptr); - VERIFY(EA::StdC::Strcmp(pDetach, pLiteral) == 0); - VERIFY(pDetach != pLiteral); - VERIFY(str.empty()); - VERIFY(str.size() == 0); - - str.get_allocator().deallocate(pDetach, sz); - } - - { - // SSO, empty string via default ctor - StringType str; - const auto sz = str.size() + 1; // +1 for null-terminator - - auto* pDetach = str.detach(); - - VERIFY(pDetach != nullptr); - VERIFY(pDetach[0] == 0); - VERIFY(str.empty()); - VERIFY(str.size() == 0); - - str.get_allocator().deallocate(pDetach, sz); - } - } - - // this_type& replace(size_type position, size_type n, const this_type& x); - // this_type& replace(size_type pos1, size_type n1, const this_type& x, size_type pos2, size_type n2); - // this_type& replace(size_type position, size_type n1, const value_type* p, size_type n2); - // this_type& replace(size_type position, size_type n1, const value_type* p); - // this_type& replace(size_type position, size_type n1, size_type n2, value_type c); - // this_type& replace(const_iterator first, const_iterator last, const this_type& x); - // this_type& replace(const_iterator first, const_iterator last, const value_type* p, size_type n); - // this_type& replace(const_iterator first, const_iterator last, const value_type* p); - // this_type& replace(const_iterator first, const_iterator last, size_type n, value_type c); - // this_type& replace(const_iterator first, const_iterator last, const value_type* pBegin, const value_type* pEnd); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - str.replace(5, 10, StringType(LITERAL("123"))); - VERIFY(str == LITERAL("abcde123pqrstuvwxyz")); - - str.replace(13, 1, StringType(LITERAL("0123456789")), 4, 6 ); - VERIFY(str == LITERAL("abcde123pqrst456789vwxyz")); - - str.replace(24, 1, LITERAL("0123456789")); - VERIFY(str == LITERAL("abcde123pqrst456789vwxyz0123456789")); - - str.replace(16, 4, 4, LITERAL('@')); - VERIFY(str == LITERAL("abcde123pqrst456@@@@wxyz0123456789")); - } - - // size_type copy(value_type* p, size_type n, size_type position = 0) const; - { - typename StringType::value_type buf[64]; - - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.copy(buf, 10, 10); - - VERIFY(EA::StdC::Memcmp(buf, LITERAL("klmnopqrst"), 10) == 0); - } - - // size_type find(const this_type& x, size_type position = 0) const EA_NOEXCEPT; - // size_type find(const value_type* p, size_type position = 0) const; - // size_type find(const value_type* p, size_type position, size_type n) const; - // size_type find(value_type c, size_type position = 0) const EA_NOEXCEPT; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str.find(StringType(LITERAL("d"))) != StringType::npos); - VERIFY(str.find(StringType(LITERAL("tuv"))) != StringType::npos); - VERIFY(str.find(StringType(LITERAL("123r"))) == StringType::npos); - - VERIFY(str.find(LITERAL("d")) != StringType::npos); - VERIFY(str.find(LITERAL("tuv")) != StringType::npos); - VERIFY(str.find(LITERAL("123r")) == StringType::npos); - - VERIFY(str.find(LITERAL("d"), 0) != StringType::npos); - VERIFY(str.find(LITERAL("tuv"), 2) != StringType::npos); - VERIFY(str.find(LITERAL("123r"), 2) == StringType::npos); - - VERIFY(str.find(LITERAL('d'), 0) != StringType::npos); - VERIFY(str.find(LITERAL('t'), 2) != StringType::npos); - VERIFY(str.find(LITERAL('1'), 2) == StringType::npos); - } - - // size_type rfind(const this_type& x, size_type position = npos) const EA_NOEXCEPT; - // size_type rfind(const value_type* p, size_type position = npos) const; - // size_type rfind(const value_type* p, size_type position, size_type n) const; - // size_type rfind(value_type c, size_type position = npos) const EA_NOEXCEPT; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str.rfind(StringType(LITERAL("d"))) != StringType::npos); - VERIFY(str.rfind(StringType(LITERAL("tuv"))) != StringType::npos); - VERIFY(str.rfind(StringType(LITERAL("123r"))) == StringType::npos); - - VERIFY(str.rfind(LITERAL("d")) != StringType::npos); - VERIFY(str.rfind(LITERAL("tuv")) != StringType::npos); - VERIFY(str.rfind(LITERAL("123r")) == StringType::npos); - - VERIFY(str.rfind(LITERAL("d"), 20) != StringType::npos); - VERIFY(str.rfind(LITERAL("tuv"), 20) != StringType::npos); - VERIFY(str.rfind(LITERAL("123r"), 20) == StringType::npos); - - VERIFY(str.rfind(LITERAL('d'), 20) != StringType::npos); - VERIFY(str.rfind(LITERAL('t'), 20) != StringType::npos); - VERIFY(str.rfind(LITERAL('1'), 20) == StringType::npos); - } - - // size_type find_first_of(const this_type& x, size_type position = 0) const EA_NOEXCEPT; - // size_type find_first_of(const value_type* p, size_type position = 0) const; - // size_type find_first_of(const value_type* p, size_type position, size_type n) const; - // size_type find_first_of(value_type c, size_type position = 0) const EA_NOEXCEPT; - { - StringType str(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(str.find_first_of(StringType(LITERAL("aaa"))) == 0); - VERIFY(str.find_first_of(LITERAL("aab")) == 0); - VERIFY(str.find_first_of(LITERAL("baab")) == 0); - VERIFY(str.find_first_of(LITERAL("ceg")) == 10); - VERIFY(str.find_first_of(LITERAL("eeef"), 1, 2) == 18); - VERIFY(str.find_first_of(LITERAL("eeef"), 1, 4) == 18); - VERIFY(str.find_first_of(LITERAL('g')) == 26); - VERIFY(str.find_first_of(LITERAL('$')) == StringType::npos); - } - - // size_type find_last_of(const this_type& x, size_type position = npos) const EA_NOEXCEPT; - // size_type find_last_of(const value_type* p, size_type position = npos) const; - // size_type find_last_of(const value_type* p, size_type position, size_type n) const; - // size_type find_last_of(value_type c, size_type position = npos) const EA_NOEXCEPT; - { - StringType str(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(str.find_last_of(StringType(LITERAL("aaa"))) == 4); - VERIFY(str.find_last_of(LITERAL("aab")) == 9); - VERIFY(str.find_last_of(LITERAL("baab")) == 9); - VERIFY(str.find_last_of(LITERAL("ceg")) == 27); - // VERIFY(str.find_last_of(LITERAL("eeef"), 1, 2) == StringType::npos); // todo: FIX ME - // VERIFY(str.find_last_of(LITERAL("eeef"), 1, 4) == StringType::npos); // todo: FIX ME - VERIFY(str.find_last_of(LITERAL('g')) == 27); - VERIFY(str.find_last_of(LITERAL('$')) == StringType::npos); - } - - // size_type find_first_not_of(const this_type& x, size_type position = 0) const EA_NOEXCEPT; - // size_type find_first_not_of(const value_type* p, size_type position = 0) const; - // size_type find_first_not_of(const value_type* p, size_type position, size_type n) const; - // size_type find_first_not_of(value_type c, size_type position = 0) const EA_NOEXCEPT; - { - StringType str(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(str.find_first_not_of(StringType(LITERAL("abcdfg"))) == 18); - VERIFY(str.find_first_not_of(LITERAL("abcdfg")) == 18); - // VERIFY(str.find_first_not_of(LITERAL("abcdfg"), 2, 2) == 0); // todo: FIX ME - // VERIFY(str.find_first_not_of(LITERAL("abcdfg"), 0, 2) == 10); // todo: FIX ME - VERIFY(str.find_first_not_of(LITERAL('a')) == 5); - } - - // size_type find_last_not_of(const this_type& x, size_type position = npos) const EA_NOEXCEPT; - // size_type find_last_not_of(const value_type* p, size_type position = npos) const; - // size_type find_last_not_of(const value_type* p, size_type position, size_type n) const; - // size_type find_last_not_of(value_type c, size_type position = npos) const EA_NOEXCEPT; - { - StringType str(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(str.find_last_not_of(StringType(LITERAL("a"))) == 28); - VERIFY(str.find_last_not_of(StringType(LITERAL("abcdfg"))) == 28); - VERIFY(str.find_last_not_of(StringType(LITERAL("abcdfgh"))) == 22); - VERIFY(str.find_last_not_of(LITERAL("abcdfgh")) == 22); - // VERIFY(str.find_last_not_of(LITERAL("abcdfg"), 2, 2) == 0); // todo: FIX ME - // VERIFY(str.find_last_not_of(LITERAL("abcdfg"), 0, 2) == 10); // todo: FIX ME - VERIFY(str.find_last_not_of(LITERAL('a')) == 28); - } - - // this_type substr(size_type position = 0, size_type n = npos) const; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - auto substring = str.substr(0, 6); - VERIFY(substring == LITERAL("abcdef")); - - substring = str.substr(0, 0); - VERIFY(substring == LITERAL("")); - - substring = str.substr(16, 0); - VERIFY(substring == LITERAL("")); - - substring = str.substr(16, 42); - VERIFY(substring == LITERAL("qrstuvwxyz")); - } - - // int compare(const this_type& x) const EA_NOEXCEPT; - // int compare(size_type pos1, size_type n1, const this_type& x) const; - // int compare(size_type pos1, size_type n1, const this_type& x, size_type pos2, size_type n2) const; - // int compare(const value_type* p) const; - // int compare(size_type pos1, size_type n1, const value_type* p) const; - // int compare(size_type pos1, size_type n1, const value_type* p, size_type n2) const; - // static int compare(const value_type* pBegin1, const value_type* pEnd1, const value_type* pBegin2, const value_type* pEnd2); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str.compare(StringType(LITERAL("abcdefghijklmnopqrstuvwxyz"))) == 0); - VERIFY(str.compare(StringType(LITERAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) != 0); - VERIFY(str.compare(StringType(LITERAL("abcdefghijklmnopqrstuvwxyz123"))) != 0); - VERIFY(str.compare(LITERAL("abcdefghijklmnopqrstuvwxyz")) == 0); - VERIFY(str.compare(LITERAL("abcdefghijklmnopqrstuvwxyz123")) != 0); - VERIFY(str.compare(LITERAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ123")) != 0); - } - - // int comparei(const this_type& x) const EA_NOEXCEPT; - // int comparei(const value_type* p) const; - // static int comparei(const value_type* pBegin1, const value_type* pEnd1, const value_type* pBegin2, const value_type* pEnd2); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str.comparei(StringType(LITERAL("abcdefghijklmnopqrstuvwxyz"))) == 0); - VERIFY(str.comparei(StringType(LITERAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) == 0); - VERIFY(str.comparei(StringType(LITERAL("abcdefghijklmnopqrstuvwxyz123"))) != 0); - VERIFY(str.comparei(LITERAL("abcdefghijklmnopqrstuvwxyz")) == 0); - VERIFY(str.comparei(LITERAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ")) == 0); - VERIFY(str.comparei(LITERAL("abcdefghijklmnopqrstuvwxyz123")) != 0); - } - - // void make_lower(); - { - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.make_lower(); - VERIFY(str == LITERAL("abcdefghijklmnopqrstuvwxyz")); - } - { - StringType str(LITERAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); - str.make_lower(); - VERIFY(str == LITERAL("abcdefghijklmnopqrstuvwxyz")); - } - { - StringType str(LITERAL("123456789~!@#$%^&*()_+")); - str.make_lower(); - VERIFY(str == LITERAL("123456789~!@#$%^&*()_+")); - } - } - - // void make_upper(); - { - { - StringType str(LITERAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); - str.make_upper(); - VERIFY(str == LITERAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); - } - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - str.make_upper(); - VERIFY(str == LITERAL("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); - } - { - StringType str(LITERAL("123456789~!@#$%^&*()_+")); - str.make_upper(); - VERIFY(str == LITERAL("123456789~!@#$%^&*()_+")); - } - } - - // void ltrim(); - // void rtrim(); - // void trim(); - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - { - StringType rstr(LITERAL("abcdefghijklmnopqrstuvwxyz \t \t\t\t ")); - rstr.ltrim(); - VERIFY(str != rstr); - } - { - StringType lstr(LITERAL(" \t abcdefghijklmnopqrstuvwxyz")); - lstr.ltrim(); - VERIFY(str == lstr); - } - { - StringType rstr(LITERAL("abcdefghijklmnopqrstuvwxyz \t\t\t ")); - rstr.rtrim(); - VERIFY(str == rstr); - } - { - StringType lstr(LITERAL(" \t abcdefghijklmnopqrstuvwxyz")); - lstr.rtrim(); - VERIFY(str != lstr); - } - { - StringType lrstr(LITERAL(" \t abcdefghijklmnopqrstuvwxyz \t ")); - lrstr.trim(); - VERIFY(str == lrstr); - } - { - auto* pLiteral = LITERAL("abcdefghijklmn opqrstuvwxyz"); - StringType mstr(pLiteral); - mstr.trim(); - VERIFY(mstr == pLiteral); - } - } - - // void ltrim("a"); - // void rtrim("b"); - // void trim("?"); - { - StringType expected(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - { - const auto source = LITERAL("abcdefghijklmnopqrstuvwxyz "); - - StringType rstr(source); - rstr.ltrim(LITERAL(" ")); - VERIFY(rstr == source); - - rstr.rtrim(LITERAL(" ")); - VERIFY(expected == rstr); - } - - { - const auto source = LITERAL("abcdefghijklmnopqrstuvwxyz \t \t\t\t "); - - StringType rstr(source); - rstr.ltrim(LITERAL(" \t")); - VERIFY(rstr == source); - - rstr.rtrim(LITERAL(" \t")); - VERIFY(expected == rstr); - } - - { - const auto source = LITERAL(" \t \t\t\t abcdefghijklmnopqrstuvwxyz"); - - StringType rstr(source); - rstr.rtrim(LITERAL(" \t")); - VERIFY(rstr == source); - - rstr.ltrim(LITERAL(" \t")); - VERIFY(expected == rstr); - } - - { - const auto source = LITERAL("$$$%$$$$$$%$$$$$$$$$%$$$$$$$$abcdefghijklmnopqrstuvwxyz*********@*****************@******"); - StringType rstr(source); - rstr.trim(LITERAL("^(")); - VERIFY(rstr == source); - } - - { - const auto source = LITERAL("$$$%$$$$$$%$$$$$$$$$%$$$$$$$$abcdefghijklmnopqrstuvwxyz*********@*****************@******"); - StringType rstr(source); - rstr.rtrim(LITERAL("@*")); - - VERIFY(expected != rstr); - VERIFY(rstr == LITERAL("$$$%$$$$$$%$$$$$$$$$%$$$$$$$$abcdefghijklmnopqrstuvwxyz")); - - rstr.ltrim(LITERAL("$%")); - VERIFY(expected == rstr); - } - - { - const auto source = LITERAL("abcdefghijklmnopqrstuvwxyz**********************************"); - StringType rstr(source); - rstr.ltrim(LITERAL("*")); - VERIFY(expected != source); - } - - { - const auto source = LITERAL(" ? abcdefghijklmnopqrstuvwxyz**********************************"); - StringType rstr(source); - rstr.trim(LITERAL("*? ")); - VERIFY(expected != source); - } - } - - // this_type left(size_type n) const; - // this_type right(size_type n) const; - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - auto lstr = str.left(6); - VERIFY(lstr == LITERAL("abcdef")); - - auto rstr = str.right(8); - VERIFY(rstr == LITERAL("stuvwxyz")); - } - - // this_type& sprintf_va_list(const value_type* pFormat, va_list arguments); - // this_type& sprintf(const value_type* pFormat, ...); - { - #if EASTL_SNPRINTF_TESTS_ENABLED - StringType str(LITERAL("")); - - str.sprintf(LITERAL("Hello, %d"), 42); - VERIFY(str == LITERAL("Hello, 42")); - #endif - } - - // void force_size(size_type n); - { - StringType str(LITERAL("")); - str.reserve(10); - - auto p = const_cast<typename StringType::value_type*>(str.data()); - p[0] = 'a'; - p[1] = 'a'; - p[2] = 'a'; - p[3] = '\0'; - - str.force_size(3); - - VERIFY(str.size() == 3); - VERIFY(str.validate()); - VERIFY(!str.empty()); - } - - // test basic_string implicit conversion to basic_string_view - // eastl::string implicitly converts to eastl::string_view. - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - [&](basic_string_view<typename StringType::value_type> sv) // simulate api that requires eastl::string_view. - { - VERIFY(sv.compare(LITERAL("abcdefghijklmnopqrstuvwxyz")) == 0); - }(str); - } - - // test constructing a eastl::basic_string from an eastl::basic_string_view - { - using StringViewType = basic_string_view<typename StringType::value_type>; - StringViewType sv = LITERAL("abcdefghijklmnopqrstuvwxyz"); - - { - StringType str(sv); - VERIFY(str == LITERAL("abcdefghijklmnopqrstuvwxyz")); - } - - { - StringType str(sv, typename StringType::allocator_type("test")); - VERIFY(str == LITERAL("abcdefghijklmnopqrstuvwxyz")); - } - - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - VERIFY(sv == str); - } - } - - // test assigning from an eastl::basic_string_view - { - using StringViewType = basic_string_view<typename StringType::value_type>; - StringViewType sv = LITERAL("abcdefghijklmnopqrstuvwxyz"); - - { - StringType str; - str = sv; // force call to 'operator=' - VERIFY(str == LITERAL("abcdefghijklmnopqrstuvwxyz")); - } - } - - // test eastl::erase - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - auto numErased = eastl::erase(str, LITERAL('a')); - VERIFY(numErased == 1); - numErased = eastl::erase(str, LITERAL('f')); - VERIFY(numErased == 1); - numErased = eastl::erase(str, LITERAL('l')); - VERIFY(numErased == 1); - numErased = eastl::erase(str, LITERAL('w')); - VERIFY(numErased == 1); - numErased = eastl::erase(str, LITERAL('y')); - VERIFY(numErased == 1); - VERIFY(str == LITERAL("bcdeghijkmnopqrstuvxz")); - } - - // test eastl::erase_if - { - StringType str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - auto numErased = eastl::erase_if(str, [](auto c) { return c == LITERAL('a') || c == LITERAL('v'); }); - VERIFY(str == LITERAL("bcdefghijklmnopqrstuwxyz")); - VERIFY(numErased == 2); - } - - // template<> struct hash<eastl::string>; - // template<> struct hash<eastl::wstring>; - // template<> struct hash<eastl::u16string>; - // template<> struct hash<eastl::u32string>; - { - // NOTE(rparolin): This is required because the string tests inject custom allocators to assist in debugging. - // These custom string types require their own hashing specializations which we emulate by constructing a custom - // hashing functor that defers to the eastl::basic_string<CharT> hash implementation; effectively ignoring the - // custom allocator. - auto LocalHash = [](auto s) -> size_t { - using UserStringType = decltype(s); - using TargetType = eastl::basic_string<typename UserStringType::value_type>; - - TargetType t(s.data()); - return eastl::hash<TargetType>{}(t); - }; - - StringType sw1(LITERAL("Hello, World")); - StringType sw2(LITERAL("Hello, World"), 5); - StringType sw3(LITERAL("Hello")); - - VERIFY(LocalHash(sw1) != LocalHash(sw2)); - VERIFY(LocalHash(sw2) == LocalHash(sw3)); - } - - // test <=> operator - #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - StringType sw1(LITERAL("Test String ")); - StringType sw2(LITERAL("Test String 1")); - StringType sw3(LITERAL("Test String 2")); - StringType sw4(LITERAL("abcdef")); - - VERIFY((sw1 <=> sw2) != 0); - VERIFY((sw1 <=> sw3) != 0); - VERIFY((sw2 <=> sw3) != 0); - VERIFY((sw1 <=> sw2) < 0); - VERIFY((sw1 <=> sw3) < 0); - VERIFY((sw2 <=> sw2) == 0); - VERIFY((sw2 <=> sw3) < 0); - VERIFY((sw2 <=> sw4) < 0); - VERIFY((sw4 <=> sw2) > 0); - VERIFY((sw4 <=> sw3) > 0); - VERIFY((sw3 <=> sw2) > 0); - } - #endif - - return nErrorCount; -} - -// Required to prevent manual undef of macros when 'TestString.inl' preprocessed at the top of the unit test cpp file. -#undef TEST_STRING_NAME -#undef LITERAL - diff --git a/test/source/TestStringHashMap.cpp b/test/source/TestStringHashMap.cpp deleted file mode 100644 index be7e1f6..0000000 --- a/test/source/TestStringHashMap.cpp +++ /dev/null @@ -1,303 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/string_hash_map.h> -#include <EAStdC/EAString.h> - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::string_hash_map<int>; -template class eastl::string_hash_map<Align32>; - -static const char* strings[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t"}; -static const size_t kStringCount = 10; // This is intentionally half the length of strings, so that we can test with strings that are not inserted to the map. - - -int TestStringHashMap() -{ - int nErrorCount = 0; - - { // Test declarations - string_hash_map<int> stringHashMap; - - string_hash_map<int> stringHashMap2(stringHashMap); - EATEST_VERIFY(stringHashMap2.size() == stringHashMap.size()); - EATEST_VERIFY(stringHashMap2 == stringHashMap); - - - // allocator_type& get_allocator(); - // void set_allocator(const allocator_type& allocator); - string_hash_map<int>::allocator_type& allocator = stringHashMap.get_allocator(); - stringHashMap.set_allocator(EASTLAllocatorType()); - stringHashMap.set_allocator(allocator); - // To do: Try to find something better to test here. - - - // const key_equal& key_eq() const; - // key_equal& key_eq(); - string_hash_map<int> hs; - const string_hash_map<int> hsc; - - const string_hash_map<int>::key_equal& ke = hsc.key_eq(); - hs.key_eq() = ke; - - - // const char* get_name() const; - // void set_name(const char* pName); - #if EASTL_NAME_ENABLED - stringHashMap.get_allocator().set_name("test"); - const char* pName = stringHashMap.get_allocator().get_name(); - EATEST_VERIFY(equal(pName, pName + 5, "test")); - #endif - } - - - { - string_hash_map<int> stringHashMap; - - // Clear a newly constructed, already empty container. - stringHashMap.clear(true); - EATEST_VERIFY(stringHashMap.validate()); - EATEST_VERIFY(stringHashMap.size() == 0); - EATEST_VERIFY(stringHashMap.bucket_count() == 1); - - for (int i = 0; i < (int)kStringCount; i++) - stringHashMap.insert(strings[i], i); - - EATEST_VERIFY(stringHashMap.validate()); - EATEST_VERIFY(stringHashMap.size() == kStringCount); - - stringHashMap.clear(true); - EATEST_VERIFY(stringHashMap.validate()); - EATEST_VERIFY(stringHashMap.size() == 0); - EATEST_VERIFY(stringHashMap.bucket_count() == 1); - - for (int i = 0; i < (int)kStringCount; i++) - stringHashMap.insert(strings[i], i); - EATEST_VERIFY(stringHashMap.validate()); - EATEST_VERIFY(stringHashMap.size() == kStringCount); - - stringHashMap.clear(true); - EATEST_VERIFY(stringHashMap.validate()); - EATEST_VERIFY(stringHashMap.size() == 0); - EATEST_VERIFY(stringHashMap.bucket_count() == 1); - } - - - { // Test string_hash_map - - // size_type size() const - // bool empty() const - // insert_return_type insert(const value_type& value); - // insert_return_type insert(const value_type& value, hash_code_t c, node_type* pNodeNew = NULL); - // iterator insert(const_iterator, const value_type& value); - // iterator find(const key_type& k); - // const_iterator find(const key_type& k) const; - // size_type count(const key_type& k) const; - - typedef string_hash_map<int> StringHashMapInt; - - StringHashMapInt stringHashMap; - - EATEST_VERIFY(stringHashMap.empty()); - EATEST_VERIFY(stringHashMap.size() == 0); - EATEST_VERIFY(stringHashMap.count(strings[0]) == 0); - - for (int i = 0; i < (int)kStringCount; i++) - stringHashMap.insert(strings[i], i); - - EATEST_VERIFY(!stringHashMap.empty()); - EATEST_VERIFY(stringHashMap.size() == kStringCount); - EATEST_VERIFY(stringHashMap.count(strings[0]) == 1); - - int j = 0; - for (StringHashMapInt::iterator it = stringHashMap.begin(); it != stringHashMap.end(); ++it, ++j) - { - int value = (*it).second; - EATEST_VERIFY(value < (int)kStringCount); - } - - for(int i = 0; i < (int)kStringCount * 2; i++) - { - StringHashMapInt::iterator it = stringHashMap.find(strings[i]); - - if (i < (int)kStringCount) - { - EATEST_VERIFY(it != stringHashMap.end()); - const char* k = it->first; - int v = it->second; - EATEST_VERIFY(EA::StdC::Strcmp(k, strings[i]) == 0); - EATEST_VERIFY(v == i); - } - else - EATEST_VERIFY(it == stringHashMap.end()); - } - - StringHashMapInt::insert_return_type result = stringHashMap.insert("EASTLTEST"); - EATEST_VERIFY(result.second == true); - result = stringHashMap.insert("EASTLTEST"); - EATEST_VERIFY(result.second == false); - result.first->second = 0; - - // iterator erase(const_iterator); - size_t nExpectedSize = stringHashMap.size(); - - StringHashMapInt::iterator itD = stringHashMap.find("d"); - EATEST_VERIFY(itD != stringHashMap.end()); - - // erase the element and verify that the size has decreased - stringHashMap.erase(itD); - nExpectedSize--; - EATEST_VERIFY(stringHashMap.size() == nExpectedSize); - - // verify that erased element is gone - itD = stringHashMap.find(strings[3]); - EATEST_VERIFY(itD == stringHashMap.end()); - - // iterator erase(const char*) - StringHashMapInt::size_type n = stringHashMap.erase(strings[4]); - nExpectedSize--; - EATEST_VERIFY(n == 1); - EATEST_VERIFY(stringHashMap.size() == nExpectedSize); - - - // mapped_type& operator[](const key_type& key) - stringHashMap.clear(); - - int x = stringHashMap["A"]; // A default-constructed int (i.e. 0) should be returned. - EATEST_VERIFY(x == 0); - - stringHashMap["B"] = 1; - x = stringHashMap["B"]; - EATEST_VERIFY(x == 1); // Verify that the value we assigned is returned and a default-constructed value is not returned. - - stringHashMap["A"] = 10; // Overwrite our previous 0 with 10. - stringHashMap["B"] = 11; - x = stringHashMap["A"]; - EATEST_VERIFY(x == 10); // Verify the value is as expected. - x = stringHashMap["B"]; - EATEST_VERIFY(x == 11); - - } - - - { - // string_hash_map(const allocator_type& allocator); - // string_hash_map& operator=(const this_type& x); - // bool validate() const; - - string_hash_map<int> stringHashMap1(EASTLAllocatorType("TestStringHashMap")); - string_hash_map<int> stringHashMap2(stringHashMap1); - - for (int i = 0; i < (int)kStringCount; i++) - { - stringHashMap1.insert(strings[i], i); - } - - stringHashMap2 = stringHashMap1; - string_hash_map<int> stringHashMap3(stringHashMap1); - - EATEST_VERIFY(stringHashMap1.validate()); - EATEST_VERIFY(stringHashMap2.validate()); - EATEST_VERIFY(stringHashMap3.validate()); - - for (int i = 0; i < (int)kStringCount; i++) - { - EATEST_VERIFY(stringHashMap1[strings[i]] == stringHashMap2[strings[i]]); - EATEST_VERIFY(stringHashMap1[strings[i]] == stringHashMap3[strings[i]]); - } - - } - - // pair<iterator, bool> insert_or_assign(const char* key, const T& value); - { - { - string_hash_map<int> m; - - m.insert_or_assign("hello", 0); - EATEST_VERIFY(m["hello"] == 0); - - m.insert_or_assign("hello", 42); - EATEST_VERIFY(m["hello"] == 42); - - m.insert_or_assign("hello", 43); - EATEST_VERIFY(m["hello"] == 43); - - m.insert_or_assign("hello", 1143); - EATEST_VERIFY(m["hello"] == 1143); - - EATEST_VERIFY(m.size() == 1); - m.clear(); - EATEST_VERIFY(m.size() == 0); - } - - { - string_hash_map<int> m; - m.insert_or_assign("hello", 0); - m.insert_or_assign("hello2", 0); - - EATEST_VERIFY(m.size() == 2); - m.clear(); - EATEST_VERIFY(m.size() == 0); - } - - { - string_hash_map<int> m; - m.insert_or_assign("hello", 0); - m.insert_or_assign("hello2", 0); - - EATEST_VERIFY(m.size() == 2); - m.clear(true); - EATEST_VERIFY(m.size() == 0); - } - - { - string_hash_map<int> m; - m.insert_or_assign("hello", 0); - m.insert_or_assign("hello2", 0); - - EATEST_VERIFY(m.size() == 2); - m.clear(false); - EATEST_VERIFY(m.size() == 0); - } - - { - string_hash_map<TestObject> m; - - m.insert_or_assign("hello", TestObject(42)); - EATEST_VERIFY(m["hello"].mX == 42); - - m.insert_or_assign("hello", TestObject(43)); - EATEST_VERIFY(m["hello"].mX == 43); - - EATEST_VERIFY(m.size() == 1); - } - - { - typedef string_hash_map<TestObject, hash<const char*>, str_equal_to<const char*>, CountingAllocator> counting_string_hash_map; - counting_string_hash_map m; - EATEST_VERIFY(CountingAllocator::getActiveAllocationCount() == 0); - - m.insert_or_assign("hello", TestObject(42)); - EATEST_VERIFY(CountingAllocator::getActiveAllocationCount() == 3); - EATEST_VERIFY(m["hello"].mX == 42); - EATEST_VERIFY(CountingAllocator::getActiveAllocationCount() == 3); - - m.insert_or_assign("hello", TestObject(43)); - EATEST_VERIFY(CountingAllocator::getActiveAllocationCount() == 3); - EATEST_VERIFY(m["hello"].mX == 43); - EATEST_VERIFY(CountingAllocator::getActiveAllocationCount() == 3); - - EATEST_VERIFY(m.size() == 1); - } - EATEST_VERIFY(CountingAllocator::getActiveAllocationCount() == 0); - } - - return nErrorCount; -} diff --git a/test/source/TestStringMap.cpp b/test/source/TestStringMap.cpp deleted file mode 100644 index 4499fa9..0000000 --- a/test/source/TestStringMap.cpp +++ /dev/null @@ -1,207 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/string_map.h> -#include <EAStdC/EAString.h> - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::string_map<int>; -template class eastl::string_map<Align32>; - -static const char* strings[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t" }; -static const size_t kStringCount = 10; // This is intentionally half the length of strings, so that we can test with strings that are not inserted to the map. - - -int TestStringMap() -{ - int nErrorCount = 0; - - { // Test declarations - string_map<int> stringMap; - - string_map<int> stringMap2(stringMap); - EATEST_VERIFY(stringMap2.size() == stringMap.size()); - EATEST_VERIFY(stringMap2 == stringMap); - - - // allocator_type& get_allocator(); - // void set_allocator(const allocator_type& allocator); - string_map<int>::allocator_type& allocator = stringMap.get_allocator(); - stringMap.set_allocator(EASTLAllocatorType()); - stringMap.set_allocator(allocator); - // To do: Try to find something better to test here. - - - // const char* get_name() const; - // void set_name(const char* pName); -#if EASTL_NAME_ENABLED - stringMap.get_allocator().set_name("test"); - const char* pName = stringMap.get_allocator().get_name(); - EATEST_VERIFY(equal(pName, pName + 5, "test")); -#endif - } - - - { - string_map<int> stringMap; - - // Clear a newly constructed, already empty container. - stringMap.clear(); - EATEST_VERIFY(stringMap.validate()); - EATEST_VERIFY(stringMap.size() == 0); - - for (int i = 0; i < (int)kStringCount; i++) - stringMap.insert(strings[i], i); - - EATEST_VERIFY(stringMap.validate()); - EATEST_VERIFY(stringMap.size() == kStringCount); - - stringMap.clear(); - EATEST_VERIFY(stringMap.validate()); - EATEST_VERIFY(stringMap.size() == 0); - - for (int i = 0; i < (int)kStringCount; i++) - stringMap.insert(strings[i], i); - EATEST_VERIFY(stringMap.validate()); - EATEST_VERIFY(stringMap.size() == kStringCount); - - stringMap.clear(); - EATEST_VERIFY(stringMap.validate()); - EATEST_VERIFY(stringMap.size() == 0); - } - - - { // Test string_map - - // size_type size() const - // bool empty() const - // insert_return_type insert(const value_type& value); - // insert_return_type insert(const value_type& value, hash_code_t c, node_type* pNodeNew = NULL); - // iterator insert(const_iterator, const value_type& value); - // iterator find(const key_type& k); - // const_iterator find(const key_type& k) const; - // size_type count(const key_type& k) const; - - typedef string_map<int> StringMapInt; - - StringMapInt stringMap; - - EATEST_VERIFY(stringMap.empty()); - EATEST_VERIFY(stringMap.size() == 0); - EATEST_VERIFY(stringMap.count(strings[0]) == 0); - - for (int i = 0; i < (int)kStringCount; i++) - stringMap.insert(strings[i], i); - - EATEST_VERIFY(!stringMap.empty()); - EATEST_VERIFY(stringMap.size() == kStringCount); - EATEST_VERIFY(stringMap.count(strings[0]) == 1); - - int j = 0; - for (StringMapInt::iterator it = stringMap.begin(); it != stringMap.end(); ++it, ++j) - { - int value = (*it).second; - EATEST_VERIFY(value < (int)kStringCount); - } - - for (int i = 0; i < (int)kStringCount * 2; i++) - { - StringMapInt::iterator it = stringMap.find(strings[i]); - - if (i < (int)kStringCount) - { - EATEST_VERIFY(it != stringMap.end()); - const char* k = (*it).first; - int v = (*it).second; - EATEST_VERIFY(EA::StdC::Strcmp(k, strings[i]) == 0); - EATEST_VERIFY(v == i); - } - else - EATEST_VERIFY(it == stringMap.end()); - } - - StringMapInt::insert_return_type result = stringMap.insert("EASTLTEST"); - EATEST_VERIFY(result.second == true); - result = stringMap.insert("EASTLTEST"); - EATEST_VERIFY(result.second == false); - result.first->second = 0; - - // iterator erase(const_iterator); - size_t nExpectedSize = stringMap.size(); - - StringMapInt::iterator itD = stringMap.find("d"); - EATEST_VERIFY(itD != stringMap.end()); - - // erase the element and verify that the size has decreased - stringMap.erase(itD); - nExpectedSize--; - EATEST_VERIFY(stringMap.size() == nExpectedSize); - - // verify that erased element is gone - itD = stringMap.find(strings[3]); - EATEST_VERIFY(itD == stringMap.end()); - - // iterator erase(const char*) - StringMapInt::size_type n = stringMap.erase(strings[4]); - nExpectedSize--; - EATEST_VERIFY(n == 1); - EATEST_VERIFY(stringMap.size() == nExpectedSize); - - - // mapped_type& operator[](const key_type& key) - stringMap.clear(); - - int x = stringMap["A"]; // A default-constructed int (i.e. 0) should be returned. - EATEST_VERIFY(x == 0); - - stringMap["B"] = 1; - x = stringMap["B"]; - EATEST_VERIFY(x == 1); // Verify that the value we assigned is returned and a default-constructed value is not returned. - - stringMap["A"] = 10; // Overwrite our previous 0 with 10. - stringMap["B"] = 11; - x = stringMap["A"]; - EATEST_VERIFY(x == 10); // Verify the value is as expected. - x = stringMap["B"]; - EATEST_VERIFY(x == 11); - - } - - - { - // string_map(const allocator_type& allocator); - // string_map& operator=(const this_type& x); - // bool validate() const; - - string_map<int> stringMap1(EASTLAllocatorType("TestStringMap")); - string_map<int> stringMap2(stringMap1); - - for (int i = 0; i < (int)kStringCount; i++) - { - stringMap1.insert(strings[i], i); - } - - stringMap2 = stringMap1; - string_map<int> stringMap3(stringMap1); - - EATEST_VERIFY(stringMap1.validate()); - EATEST_VERIFY(stringMap2.validate()); - EATEST_VERIFY(stringMap3.validate()); - - for (int i = 0; i < (int)kStringCount; i++) - { - EATEST_VERIFY(stringMap1[strings[i]] == stringMap2[strings[i]]); - EATEST_VERIFY(stringMap1[strings[i]] == stringMap3[strings[i]]); - } - - } - - return nErrorCount; -} diff --git a/test/source/TestStringView.cpp b/test/source/TestStringView.cpp deleted file mode 100644 index 23e6e51..0000000 --- a/test/source/TestStringView.cpp +++ /dev/null @@ -1,115 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EABase/eabase.h> -#include <EASTL/numeric_limits.h> -#include <EASTL/string.h> -#include <EASTL/string_view.h> - -// Verify char8_t support is present if the test build requested it. -#if defined(EASTL_EXPECT_CHAR8T_SUPPORT) && !EA_CHAR8_UNIQUE -static_assert(false, "Building with char8_t tests enabled, but EA_CHAR8_UNIQUE evaluates to false."); -#endif - -// this mess is required inorder to inject string literal string conversion macros into the unit tests -#define TEST_STRING_NAME TestBasicStringView -#define LITERAL(x) x -#include "TestStringView.inl" - -#define TEST_STRING_NAME TestBasicStringViewW -#define LITERAL(x) EA_WCHAR(x) -#include "TestStringView.inl" - -#define TEST_STRING_NAME TestBasicStringView8 -#define LITERAL(x) EA_CHAR8(x) -#include "TestStringView.inl" - -#define TEST_STRING_NAME TestBasicStringView16 -#define LITERAL(x) EA_CHAR16(x) -#include "TestStringView.inl" - -#define TEST_STRING_NAME TestBasicStringView32 -#define LITERAL(x) EA_CHAR32(x) -#include "TestStringView.inl" - - -int TestStringView() -{ - using namespace eastl; - int nErrorCount = 0; - - nErrorCount += TestBasicStringView<eastl::basic_string_view<char>>(); - nErrorCount += TestBasicStringView<eastl::string_view>(); - - nErrorCount += TestBasicStringViewW<eastl::basic_string_view<wchar_t>>(); - nErrorCount += TestBasicStringViewW<eastl::wstring_view>(); - -#if EA_CHAR8_UNIQUE - nErrorCount += TestBasicStringView8<eastl::basic_string_view<char8_t>>(); - nErrorCount += TestBasicStringView8<eastl::u8string_view>(); -#endif - - nErrorCount += TestBasicStringView16<eastl::basic_string_view<char16_t>>(); - nErrorCount += TestBasicStringView16<eastl::u16string_view>(); - -#if EA_CHAR32_NATIVE - nErrorCount += TestBasicStringView32<eastl::basic_string_view<char32_t>>(); - nErrorCount += TestBasicStringView32<eastl::u32string_view>(); -#endif - - - // constexpr string_view operator "" sv(const char* str, size_t len) noexcept; - // constexpr u8string_view operator "" sv(const char8_t* str, size_t len) noexcept; - // constexpr u16string_view operator "" sv(const char16_t* str, size_t len) noexcept; - // constexpr u32string_view operator "" sv(const char32_t* str, size_t len) noexcept; - // constexpr wstring_view operator "" sv(const wchar_t* str, size_t len) noexcept; - #if EASTL_USER_LITERALS_ENABLED - { - VERIFY("cplusplus"_sv.compare("cplusplus") == 0); - VERIFY(L"cplusplus"_sv.compare(L"cplusplus") == 0); - VERIFY(u"cplusplus"_sv.compare(u"cplusplus") == 0); - VERIFY(U"cplusplus"_sv.compare(U"cplusplus") == 0); - VERIFY(u8"cplusplus"_sv.compare(u8"cplusplus") == 0); - - static_assert(eastl::is_same_v<decltype("abcdef"_sv), eastl::string_view>, "string_view literal type mismatch"); - static_assert(eastl::is_same_v<decltype(u8"abcdef"_sv), eastl::u8string_view>, "string_view literal type mismatch"); - static_assert(eastl::is_same_v<decltype(u"abcdef"_sv), eastl::u16string_view>, "string_view literal type mismatch"); - static_assert(eastl::is_same_v<decltype(U"abcdef"_sv), eastl::u32string_view>, "string_view literal type mismatch"); - static_assert(eastl::is_same_v<decltype(L"abcdef"_sv), eastl::wstring_view>, "string_view literal type mismatch"); - - - VERIFY("cplusplus"sv.compare("cplusplus") == 0); - VERIFY(L"cplusplus"sv.compare(L"cplusplus") == 0); - VERIFY(u"cplusplus"sv.compare(u"cplusplus") == 0); - VERIFY(U"cplusplus"sv.compare(U"cplusplus") == 0); - VERIFY(u8"cplusplus"sv.compare(u8"cplusplus") == 0); - - static_assert(eastl::is_same_v<decltype("abcdef"sv), eastl::string_view>, "string_view literal type mismatch"); - static_assert(eastl::is_same_v<decltype(u8"abcdef"sv), eastl::u8string_view>, "string_view literal type mismatch"); - static_assert(eastl::is_same_v<decltype(u"abcdef"sv), eastl::u16string_view>, "string_view literal type mismatch"); - static_assert(eastl::is_same_v<decltype(U"abcdef"sv), eastl::u32string_view>, "string_view literal type mismatch"); - static_assert(eastl::is_same_v<decltype(L"abcdef"sv), eastl::wstring_view>, "string_view literal type mismatch"); - } - #endif - - - // strlen(char_t) compatibility - { - auto* pStr = "Hello, World"; - string_view sw(pStr, strlen(pStr)); - VERIFY(sw.size() == strlen(pStr)); - } - - // strlen(wchar_t) compatibility - { - auto* pStr = L"Hello, World"; - wstring_view sw(pStr, wcslen(pStr)); - VERIFY(sw.size() == wcslen(pStr)); - } - - - return nErrorCount; -} - diff --git a/test/source/TestStringView.inl b/test/source/TestStringView.inl deleted file mode 100644 index cd4214e..0000000 --- a/test/source/TestStringView.inl +++ /dev/null @@ -1,599 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -template<typename StringViewT> -int TEST_STRING_NAME() -{ - using StringT = eastl::basic_string<typename StringViewT::value_type>; - - int nErrorCount = 0; - { - // EA_CONSTEXPR basic_string_view() - { - StringViewT sw; - VERIFY(sw.empty()); - VERIFY(sw.data() == nullptr); - VERIFY(sw.size() == 0); - VERIFY(sw.size() == sw.length()); - } - - // User-reported regression: constructing string_view from a nullptr, NULL, 0 - { - { - StringViewT sw(nullptr); - VERIFY(sw.empty()); - VERIFY(sw.data() == nullptr); - VERIFY(sw.size() == 0); - VERIFY(sw.size() == sw.length()); - } - { - StringViewT sw(0); - VERIFY(sw.empty()); - VERIFY(sw.data() == nullptr); - VERIFY(sw.size() == 0); - VERIFY(sw.size() == sw.length()); - } - { - StringViewT sw(NULL); - VERIFY(sw.empty()); - VERIFY(sw.data() == nullptr); - VERIFY(sw.size() == 0); - VERIFY(sw.size() == sw.length()); - } - } - - // EA_CONSTEXPR basic_string_view(const basic_string_view& other) = default; - { - auto* pLiteral = LITERAL("Hello, World"); - StringViewT sw1(pLiteral); - StringViewT sw2(sw1); - VERIFY(sw1.size() == sw2.size()); - VERIFY(eastl::Compare(sw1.data(), sw2.data(), sw1.size()) == 0); - } - - // EA_CONSTEXPR basic_string_view(const T* s, size_type count) - { - { - StringViewT sw(LITERAL("Hello, World"), 12); - VERIFY(!sw.empty()); - VERIFY(sw.data() != nullptr); - VERIFY(sw.size() == 12); - VERIFY(sw.size() == sw.length()); - } - - { - StringViewT sw(LITERAL("Hello, World"), 5); - VERIFY(!sw.empty()); - VERIFY(sw.data() != nullptr); - VERIFY(sw.size() == 5); - VERIFY(sw.size() == sw.length()); - VERIFY(eastl::Compare(sw.data(), LITERAL("Hello"), sw.size()) == 0); - } - } - - // EA_CONSTEXPR basic_string_view(const T* s) - { - auto* pLiteral = LITERAL("Vancouver, Canada"); - StringViewT sw(pLiteral); - VERIFY(!sw.empty()); - VERIFY(sw.data() != nullptr); - VERIFY(sw.size() == 17); - VERIFY(sw.size() == sw.length()); - VERIFY(eastl::Compare(sw.data(), pLiteral, sw.size()) == 0); - } - - // basic_string_view& operator=(const basic_string_view& view) = default; - { - auto* pLiteral = LITERAL("Hello, World"); - StringViewT sw1(pLiteral); - StringViewT sw2; - VERIFY(!sw1.empty()); - VERIFY(sw2.empty()); - - sw2 = sw1; - - VERIFY(!sw1.empty()); - VERIFY(!sw2.empty()); - VERIFY(sw1.size() == sw2.size()); - VERIFY(eastl::Compare(sw1.data(), pLiteral, sw1.size()) == 0); - VERIFY(eastl::Compare(sw2.data(), pLiteral, sw2.size()) == 0); - } - - { - // EA_CONSTEXPR const_iterator begin() const EA_NOEXCEPT - // EA_CONSTEXPR const_iterator cbegin() const EA_NOEXCEPT - StringViewT sw(LITERAL("abcdefg")); - { - auto i = sw.begin(); - auto ci = sw.cbegin(); - - VERIFY(*i++ == LITERAL('a')); - VERIFY(*i++ == LITERAL('b')); - - VERIFY(*ci++ == LITERAL('a')); - VERIFY(*ci++ == LITERAL('b')); - } - - // EA_CONSTEXPR const_iterator end() const EA_NOEXCEPT - // EA_CONSTEXPR const_iterator cend() const EA_NOEXCEPT - { - auto i = sw.end(); - auto ci = sw.cend(); - - VERIFY(*i-- == LITERAL('\0')); - VERIFY(*i-- == LITERAL('g')); - - VERIFY(*ci-- == LITERAL('\0')); - VERIFY(*ci-- == LITERAL('g')); - } - - // EA_CONSTEXPR const_reverse_iterator rbegin() const EA_NOEXCEPT - // EA_CONSTEXPR const_reverse_iterator crbegin() const EA_NOEXCEPT - { - auto i = sw.rbegin(); - auto ci = sw.crbegin(); - - VERIFY(*i++ == LITERAL('g')); - VERIFY(*i++ == LITERAL('f')); - - VERIFY(*ci++ == LITERAL('g')); - VERIFY(*ci++ == LITERAL('f')); - } - - // EA_CONSTEXPR const_reverse_iterator rend() const EA_NOEXCEPT - // EA_CONSTEXPR const_reverse_iterator crend() const EA_NOEXCEPT - { - auto i = sw.rend(); - i--; - - auto ci = sw.crend(); - ci--; - - VERIFY(*i-- == LITERAL('a')); - VERIFY(*i-- == LITERAL('b')); - - VERIFY(*ci-- == LITERAL('a')); - VERIFY(*ci-- == LITERAL('b')); - } - } - - // EA_CONSTEXPR const_pointer data() const - { - auto* pLiteral = LITERAL("Vancouver, Canada"); - StringViewT sw(pLiteral); - VERIFY(sw.data() != nullptr); - VERIFY(eastl::Compare(sw.data(), pLiteral, sw.size()) == 0); - VERIFY(eastl::Compare(sw.data() + 11, LITERAL("Canada"), 6) == 0); - } - - // EA_CONSTEXPR const_reference front() const - // EA_CONSTEXPR const_reference back() const - { - { - StringViewT sw(LITERAL("Vancouver, Canada")); - VERIFY(sw.front() == LITERAL('V')); - VERIFY(sw.back() == LITERAL('a')); - - } - { - StringViewT sw(LITERAL("Canada")); - VERIFY(sw.front() == LITERAL('C')); - VERIFY(sw.back() == LITERAL('a')); - } - } - - // EA_CONSTEXPR const_reference operator[](size_type pos) const - { - StringViewT sw(LITERAL("Vancouver")); - VERIFY(sw[0] == LITERAL('V')); - VERIFY(sw[1] == LITERAL('a')); - VERIFY(sw[2] == LITERAL('n')); - VERIFY(sw[3] == LITERAL('c')); - VERIFY(sw[4] == LITERAL('o')); - VERIFY(sw[5] == LITERAL('u')); - VERIFY(sw[6] == LITERAL('v')); - VERIFY(sw[7] == LITERAL('e')); - VERIFY(sw[8] == LITERAL('r')); - } - - // EA_CONSTEXPR size_type size() const EA_NOEXCEPT - // EA_CONSTEXPR size_type length() const EA_NOEXCEPT - // EA_CONSTEXPR size_type max_size() const EA_NOEXCEPT - // EA_CONSTEXPR bool empty() const EA_NOEXCEPT - { - StringViewT sw(LITERAL("http://en.cppreference.com/w/cpp/header/string_view")); - VERIFY(sw.size() == 51); - VERIFY(sw.length() == 51); - VERIFY(sw.max_size() == eastl::numeric_limits<typename StringViewT::size_type>::max()); - VERIFY(!sw.empty()); - } - - // EA_CONSTEXPR void swap(basic_string_view& v) - { - auto* pV = LITERAL("Vancouver"); - auto* pC = LITERAL("Canada"); - StringViewT sw1(pV); - StringViewT sw2(pC); - sw1.swap(sw2); - VERIFY(eastl::Compare(sw1.data(), pC, sw1.size()) == 0); - VERIFY(eastl::Compare(sw2.data(), pV, sw2.size()) == 0); - } - - // EA_CONSTEXPR void remove_prefix(size_type n) - // EA_CONSTEXPR void remove_suffix(size_type n) - { - StringViewT sw(LITERAL("Vancouver")); - sw.remove_prefix(3); - VERIFY(eastl::Compare(sw.data(), LITERAL("couver"), sw.size()) == 0); - VERIFY(sw.size() == 6); - - sw.remove_prefix(3); - VERIFY(eastl::Compare(sw.data(), LITERAL("ver"), sw.size()) == 0); - VERIFY(sw.size() == 3); - - sw.remove_suffix(1); - VERIFY(eastl::Compare(sw.data(), LITERAL("ve"), sw.size()) == 0); - VERIFY(sw.size() == 2); - - sw.remove_suffix(1); - VERIFY(eastl::Compare(sw.data(), LITERAL("v"), sw.size()) == 0); - VERIFY(sw.size() == 1); - - sw.remove_suffix(1); - VERIFY(eastl::Compare(sw.data(), LITERAL(""), sw.size()) == 0); - VERIFY(sw.size() == 0); - } - - // size_type copy(T* s, size_type n, size_type pos = 0) const; - { - typename StringViewT::value_type buf[256]; - StringViewT sw(LITERAL("**Hello, World")); - auto cnt = sw.copy(buf, 5, 2); - VERIFY(eastl::Compare(buf, LITERAL("Hello"), 5) == 0); - VERIFY(cnt == 5); - } - - // EA_CONSTEXPR basic_string_view substr(size_type pos = 0, size_type n = npos) const; - { - StringViewT sw(LITERAL("**Hello, World")); - auto sw2 = sw.substr(2, 5); - VERIFY(eastl::Compare(sw2.data(), LITERAL("Hello"), sw2.size()) == 0); - } - - // EA_CONSTEXPR int compare(basic_string_view s) const EA_NOEXCEPT; - { - { - VERIFY(StringViewT(LITERAL("A")).compare(StringViewT(LITERAL("A"))) == 0); - VERIFY(StringViewT(LITERAL("a")).compare(StringViewT(LITERAL("a"))) == 0); - VERIFY(StringViewT(LITERAL("A")).compare(StringViewT(LITERAL("a"))) != 0); - VERIFY(StringViewT(LITERAL("A")).compare(StringViewT(LITERAL("a"))) < 0); - VERIFY(StringViewT(LITERAL("A")).compare(StringViewT(LITERAL("A"))) <= 0); - VERIFY(StringViewT(LITERAL("a")).compare(StringViewT(LITERAL("A"))) > 0); - VERIFY(StringViewT(LITERAL("A")).compare(StringViewT(LITERAL("A"))) >= 0); - } - - { - VERIFY(StringViewT(LITERAL("Aa")).compare(StringViewT(LITERAL("A"))) > 0); - VERIFY(StringViewT(LITERAL("A")).compare(StringViewT(LITERAL("Aa"))) < 0); - } - - { - StringViewT sw1(LITERAL("Hello, World")); - StringViewT sw2(LITERAL("Hello, WWorld")); - StringViewT sw3(LITERAL("Hello, Wzorld")); - VERIFY(sw1.compare(sw1) == 0); - VERIFY(sw1.compare(sw2) > 0); - VERIFY(sw1.compare(sw3) < 0); - } - } - - // EA_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view s) const; - { - StringViewT sw1(LITERAL("*** Hello ***")); - StringViewT sw2(LITERAL("Hello")); - VERIFY(sw1.compare(4, 5, sw2) == 0); - } - - // EA_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view s, size_type pos2, size_type n2) const; - { - StringViewT sw(LITERAL("Vancouver")); - VERIFY(sw.compare(0, 3, StringViewT(LITERAL("Van")), 0, 3) == 0); - VERIFY(sw.compare(6, 3, StringViewT(LITERAL("ver")), 0, 3) == 0); - VERIFY(sw.compare(0, 3, StringViewT(LITERAL("Tan")), 0, 3) != 0); - } - - // EA_CONSTEXPR int compare(const T* s) const; - { - StringViewT sw(LITERAL("Hello")); - VERIFY(sw.compare(LITERAL("Vancouver")) != 0); - VERIFY(sw.compare(LITERAL("Vancouver!")) != 0); - VERIFY(sw.compare(LITERAL("Hello")) == 0); - } - - // EA_CONSTEXPR int compare(size_type pos1, size_type n1, const T* s) const; - { - StringViewT sw(LITERAL("*** Hello")); - VERIFY(sw.compare(4, 5, LITERAL("Hello")) == 0); - VERIFY(sw.compare(4, 5, LITERAL("Hello 555")) != 0); - VERIFY(sw.compare(4, 5, LITERAL("hello")) != 0); - } - - // EA_CONSTEXPR int compare(size_type pos1, size_type n1, const T* s, size_type n2) const; - { - StringViewT sw(LITERAL("*** Hello ***")); - VERIFY(sw.compare(4, 5, LITERAL("Hello"), 5) == 0); - VERIFY(sw.compare(0, 1, LITERAL("*"), 1) == 0); - VERIFY(sw.compare(0, 2, LITERAL("**"), 1) != 0); - VERIFY(sw.compare(0, 2, LITERAL("**"), 2) == 0); - VERIFY(sw.compare(0, 2, LITERAL("^^"), 2) != 0); - } - - - // EA_CONSTEXPR size_type find(basic_string_view s, size_type pos = 0) const EA_NOEXCEPT; - { - StringViewT sw(LITERAL("*** Hello ***")); - VERIFY(sw.find(StringViewT(LITERAL("Hello"))) != StringViewT::npos); - VERIFY(sw.find(StringViewT(LITERAL("ell"))) != StringViewT::npos); - VERIFY(sw.find(StringViewT(LITERAL("FailToFindMe"))) == StringViewT::npos); - } - - // EA_CONSTEXPR size_type find(T c, size_type pos = 0) const EA_NOEXCEPT; - { - StringViewT sw(LITERAL("*** Hello ***")); - VERIFY(sw.find(LITERAL("H")) == 4); - VERIFY(sw.find(LITERAL("e")) == 5); - VERIFY(sw.find(LITERAL("l")) == 6); - VERIFY(sw.find(LITERAL("o")) == 8); - VERIFY(sw.find(LITERAL("&")) == StringViewT::npos); - VERIFY(sw.find(LITERAL("@")) == StringViewT::npos); - } - - // EA_CONSTEXPR size_type find(const T* s, size_type pos, size_type n) const; - { - StringViewT sw(LITERAL("Hello, Vancouver")); - VERIFY(sw.find(LITERAL("Hello"), 0, 3) != StringViewT::npos); - VERIFY(sw.find(LITERAL("Hello"), 3, 3) == StringViewT::npos); - VERIFY(sw.find(LITERAL("Vancouv"), 7, 7) != StringViewT::npos); - } - - // EA_CONSTEXPR size_type find(const T* s, size_type pos = 0) const; - { - StringViewT sw(LITERAL("Hello, Vancouver")); - VERIFY(sw.find(LITERAL("Hello"), 0) != StringViewT::npos); - VERIFY(sw.find(LITERAL("Hello"), 3) == StringViewT::npos); - VERIFY(sw.find(LITERAL("Vancouv"), 7) != StringViewT::npos); - } - - - // EA_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type rfind(T c, size_type pos = npos) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type rfind(const T* s, size_type pos, size_type n) const; - // EA_CONSTEXPR size_type rfind(const T* s, size_type pos = npos) const; - { - StringViewT str(LITERAL("abcdefghijklmnopqrstuvwxyz")); - - VERIFY(str.rfind(StringViewT(LITERAL("d"))) != StringViewT::npos); - VERIFY(str.rfind(StringViewT(LITERAL("tuv"))) != StringViewT::npos); - VERIFY(str.rfind(StringViewT(LITERAL("123r"))) == StringViewT::npos); - - VERIFY(str.rfind(LITERAL("d")) != StringViewT::npos); - VERIFY(str.rfind(LITERAL("tuv")) != StringViewT::npos); - VERIFY(str.rfind(LITERAL("123r")) == StringViewT::npos); - - VERIFY(str.rfind(LITERAL("d"), str.length()) != StringViewT::npos); - VERIFY(str.rfind(LITERAL("tuv"), str.length() - 2) != StringViewT::npos); - VERIFY(str.rfind(LITERAL("123r"), str.length() - 2) == StringViewT::npos); - - VERIFY(str.rfind(LITERAL('d'), str.length() - 0) != StringViewT::npos); - VERIFY(str.rfind(LITERAL('t'), str.length() - 2) != StringViewT::npos); - VERIFY(str.rfind(LITERAL('1'), str.length() - 2) == StringViewT::npos); - } - - // EA_CONSTEXPR size_type find_first_of(basic_string_view s, size_type pos = 0) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type find_first_of(T c, size_type pos = 0) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type find_first_of(const T* s, size_type pos, size_type n) const; - // EA_CONSTEXPR size_type find_first_of(const T* s, size_type pos = 0) const; - { - StringViewT str(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(str.find_first_of(StringViewT(LITERAL("aaa"))) == 0); - VERIFY(str.find_first_of(LITERAL("aab")) == 0); - VERIFY(str.find_first_of(LITERAL("baab")) == 0); - VERIFY(str.find_first_of(LITERAL("ceg")) == 10); - VERIFY(str.find_first_of(LITERAL("eeef"), 1, 2) == 18); - VERIFY(str.find_first_of(LITERAL("eeef"), 1, 4) == 18); - VERIFY(str.find_first_of(LITERAL('g')) == 26); - VERIFY(str.find_first_of(LITERAL('$')) == StringViewT::npos); - VERIFY(str.find_first_of(StringViewT(LITERAL(" a"), 1)) == StringViewT::npos); - } - - // EA_CONSTEXPR size_type find_last_of(basic_string_view s, size_type pos = npos) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type find_last_of(T c, size_type pos = npos) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type find_last_of(const T* s, size_type pos, size_type n) const; - // EA_CONSTEXPR size_type find_last_of(const T* s, size_type pos = npos) const; - { - StringViewT str(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(str.find_last_of(StringViewT(LITERAL("aaa"))) == 4); - VERIFY(str.find_last_of(LITERAL("aab")) == 9); - VERIFY(str.find_last_of(LITERAL("baab")) == 9); - VERIFY(str.find_last_of(LITERAL("ceg")) == 27); - // VERIFY(str.find_last_of(LITERAL("eeef"), 1, 2) == StringViewT::npos); // todo: FIX ME - // VERIFY(str.find_last_of(LITERAL("eeef"), 1, 4) == StringViewT::npos); // todo: FIX ME - VERIFY(str.find_last_of(LITERAL('g')) == 27); - VERIFY(str.find_last_of(LITERAL('$')) == StringViewT::npos); - } - - // EA_CONSTEXPR size_type find_first_not_of(basic_string_view s, size_type pos = 0) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type find_first_not_of(T c, size_type pos = 0) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type find_first_not_of(const T* s, size_type pos, size_type n) const; - // EA_CONSTEXPR size_type find_first_not_of(const T* s, size_type pos = 0) const; - { - StringViewT str(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(str.find_first_not_of(StringViewT(LITERAL("abcdfg"))) == 18); - VERIFY(str.find_first_not_of(LITERAL("abcdfg")) == 18); - // VERIFY(str.find_first_not_of(LITERAL("abcdfg"), 2, 2) == 0); // todo: FIX ME - // VERIFY(str.find_first_not_of(LITERAL("abcdfg"), 0, 2) == 10); // todo: FIX ME - VERIFY(str.find_first_not_of(LITERAL('a')) == 5); - } - - - // EA_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type find_last_not_of(T c, size_type pos = npos) const EA_NOEXCEPT; - // EA_CONSTEXPR size_type find_last_not_of(const T* s, size_type pos, size_type n) const; - // EA_CONSTEXPR size_type find_last_not_of(const T* s, size_type pos = npos) const; - { - StringViewT str(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(str.find_last_not_of(StringViewT(LITERAL("a"))) == 28); - VERIFY(str.find_last_not_of(StringViewT(LITERAL("abcdfg"))) == 28); - VERIFY(str.find_last_not_of(StringViewT(LITERAL("abcdfgh"))) == 22); - VERIFY(str.find_last_not_of(LITERAL("abcdfgh")) == 22); - // VERIFY(str.find_last_not_of(LITERAL("abcdfg"), 2, 2) == 0); // todo: FIX ME - // VERIFY(str.find_last_not_of(LITERAL("abcdfg"), 0, 2) == 10); // todo: FIX ME - VERIFY(str.find_last_not_of(LITERAL('a')) == 28); - } - - // template <class CharT, class Traits> - // constexpr bool operator==(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs); - // template <class CharT, class Traits> - // constexpr bool operator!=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs); - // template <class CharT, class Traits> - // constexpr bool operator<(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs); - // template <class CharT, class Traits> - // constexpr bool operator<=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs); - // template <class CharT, class Traits> - // constexpr bool operator>(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs); - // template <class CharT, class Traits> - // constexpr bool operator>=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs); - { - StringViewT sw1(LITERAL("AAAAABBBBBCCCDDDDDEEEEEFFFGGH")); - StringViewT sw2(LITERAL("aaaaabbbbbcccdddddeeeeefffggh")); - - VERIFY(sw1 == StringViewT(LITERAL("AAAAABBBBBCCCDDDDDEEEEEFFFGGH"))); - VERIFY(sw1 != StringViewT(LITERAL("abcdefghijklmnopqrstuvwxyz"))); - VERIFY(sw1 < sw2); - VERIFY(sw1 <= sw2); - VERIFY(sw2 > sw1); - VERIFY(sw2 >= sw1); - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - VERIFY((sw1 <=> StringViewT(LITERAL("AAAAABBBBBCCCDDDDDEEEEEFFFGGH"))) == 0); - VERIFY((sw1 <=> StringViewT(LITERAL("abcdefghijklmnopqrstuvwxyz"))) != 0); - VERIFY((sw1 <=> sw2) < 0); - VERIFY((sw1 <=> sw2) <= 0); - VERIFY((sw2 <=> sw1) > 0); - VERIFY((sw2 <=> sw1) >= 0); -#endif - } - - { - auto s = LITERAL("Hello, World"); - StringViewT sv(s); - - VERIFY(s == sv); - VERIFY(sv == s); - - VERIFY(s <= sv); - VERIFY(sv <= s); - VERIFY(s >= sv); - VERIFY(sv >= s); - VERIFY(!(s != sv)); - VERIFY(!(sv != s)); - VERIFY(!(s < sv)); - VERIFY(!(sv < s)); - VERIFY(!(s > sv)); - VERIFY(!(sv > s)); - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - VERIFY((s <=> sv) == 0); - VERIFY((sv <=> s) == 0); - - VERIFY((s <=> sv) <= 0); - VERIFY((sv <=> s) <= 0); - VERIFY((s <=> sv) >= 0); - VERIFY((sv <=> s) >= 0); - VERIFY(!((s <=> sv) != 0)); - VERIFY(!((sv <=> s) != 0)); - VERIFY(!((s <=> sv) > 0)); - VERIFY(!((sv <=> s) < 0)); -#endif - } - - // Regression comparison operators should work between basic_string_view and basic_string. - // The idea is that type_identity_t on some overloads will force basic_string::operator basic_string_view() to kick in. - { - StringT s(LITERAL("Hello, Stockholm")); - StringViewT sv(s); - - VERIFY(s == sv); - VERIFY(sv == s); - - // All the operators bellow used to not work. - VERIFY(s <= sv); - VERIFY(sv <= s); - VERIFY(s >= sv); - VERIFY(sv >= s); - VERIFY(!(s != sv)); - VERIFY(!(sv != s)); - VERIFY(!(s < sv)); - VERIFY(!(sv < s)); - VERIFY(!(s > sv)); - VERIFY(!(sv > s)); - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - VERIFY((s <=> sv) == 0); - VERIFY((sv <=> s) == 0); - - VERIFY((s <=> sv) <= 0); - VERIFY((sv <=> s) <= 0); - VERIFY((s <=> sv) >= 0); - VERIFY((sv <=> s) >= 0); - VERIFY(!((s <=> sv) != 0)); - VERIFY(!((sv <=> s) != 0)); - VERIFY(!((s <=> sv) > 0)); - VERIFY(!((sv <=> s) < 0)); -#endif - } - - // template<> struct hash<std::string_view>; - // template<> struct hash<std::wstring_view>; - // template<> struct hash<std::u16string_view>; - // template<> struct hash<std::u32string_view>; - { - StringViewT sw1(LITERAL("Hello, World")); - StringViewT sw2(LITERAL("Hello, World"), 5); - StringViewT sw3(LITERAL("Hello")); - auto s = LITERAL("Hello"); - - VERIFY(eastl::hash<StringViewT>{}(sw1) != eastl::hash<StringViewT>{}(sw2)); - VERIFY(eastl::hash<StringViewT>{}(sw2) == eastl::hash<StringViewT>{}(sw3)); - VERIFY(eastl::hash<StringViewT>{}(sw3) == eastl::hash<decltype(s)>{}(s)); - } - } - - { - StringViewT sw1(LITERAL("AAAAABBBBBCCCDDDDDEEEEEFFFGGH")); - - VERIFY( sw1.starts_with(LITERAL('A'))); - VERIFY(!sw1.starts_with(LITERAL('X'))); - VERIFY( sw1.starts_with(LITERAL("AAAA"))); - VERIFY( sw1.starts_with(StringViewT(LITERAL("AAAA")))); - VERIFY(!sw1.starts_with(LITERAL("AAAB"))); - - VERIFY( sw1.ends_with(LITERAL('H'))); - VERIFY(!sw1.ends_with(LITERAL('X'))); - VERIFY( sw1.ends_with(LITERAL("FGGH"))); - VERIFY( sw1.ends_with(StringViewT(LITERAL("FGGH")))); - VERIFY(!sw1.ends_with(LITERAL("FGGH$"))); - } - - return nErrorCount; -} - -// Required to prevent manual undef of macros when 'TestString.inl' preprocessed at the top of the unit test cpp file. -#undef TEST_STRING_NAME -#undef LITERAL - diff --git a/test/source/TestTuple.cpp b/test/source/TestTuple.cpp deleted file mode 100644 index 6a7647e..0000000 --- a/test/source/TestTuple.cpp +++ /dev/null @@ -1,587 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" - -EA_DISABLE_VC_WARNING(4623 4625 4413 4510) - -#include <EASTL/tuple.h> -#include <EASTL/unique_ptr.h> - -#if EASTL_TUPLE_ENABLED - -namespace TestTupleInternal -{ - -struct DefaultConstructibleType -{ - static const int defaultVal = 0x1EE7C0DE; - DefaultConstructibleType() : mVal(defaultVal) {} - int mVal; -}; - -struct OperationCountingType -{ - OperationCountingType() : mVal() { ++mDefaultConstructorCalls; } - OperationCountingType(int x) : mVal(x) { ++mIntConstructorCalls; } - OperationCountingType(const OperationCountingType& x) : mVal(x.mVal) { ++mCopyConstructorCalls; } - OperationCountingType(OperationCountingType&& x) : mVal(x.mVal) - { - ++mMoveConstructorCalls; - x.mVal = 0; - } - OperationCountingType& operator=(const OperationCountingType& x) - { - mVal = x.mVal; - ++mCopyAssignmentCalls; - return *this; - } - OperationCountingType& operator=(OperationCountingType&& x) - { - mVal = x.mVal; - x.mVal = 0; - ++mMoveAssignmentCalls; - return *this; - } - ~OperationCountingType() { ++mDestructorCalls; } - - int mVal; - - static void ResetCounters() - { - mDefaultConstructorCalls = 0; - mIntConstructorCalls = 0; - mCopyConstructorCalls = 0; - mMoveConstructorCalls = 0; - mCopyAssignmentCalls = 0; - mMoveAssignmentCalls = 0; - mDestructorCalls = 0; - } - - static int mDefaultConstructorCalls; - static int mIntConstructorCalls; - static int mCopyConstructorCalls; - static int mMoveConstructorCalls; - static int mCopyAssignmentCalls; - static int mMoveAssignmentCalls; - static int mDestructorCalls; -}; - -int OperationCountingType::mDefaultConstructorCalls = 0; -int OperationCountingType::mIntConstructorCalls = 0; -int OperationCountingType::mCopyConstructorCalls = 0; -int OperationCountingType::mMoveConstructorCalls = 0; -int OperationCountingType::mCopyAssignmentCalls = 0; -int OperationCountingType::mMoveAssignmentCalls = 0; -int OperationCountingType::mDestructorCalls = 0; - -} // namespace TestTupleInternal - -int TestTuple() -{ - using namespace eastl; - using namespace TestTupleInternal; - - int nErrorCount = 0; - - static_assert(tuple_size<tuple<int>>::value == 1, "tuple_size<tuple<T>> test failed."); - static_assert(tuple_size<const tuple<int>>::value == 1, "tuple_size<const tuple<T>> test failed."); - static_assert(tuple_size<const tuple<const int>>::value == 1, "tuple_size<const tuple<const T>> test failed."); - static_assert(tuple_size<volatile tuple<int>>::value == 1, "tuple_size<volatile tuple<T>> test failed."); - static_assert(tuple_size<const volatile tuple<int>>::value == 1, "tuple_size<const volatile tuple<T>> test failed."); - static_assert(tuple_size<tuple<int, float, bool>>::value == 3, "tuple_size<tuple<T, T, T>> test failed."); - - static_assert(is_same<tuple_element_t<0, tuple<int>>, int>::value, "tuple_element<I, T> test failed."); - static_assert(is_same<tuple_element_t<1, tuple<float, int>>, int>::value, "tuple_element<I, T> test failed."); - static_assert(is_same<tuple_element_t<1, tuple<float, const int>>, const int>::value, "tuple_element<I, T> test failed."); - static_assert(is_same<tuple_element_t<1, tuple<float, volatile int>>, volatile int>::value, "tuple_element<I, T> test failed."); - static_assert(is_same<tuple_element_t<1, tuple<float, const volatile int>>, const volatile int>::value, "tuple_element<I, T> test failed."); - static_assert(is_same<tuple_element_t<1, tuple<float, int&>>, int&>::value, "tuple_element<I, T> test failed."); - - { - tuple<int> aSingleElementTuple(1); - EATEST_VERIFY(get<0>(aSingleElementTuple) == 1); - get<0>(aSingleElementTuple) = 2; - EATEST_VERIFY(get<0>(aSingleElementTuple) == 2); - get<int>(aSingleElementTuple) = 3; - EATEST_VERIFY(get<int>(aSingleElementTuple) == 3); - - const tuple<int> aConstSingleElementTuple(3); - EATEST_VERIFY(get<0>(aConstSingleElementTuple) == 3); - EATEST_VERIFY(get<int>(aConstSingleElementTuple) == 3); - - tuple<DefaultConstructibleType> aDefaultConstructedTuple; - EATEST_VERIFY(get<0>(aDefaultConstructedTuple).mVal == DefaultConstructibleType::defaultVal); - - OperationCountingType::ResetCounters(); - tuple<OperationCountingType> anOperationCountingTuple; - EATEST_VERIFY(OperationCountingType::mDefaultConstructorCalls == 1 && - get<0>(anOperationCountingTuple).mVal == 0); - get<0>(anOperationCountingTuple).mVal = 1; - tuple<OperationCountingType> anotherOperationCountingTuple(anOperationCountingTuple); - EATEST_VERIFY(OperationCountingType::mDefaultConstructorCalls == 1 && - OperationCountingType::mCopyConstructorCalls == 1 && - get<0>(anotherOperationCountingTuple).mVal == 1); - get<0>(anOperationCountingTuple).mVal = 2; - anotherOperationCountingTuple = anOperationCountingTuple; - EATEST_VERIFY( - OperationCountingType::mDefaultConstructorCalls == 1 && OperationCountingType::mCopyConstructorCalls == 1 && - OperationCountingType::mCopyAssignmentCalls == 1 && get<0>(anotherOperationCountingTuple).mVal == 2); - - OperationCountingType::ResetCounters(); - tuple<OperationCountingType> yetAnotherOperationCountingTuple(OperationCountingType(5)); - EATEST_VERIFY( - OperationCountingType::mMoveConstructorCalls == 1 && OperationCountingType::mDefaultConstructorCalls == 0 && - OperationCountingType::mCopyConstructorCalls == 0 && get<0>(yetAnotherOperationCountingTuple).mVal == 5); - } - - EATEST_VERIFY(OperationCountingType::mDestructorCalls == 4); - - { - // Test constructor - tuple<int, float, bool> aTuple(1, 1.0f, true); - EATEST_VERIFY(get<0>(aTuple) == 1); - EATEST_VERIFY(get<1>(aTuple) == 1.0f); - EATEST_VERIFY(get<2>(aTuple) == true); - EATEST_VERIFY(get<int>(aTuple) == 1); - EATEST_VERIFY(get<float>(aTuple) == 1.0f); - EATEST_VERIFY(get<bool>(aTuple) == true); - - get<1>(aTuple) = 2.0f; - EATEST_VERIFY(get<1>(aTuple) == 2.0f); - - // Test copy constructor - tuple<int, float, bool> anotherTuple(aTuple); - EATEST_VERIFY(get<0>(anotherTuple) == 1 && get<1>(anotherTuple) == 2.0f && get<2>(anotherTuple) == true); - - // Test copy assignment - tuple<int, float, bool> yetAnotherTuple(2, 3.0f, true); - EATEST_VERIFY(get<0>(yetAnotherTuple) == 2 && get<1>(yetAnotherTuple) == 3.0f && - get<2>(yetAnotherTuple) == true); - yetAnotherTuple = anotherTuple; - EATEST_VERIFY(get<0>(yetAnotherTuple) == 1 && get<1>(yetAnotherTuple) == 2.0f && - get<2>(yetAnotherTuple) == true); - - // Test converting 'copy' constructor (from a tuple of different type whose members are each convertible) - tuple<double, double, bool> aDifferentTuple(aTuple); - EATEST_VERIFY(get<0>(aDifferentTuple) == 1.0 && get<1>(aDifferentTuple) == 2.0 && - get<2>(aDifferentTuple) == true); - - // Test converting assignment operator (from a tuple of different type whose members are each convertible) - tuple<double, double, bool> anotherDifferentTuple; - EATEST_VERIFY(get<0>(anotherDifferentTuple) == 0.0 && get<1>(anotherDifferentTuple) == 0.0 && - get<2>(anotherDifferentTuple) == false); - anotherDifferentTuple = anotherTuple; - EATEST_VERIFY(get<0>(anotherDifferentTuple) == 1.0 && get<1>(anotherDifferentTuple) == 2.0 && - get<2>(anotherDifferentTuple) == true); - - // Test default initialization (built in types should be value initialized rather than default initialized) - tuple<int, float, bool> aDefaultInitializedTuple; - EATEST_VERIFY(get<0>(aDefaultInitializedTuple) == 0 && get<1>(aDefaultInitializedTuple) == 0.0f && - get<2>(aDefaultInitializedTuple) == false); - } - - { - // Test some other cases with typed-getter - tuple<double, double, bool> aTupleWithRepeatedType(1.0f, 2.0f, true); - EATEST_VERIFY(get<bool>(aTupleWithRepeatedType) == true); - - tuple<double, bool, double> anotherTupleWithRepeatedType(1.0f, true, 2.0f); - EATEST_VERIFY(get<bool>(anotherTupleWithRepeatedType) == true); - - tuple<bool, double, double> yetAnotherTupleWithRepeatedType(true, 1.0f, 2.0f); - EATEST_VERIFY(get<bool>(anotherTupleWithRepeatedType) == true); - - struct floatOne { float val; }; - struct floatTwo { float val; }; - tuple<floatOne, floatTwo> aTupleOfStructs({ 1.0f }, { 2.0f } ); - EATEST_VERIFY(get<floatOne>(aTupleOfStructs).val == 1.0f); - EATEST_VERIFY(get<floatTwo>(aTupleOfStructs).val == 2.0f); - - const tuple<double, double, bool> aConstTuple(aTupleWithRepeatedType); - const bool& constRef = get<bool>(aConstTuple); - EATEST_VERIFY(constRef == true); - - const bool&& constRval = get<bool>(eastl::move(aTupleWithRepeatedType)); - EATEST_VERIFY(constRval == true); - } - - { - tuple<int, float> aTupleWithDefaultInit(1, {}); - - // tuple construction from pair - pair<int, float> aPair(1, 2.0f); - tuple<int, float> aTuple(aPair); - EATEST_VERIFY(get<0>(aTuple) == 1 && get<1>(aTuple) == 2.0f); - tuple<double, double> anotherTuple(aPair); - EATEST_VERIFY(get<0>(anotherTuple) == 1.0 && get<1>(anotherTuple) == 2.0); - anotherTuple = make_pair(2, 3); - EATEST_VERIFY(get<0>(anotherTuple) == 2.0 && get<1>(anotherTuple) == 3.0); - - // operators: ==, !=, < - anotherTuple = aTuple; - EATEST_VERIFY(aTuple == anotherTuple); - EATEST_VERIFY(!(aTuple < anotherTuple) && !(anotherTuple < aTuple)); - tuple<double, double> aDefaultInitTuple; - EATEST_VERIFY(aTuple != aDefaultInitTuple); - EATEST_VERIFY(aDefaultInitTuple < aTuple); - - #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - EATEST_VERIFY((aTuple <=> anotherTuple) == 0); - EATEST_VERIFY((aTuple <=> anotherTuple) >= 0); - EATEST_VERIFY((anotherTuple <=> aTuple) >= 0); - EATEST_VERIFY((aTuple <=> aDefaultInitTuple) != 0); - EATEST_VERIFY((aDefaultInitTuple <=> aTuple) < 0); - #endif - - tuple<int, int, int> lesserTuple(1, 2, 3); - tuple<int, int, int> greaterTuple(1, 2, 4); - EATEST_VERIFY(lesserTuple < greaterTuple && !(greaterTuple < lesserTuple) && greaterTuple > lesserTuple && - !(lesserTuple > greaterTuple)); - - #if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - EATEST_VERIFY((lesserTuple <=> greaterTuple) != 0); - EATEST_VERIFY((lesserTuple <=> greaterTuple) < 0); - EATEST_VERIFY((lesserTuple <=> greaterTuple) <= 0); - EATEST_VERIFY((greaterTuple <=> lesserTuple) > 0); - EATEST_VERIFY((greaterTuple <=> lesserTuple) >= 0); - #endif - - tuple<int, float, TestObject> valTup(2, 2.0f, TestObject(2)); - tuple<int&, float&, TestObject&> refTup(valTup); - tuple<const int&, const float&, const TestObject&> constRefTup(valTup); - - EATEST_VERIFY(get<0>(refTup) == get<0>(valTup)); - EATEST_VERIFY(get<1>(refTup) == get<1>(valTup)); - EATEST_VERIFY(refTup == valTup); - EATEST_VERIFY(get<0>(refTup) == get<0>(constRefTup)); - EATEST_VERIFY(get<1>(refTup) == get<1>(constRefTup)); - EATEST_VERIFY(constRefTup == valTup); - EATEST_VERIFY(constRefTup == refTup); - - // swap - swap(lesserTuple, greaterTuple); - EATEST_VERIFY(get<2>(lesserTuple) == 4 && get<2>(greaterTuple) == 3); - swap(greaterTuple, lesserTuple); - EATEST_VERIFY(lesserTuple < greaterTuple); - } - - { - // Test construction of tuple containing a move only type - static_assert(is_constructible<MoveOnlyType, MoveOnlyType>::value, "is_constructible type trait giving confusing answers."); - static_assert(is_constructible<MoveOnlyType, MoveOnlyType&&>::value, "is_constructible type trait giving wrong answers."); - static_assert(is_constructible<MoveOnlyType&&, MoveOnlyType&&>::value, "is_constructible type trait giving bizarre answers."); - tuple<MoveOnlyType> aTupleWithMoveOnlyMember(1); - EATEST_VERIFY(get<0>(aTupleWithMoveOnlyMember).mVal == 1); - get<0>(aTupleWithMoveOnlyMember) = MoveOnlyType(2); - EATEST_VERIFY(get<0>(aTupleWithMoveOnlyMember).mVal == 2); - - tuple<const MoveOnlyType&> aTupleWithRefToMoveOnlyMember(aTupleWithMoveOnlyMember); - EATEST_VERIFY(get<0>(aTupleWithRefToMoveOnlyMember).mVal == 2); - - tuple<const MoveOnlyType&> aTupleWithConstRefToGetMoveOnly(get<0>(aTupleWithMoveOnlyMember)); - EATEST_VERIFY(get<0>(aTupleWithConstRefToGetMoveOnly).mVal == 2); - - tuple<MoveOnlyType&> aTupleWithRefToGetMoveOnly(get<0>(aTupleWithMoveOnlyMember)); - EATEST_VERIFY(get<0>(aTupleWithRefToGetMoveOnly).mVal == 2); - } - - { - // Test construction of tuple containing r-value references - int x = 42; - TestObject object{1337}; - - tuple<int&&, TestObject&&> aTupleWithRValueReference(eastl::move(x), eastl::move(object)); - static_assert(is_same<decltype(get<0>(aTupleWithRValueReference)), int&>::value, "wrong return type for get when using r-value reference."); - static_assert(is_same<decltype(get<1>(aTupleWithRValueReference)), TestObject&>::value, "wrong return type for get when using r-value reference."); - EATEST_VERIFY(get<0>(aTupleWithRValueReference) == 42); - EATEST_VERIFY(get<1>(aTupleWithRValueReference).mX == 1337); - - static_assert(!is_constructible<decltype(aTupleWithRValueReference), int&, TestObject&>::value, "it shouldn't be possible to assign r-value references with l-values."); - } - - { - // Tuple helpers - - // make_tuple - auto makeTuple = make_tuple(1, 2.0, true); - EATEST_VERIFY(get<0>(makeTuple) == 1 && get<1>(makeTuple) == 2.0 && get<2>(makeTuple) == true); - - // TODO: reference_wrapper implementation needs to be finished to enable this code - { - int a = 2; - float b = 3.0f; - auto makeTuple2 = make_tuple(ref(a), b); - get<0>(makeTuple2) = 3; - get<1>(makeTuple2) = 4.0f; - EATEST_VERIFY(get<0>(makeTuple2) == 3 && get<1>(makeTuple2) == 4.0f && a == 3 && b == 3.0f); - } - - // forward_as_tuple - { - auto forwardTest = [](tuple<MoveOnlyType&&, MoveOnlyType&&> x) -> tuple<MoveOnlyType, MoveOnlyType> - { - return tuple<MoveOnlyType, MoveOnlyType>(move(x)); - }; - - tuple<MoveOnlyType, MoveOnlyType> aMovableTuple( - forwardTest(forward_as_tuple(MoveOnlyType(1), MoveOnlyType(2)))); - - EATEST_VERIFY(get<0>(aMovableTuple).mVal == 1 && get<1>(aMovableTuple).mVal == 2); - } - - { - // tie - int a = 0; - double b = 0.0f; - static_assert(is_assignable<const Internal::ignore_t&, int>::value, "ignore_t not assignable"); - static_assert(Internal::TupleAssignable<tuple<const Internal::ignore_t&>, tuple<int>>::value, "Not assignable"); - tie(a, ignore, b) = make_tuple(1, 3, 5); - EATEST_VERIFY(a == 1 && b == 5.0f); - - // tuple_cat - auto tcatRes = tuple_cat(make_tuple(1, 2.0f), make_tuple(3.0, true)); - EATEST_VERIFY(get<0>(tcatRes) == 1 && get<1>(tcatRes) == 2.0f && get<2>(tcatRes) == 3.0 && - get<3>(tcatRes) == true); - - auto tcatRes2 = tuple_cat(make_tuple(1, 2.0f), make_tuple(3.0, true), make_tuple(5u, '6')); - EATEST_VERIFY(get<0>(tcatRes2) == 1 && get<1>(tcatRes2) == 2.0f && get<2>(tcatRes2) == 3.0 && - get<3>(tcatRes2) == true && get<4>(tcatRes2) == 5u && get<5>(tcatRes2) == '6'); - - auto aCattedRefTuple = tuple_cat(make_tuple(1), tie(a, ignore, b)); - get<1>(aCattedRefTuple) = 2; - EATEST_VERIFY(a == 2); - } - - { - // Empty tuple - tuple<> emptyTuple; - EATEST_VERIFY(tuple_size<decltype(emptyTuple)>::value == 0); - emptyTuple = make_tuple(); - auto anotherEmptyTuple = make_tuple(); - swap(anotherEmptyTuple, emptyTuple); - } - } - - // test piecewise_construct - { - { - struct local - { - local() = default; - local(int a, int b) : mA(a), mB(b) {} - - int mA = 0; - int mB = 0; - }; - - auto t = make_tuple(42, 43); - - eastl::pair<local, local> p(eastl::piecewise_construct, t, t); - - EATEST_VERIFY(p.first.mA == 42); - EATEST_VERIFY(p.second.mA == 42); - EATEST_VERIFY(p.first.mB == 43); - EATEST_VERIFY(p.second.mB == 43); - } - - { - struct local - { - local() = default; - local(int a, int b, int c, int d) : mA(a), mB(b), mC(c), mD(d) {} - - int mA = 0; - int mB = 0; - int mC = 0; - int mD = 0; - }; - - auto t = make_tuple(42, 43, 44, 45); - - eastl::pair<local, local> p(eastl::piecewise_construct, t, t); - - EATEST_VERIFY(p.first.mA == 42); - EATEST_VERIFY(p.second.mA == 42); - - EATEST_VERIFY(p.first.mB == 43); - EATEST_VERIFY(p.second.mB == 43); - - EATEST_VERIFY(p.first.mC == 44); - EATEST_VERIFY(p.second.mC == 44); - - EATEST_VERIFY(p.first.mD == 45); - EATEST_VERIFY(p.second.mD == 45); - } - - { - struct local1 - { - local1() = default; - local1(int a) : mA(a) {} - int mA = 0; - }; - - struct local2 - { - local2() = default; - local2(char a) : mA(a) {} - char mA = 0; - }; - - auto t1 = make_tuple(42); - auto t2 = make_tuple('a'); - - eastl::pair<local1, local2> p(eastl::piecewise_construct, t1, t2); - - EATEST_VERIFY(p.first.mA == 42); - EATEST_VERIFY(p.second.mA == 'a'); - } - } - - // apply - { - // test with tuples - { - { - auto result = eastl::apply([](int i) { return i; }, make_tuple(1)); - EATEST_VERIFY(result == 1); - } - - { - auto result = eastl::apply([](int i, int j) { return i + j; }, make_tuple(1, 2)); - EATEST_VERIFY(result == 3); - } - - - { - auto result = eastl::apply([](int i, int j, int k, int m) { return i + j + k + m; }, make_tuple(1, 2, 3, 4)); - EATEST_VERIFY(result == 10); - } - } - - // test with pair - { - auto result = eastl::apply([](int i, int j) { return i + j; }, make_pair(1, 2)); - EATEST_VERIFY(result == 3); - } - - // test with array - { - // TODO(rparolin): - // eastl::array requires eastl::get support before we can support unpacking eastl::arrays with eastl::apply. - // - // { - // auto result = eastl::apply([](int i) { return i; }, eastl::array<int, 1>{1}); - // EATEST_VERIFY(result == 1); - // } - // { - // auto result = eastl::apply([](int i, int j) { return i + j; }, eastl::array<int, 2>{1,2}); - // EATEST_VERIFY(result == 3); - // } - // { - // auto result = eastl::apply([](int i, int j, int k, int m) { return i + j + k + m; }, eastl::array<int, 4>{1, 2, 3, 4}); - // EATEST_VERIFY(result == 10); - // } - } - } - - // Compilation test to make sure that the conditionally-explicit cast works - { - eastl::tuple<int, float, TestObject> arrayTup[] = { - {1, 1.0f, TestObject(1)}, - {2, 2.0f, TestObject(2)}, - {3, 3.0f, TestObject(3)}, - {4, 4.0f, TestObject(4)} - }; - (void)arrayTup; - -#if false - // the following code should not compile with conditionally-explicit behaviour (but does with fully implicit behaviour) - eastl::tuple<eastl::vector<float>, float> arrayOfArrayTup[] = { - {1.0f, 1.0f}, - {2.0f, 2.0f} - }; - - eastl::tuple<eastl::vector<int>, float> arrayOfArrayTup2[] = { - {1, 1.0f}, - {2, 2.0f} - }; -#endif - } - - // Compilation test to make sure that we can handle reference to forward-declared types - { - struct ForwardDeclared; - - auto fill_tuple = [](ForwardDeclared& f) { - eastl::tuple<ForwardDeclared&, const ForwardDeclared&> t{f, f}; - return t; - }; - - struct ForwardDeclared - { - int x; - }; - - ForwardDeclared f{666}; - auto t = fill_tuple(f); - - EATEST_VERIFY(get<0>(t).x == 666); - EATEST_VERIFY(get<1>(t).x == 666); - } - - #ifndef EA_COMPILER_NO_STRUCTURED_BINDING - // tuple structured bindings test - { - eastl::tuple<int, int, int> t = {1,2,3}; - auto [x,y,z] = t; - EATEST_VERIFY(x == 1); - EATEST_VERIFY(y == 2); - EATEST_VERIFY(z == 3); - } - - { // const unpacking test - eastl::tuple<int, int, int> t = {1,2,3}; - const auto [x,y,z] = t; - EATEST_VERIFY(x == 1); - EATEST_VERIFY(y == 2); - EATEST_VERIFY(z == 3); - } - #endif - - // user regression for tuple_cat - { - void* empty = nullptr; - auto t = eastl::make_tuple(empty, true); - auto tc = eastl::tuple_cat(eastl::make_tuple("asd", 1), t); - - static_assert(eastl::is_same_v<decltype(tc), eastl::tuple<const char*, int, void*, bool>>, "type mismatch"); - - EATEST_VERIFY(eastl::string("asd") == eastl::get<0>(tc)); - EATEST_VERIFY(eastl::get<1>(tc) == 1); - EATEST_VERIFY(eastl::get<2>(tc) == nullptr); - EATEST_VERIFY(eastl::get<3>(tc) == true); - } - - // user reported regression that exercises type_traits trying to pull out the element_type from "fancy pointers" - { - auto up = eastl::make_unique<int[]>(100); - auto t = eastl::make_tuple(eastl::move(up)); - - using ResultTuple_t = decltype(t); - static_assert(eastl::is_same_v<ResultTuple_t, eastl::tuple<eastl::unique_ptr<int[]>>>); - static_assert(eastl::is_same_v<eastl::tuple_element_t<0, ResultTuple_t>, eastl::unique_ptr<int[]>>); - } - - return nErrorCount; -} - -#else - -int TestTuple() { return 0; } - -#endif // EASTL_TUPLE_ENABLED - -EA_RESTORE_VC_WARNING() diff --git a/test/source/TestTupleVector.cpp b/test/source/TestTupleVector.cpp deleted file mode 100644 index 8a83803..0000000 --- a/test/source/TestTupleVector.cpp +++ /dev/null @@ -1,1540 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// TestTupleVector.cpp -// -// Copyright (c) 2018, Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" - -#include <EASTL/bonus/tuple_vector.h> - -#include <EASTL/sort.h> - -using namespace eastl; - -int TestTupleVector() -{ - int nErrorCount = 0; - - // Test push-backs and accessors - { - tuple_vector<int> singleElementVec; - EATEST_VERIFY(singleElementVec.size() == 0); - EATEST_VERIFY(singleElementVec.capacity() == 0); - EATEST_VERIFY(singleElementVec.empty() == true); - EATEST_VERIFY(singleElementVec.validate()); - singleElementVec.push_back_uninitialized(); - singleElementVec.push_back(5); - EATEST_VERIFY(singleElementVec.size() == 2); - EATEST_VERIFY(singleElementVec.capacity() > 0); - EATEST_VERIFY(singleElementVec.get<0>()[1] == 5); - EATEST_VERIFY(singleElementVec.get<int>()[1] == 5); - EATEST_VERIFY(singleElementVec.empty() == false); - EATEST_VERIFY(singleElementVec.validate()); - - tuple_vector<int, float, bool> complexVec; - complexVec.reserve(5); - { - // need to call an overload of push_back that specifically grabs lvalue candidates - providing constants tend to prefer rvalue path - int intArg = 3; - float floatArg = 2.0f; - bool boolArg = true; - complexVec.push_back(intArg, floatArg, boolArg); - } - complexVec.push_back(1, 4.0f, false); - complexVec.push_back(2, 1.0f, true); - { - tuple<int, float, bool> complexTup(4, 3.0f, false); - complexVec.push_back(complexTup); - } - complexVec.push_back(); - EATEST_VERIFY(complexVec.capacity() == 5); - EATEST_VERIFY(*(complexVec.get<0>()) == 3); - EATEST_VERIFY(complexVec.get<float>()[1] == 4.0f); - EATEST_VERIFY(complexVec.get<2>()[2] == complexVec.get<bool>()[2]); - EATEST_VERIFY(complexVec.validate()); - - tuple<int, float, bool> defaultComplexTup; - EATEST_VERIFY(complexVec.at(4) == defaultComplexTup); - - tuple<int*, float*, bool*> complexPtrTuple = complexVec.data(); - EATEST_VERIFY(get<0>(complexPtrTuple) != nullptr); - EATEST_VERIFY(get<2>(complexPtrTuple)[2] == complexVec.get<2>()[2]); - - tuple<int&, float&, bool&> complexRefTuple = complexVec.at(2); - tuple<int&, float&, bool&> complexRefTupleBracket = complexVec[2]; - tuple<int&, float&, bool&> complexRefTupleFront = complexVec.front(); - tuple<int&, float&, bool&> complexRefTupleBack = complexVec.back(); - EATEST_VERIFY(get<2>(complexRefTuple) == complexVec.get<2>()[2]); - EATEST_VERIFY(get<1>(complexRefTupleBracket) == 1.0f); - EATEST_VERIFY(get<1>(complexRefTupleFront) == 2.0f); - EATEST_VERIFY(get<1>(complexRefTupleBack) == 0.0f); - - // verify the equivalent accessors for the const container exist/compile - { - const tuple_vector<int, float, bool>& constVec = complexVec; - - EATEST_VERIFY(constVec.size() == 5); - EATEST_VERIFY(constVec.capacity() >= constVec.size()); - EATEST_VERIFY(constVec.empty() == false); - EATEST_VERIFY(constVec.get<1>() == constVec.get<float>()); - - tuple<const int*, const float*, const bool*> constPtrTuple = constVec.data(); - EATEST_VERIFY(get<0>(constPtrTuple) != nullptr); - EATEST_VERIFY(get<2>(constPtrTuple)[2] == constVec.get<2>()[2]); - - tuple<const int&, const float&, const bool&> constRefTuple = constVec.at(2); - tuple<const int&, const float&, const bool&> constRefTupleBracket = constVec[2]; - tuple<const int&, const float&, const bool&> constRefTupleFront = constVec.front(); - tuple<const int&, const float&, const bool&> constRefTupleBack = constVec.back(); - EATEST_VERIFY(get<2>(constRefTuple) == constVec.get<2>()[2]); - EATEST_VERIFY(get<1>(constRefTupleBracket) == 1.0f); - EATEST_VERIFY(get<1>(constRefTupleFront) == 2.0f); - EATEST_VERIFY(get<1>(constRefTupleBack) == 0.0f); - - // check that return types of const-version of begin and cbegin (etc) match - static_assert(eastl::is_same<decltype(constVec.begin()), decltype(constVec.cbegin())>::value, "error"); - static_assert(eastl::is_same<decltype(constVec.end()), decltype(constVec.cend())>::value, "error"); - static_assert(eastl::is_same<decltype(constVec.rbegin()), decltype(constVec.crbegin())>::value, "error"); - static_assert(eastl::is_same<decltype(constVec.rend()), decltype(constVec.crend())>::value, "error"); - - // check that return type of non-const version of begin and cbegin (etc) do _not_ match - static_assert(!eastl::is_same<decltype(complexVec.begin()), decltype(complexVec.cbegin())>::value, "error"); - static_assert(!eastl::is_same<decltype(complexVec.end()), decltype(complexVec.cend())>::value, "error"); - static_assert(!eastl::is_same<decltype(complexVec.rbegin()), decltype(complexVec.crbegin())>::value, "error"); - static_assert(!eastl::is_same<decltype(complexVec.rend()), decltype(complexVec.crend())>::value, "error"); - - } - } - - // test the memory layouts work for aligned structures - { - struct EA_ALIGN(16) AlignTestVec4 - { - float a[4]; - AlignTestVec4() : a{1.0f, 2.0f, 3.0f, 4.0f} {} - }; - - struct AlignTestByte3 - { - char a[3]; - AlignTestByte3() : a{1, 2, 3} {} - }; - - struct EA_ALIGN(8) AlignTestFourByte - { - int a[5]; - AlignTestFourByte() : a{-1, -2, -3, -4, -5} {} - }; - - tuple_vector<bool, AlignTestVec4, AlignTestByte3, AlignTestFourByte> alignElementVec; - alignElementVec.push_back(); - alignElementVec.push_back(); - alignElementVec.push_back(); - alignElementVec.push_back(); - alignElementVec.push_back(); - - EATEST_VERIFY((uintptr_t)alignElementVec.get<AlignTestVec4>() % 16 == 0); - EATEST_VERIFY((uintptr_t)alignElementVec.get<AlignTestFourByte>() % 8 == 0); - } - - // Test resize and various modifications - { - TestObject::Reset(); - - tuple_vector<bool, TestObject, float> testVec; - typedef tuple_vector<bool, TestObject, float>::size_type tuple_vector_size_type; - testVec.reserve(10); - for (int i = 0; i < 10; ++i) - { - testVec.push_back(i % 3 == 0, TestObject(i), (float)i); - } - testVec.pop_back(); - EATEST_VERIFY(testVec.size() == 9); - - // test resize that does destruction of objects - testVec.resize(5); - EATEST_VERIFY(testVec.size() == 5); - EATEST_VERIFY(TestObject::sTOCount == 5); - EATEST_VERIFY(testVec.capacity() == 10); - - // test resize that does default construction of objects - testVec.resize(10); - EATEST_VERIFY(testVec.size() == 10); - EATEST_VERIFY(TestObject::sTOCount == 10); - EATEST_VERIFY(testVec.capacity() == 10); - - // test resize that does default construction of objects and grows the vector - testVec.resize(15); - EATEST_VERIFY(testVec.size() == 15); - EATEST_VERIFY(TestObject::sTOCount == 15); - EATEST_VERIFY(testVec.capacity() > 10); - EATEST_VERIFY(testVec.validate()); - - // test resize with args that does destruction of objects - auto testVecCapacity = testVec.capacity(); - testVec.resize(5, true, TestObject(5), 5.0f); - EATEST_VERIFY(testVec.size() == 5); - EATEST_VERIFY(TestObject::sTOCount == 5); - EATEST_VERIFY(testVec.capacity() == testVecCapacity); - - // test resize with args that does construction of objects - testVec.resize(15, true, TestObject(5), 5.0f); - EATEST_VERIFY(testVec.size() == 15); - EATEST_VERIFY(TestObject::sTOCount == 15); - EATEST_VERIFY(testVec.capacity() == testVecCapacity); - - // test resize with args that does construction of objects and grows the vector - auto newTestVecSize = testVecCapacity + 5; - testVec.resize(newTestVecSize, true, TestObject(5), 5.0f); - EATEST_VERIFY(testVec.size() == newTestVecSize); - EATEST_VERIFY(static_cast<tuple_vector_size_type>(TestObject::sTOCount) == newTestVecSize); - EATEST_VERIFY(testVec.capacity() > newTestVecSize); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 5; i < newTestVecSize; ++i) - { - EATEST_VERIFY(testVec.get<0>()[i] == true); - EATEST_VERIFY(testVec.get<1>()[i] == TestObject(5)); - EATEST_VERIFY(testVec.get<2>()[i] == 5.0f); - } - - { - tuple<bool, TestObject, float> resizeTup(true, TestObject(10), 10.0f); - typedef tuple_vector<bool, TestObject, float>::size_type tuple_vector_size_type; - - // test resize with tuple that does destruction of objects - testVecCapacity = testVec.capacity(); - EATEST_VERIFY(testVecCapacity >= 15); // check for next two resizes to make sure we don't grow vec - - testVec.resize(20, resizeTup); - EATEST_VERIFY(testVec.size() == 20); - EATEST_VERIFY(TestObject::sTOCount == 20 + 1); - EATEST_VERIFY(testVec.capacity() == testVecCapacity); - - // test resize with tuple that does construction of objects - testVec.resize(25, resizeTup); - EATEST_VERIFY(testVec.size() == 25); - EATEST_VERIFY(TestObject::sTOCount == 25 + 1); - EATEST_VERIFY(testVec.capacity() == testVecCapacity); - - // test resize with tuple that does construction of objects and grows the vector - newTestVecSize = testVecCapacity + 5; - testVec.resize(newTestVecSize, resizeTup); - EATEST_VERIFY(testVec.size() == newTestVecSize); - EATEST_VERIFY(static_cast<tuple_vector_size_type>(TestObject::sTOCount) == newTestVecSize + 1); - EATEST_VERIFY(testVec.capacity() > newTestVecSize); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 5; i < 20; ++i) - { - EATEST_VERIFY(testVec.get<0>()[i] == true); - EATEST_VERIFY(testVec.get<1>()[i] == TestObject(5)); - EATEST_VERIFY(testVec.get<2>()[i] == 5.0f); - } - for (unsigned int i = 20; i < testVecCapacity; ++i) - { - EATEST_VERIFY(testVec.get<0>()[i] == get<0>(resizeTup)); - EATEST_VERIFY(testVec.get<1>()[i] == get<1>(resizeTup)); - EATEST_VERIFY(testVec.get<2>()[i] == get<2>(resizeTup)); - } - } - - // test other modifiers - testVec.pop_back(); - EATEST_VERIFY(testVec.size() == newTestVecSize - 1); - EATEST_VERIFY(static_cast<decltype(testVec)::size_type>(TestObject::sTOCount) == newTestVecSize - 1); // down 2 from last sTOCount check - resizeTup dtor and pop_back - - EATEST_VERIFY(testVec.capacity() > newTestVecSize); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == testVec.size()); - EATEST_VERIFY(testVec.validate()); - - testVec.clear(); - EATEST_VERIFY(testVec.empty()); - EATEST_VERIFY(testVec.validate()); - EATEST_VERIFY(TestObject::IsClear()); - - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 0); - EATEST_VERIFY(testVec.validate()); - TestObject::Reset(); - } - - // Test insert - { - TestObject::Reset(); - - // test insert with n values and lvalue args - { - tuple_vector<bool, TestObject, float> testVec; - bool boolArg = true; - TestObject toArg = TestObject(0); - float floatArg = 0.0f; - testVec.reserve(10); - - // test insert on empty vector that doesn't cause growth - toArg = TestObject(3); - floatArg = 3.0f; - auto insertIter = testVec.insert(testVec.begin(), 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(insertIter == testVec.begin()); - - // test insert to end of vector that doesn't cause growth - toArg = TestObject(5); - floatArg = 5.0f; - insertIter = testVec.insert(testVec.end(), 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 6); - EATEST_VERIFY(insertIter == testVec.begin() + 3); - - // test insert to middle of vector that doesn't cause growth - toArg = TestObject(4); - floatArg = 4.0f; - testVec.insert(testVec.begin() + 3, 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 9); - EATEST_VERIFY(testVec.capacity() == 10); - - // test insert to end of vector that causes growth - toArg = TestObject(6); - floatArg = 6.0f; - testVec.insert(testVec.end(), 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 12); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 12); - - // test insert to beginning of vector that causes growth - toArg = TestObject(1); - floatArg = 1.0f; - testVec.insert(testVec.begin(), 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 15); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 15); - - // test insert to middle of vector that causes growth - toArg = TestObject(2); - floatArg = 2.0f; - testVec.insert(testVec.begin() + 3, 3, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 18); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 18); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.get<1>()[i] == TestObject(i / 3 + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with lvalue args - { - tuple_vector<bool, TestObject, float> testVec; - bool boolArg = true; - TestObject toArg = TestObject(0); - float floatArg = 0.0f; - testVec.reserve(3); - - // test insert on empty vector that doesn't cause growth - toArg = TestObject(3); - floatArg = 3.0f; - testVec.insert(testVec.begin(), boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 1); - - // test insert to end of vector that doesn't cause growth - toArg = TestObject(5); - floatArg = 5.0f; - testVec.insert(testVec.end(), boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 2); - - // test insert to middle of vector that doesn't cause growth - toArg = TestObject(4); - floatArg = 4.0f; - testVec.insert(testVec.begin() + 1, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3); - - // test insert to end of vector that causes growth - toArg = TestObject(6); - floatArg = 6.0f; - testVec.insert(testVec.end(), boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 4); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 4); - - // test insert to beginning of vector that causes growth - toArg = TestObject(1); - floatArg = 1.0f; - testVec.insert(testVec.begin(), boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 5); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 5); - - // test insert to middle of vector that causes growth - toArg = TestObject(2); - floatArg = 2.0f; - testVec.insert(testVec.begin() + 1, boolArg, toArg, floatArg); - EATEST_VERIFY(testVec.size() == 6); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 6); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.get<1>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with n and tuple - { - tuple_vector<bool, TestObject, float> testVec; - tuple<bool, TestObject, float> testTup; - testVec.reserve(10); - - // test insert on empty vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(3), 3.0f); - testVec.insert(testVec.begin(), 3, testTup); - EATEST_VERIFY(testVec.size() == 3); - - // test insert to end of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(5), 5.0f); - testVec.insert(testVec.end(), 3, testTup); - EATEST_VERIFY(testVec.size() == 6); - - // test insert to middle of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(4), 4.0f); - testVec.insert(testVec.begin() + 3, 3, testTup); - EATEST_VERIFY(testVec.size() == 9); - EATEST_VERIFY(testVec.capacity() == 10); - - // test insert to end of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(6), 6.0f); - testVec.insert(testVec.end(), 3, testTup); - EATEST_VERIFY(testVec.size() == 12); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 12); - - // test insert to beginning of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(1), 1.0f); - testVec.insert(testVec.begin(), 3, testTup); - EATEST_VERIFY(testVec.size() == 15); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 15); - - // test insert to middle of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(2), 2.0f); - testVec.insert(testVec.begin() + 3, 3, testTup); - EATEST_VERIFY(testVec.size() == 18); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 18); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.get<1>()[i] == TestObject(i / 3 + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with tuple - { - tuple_vector<bool, TestObject, float> testVec; - tuple<bool, TestObject, float> testTup; - testVec.reserve(3); - - // test insert on empty vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(3), 3.0f); - testVec.insert(testVec.begin(), testTup); - EATEST_VERIFY(testVec.size() == 1); - - // test insert to end of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(5), 5.0f); - testVec.insert(testVec.end(), testTup); - EATEST_VERIFY(testVec.size() == 2); - - // test insert to middle of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(4), 4.0f); - testVec.insert(testVec.begin() + 1, testTup); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3); - - // test insert to end of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(6), 6.0f); - testVec.insert(testVec.end(), 1, testTup); - EATEST_VERIFY(testVec.size() == 4); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 4); - - // test insert to beginning of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(1), 1.0f); - testVec.insert(testVec.begin(), 1, testTup); - EATEST_VERIFY(testVec.size() == 5); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 5); - - // test insert to middle of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(2), 2.0f); - testVec.insert(testVec.begin() + 1, 1, testTup); - EATEST_VERIFY(testVec.size() == 6); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 6); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.get<1>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with initList - { - tuple_vector<bool, TestObject, float> testVec; - tuple<bool, TestObject, float> testTup; - testVec.reserve(10); - - // test insert on empty vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(3), 3.0f); - testVec.insert(testVec.begin(), { - {true, TestObject(3), 3.0f}, - testTup, - {true, TestObject(3), 3.0f} - }); - EATEST_VERIFY(testVec.size() == 3); - - // test insert to end of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(5), 5.0f); - testVec.insert(testVec.end(), { - {true, TestObject(5), 5.0f}, - testTup, - {true, TestObject(5), 5.0f} - }); - EATEST_VERIFY(testVec.size() == 6); - - // test insert to middle of vector that doesn't cause growth - testTup = tuple<bool, TestObject, float>(true, TestObject(4), 4.0f); - testVec.insert(testVec.begin() + 3, { - {true, TestObject(4), 4.0f}, - testTup, - {true, TestObject(4), 4.0f} - }); - EATEST_VERIFY(testVec.size() == 9); - EATEST_VERIFY(testVec.capacity() == 10); - - // test insert to end of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(6), 6.0f); - testVec.insert(testVec.end(), { - {true, TestObject(6), 6.0f}, - testTup, - {true, TestObject(6), 6.0f} - }); - EATEST_VERIFY(testVec.size() == 12); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 12); - - // test insert to beginning of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(1), 1.0f); - testVec.insert(testVec.begin(), { - {true, TestObject(1), 1.0f}, - testTup, - {true, TestObject(1), 1.0f} - }); - EATEST_VERIFY(testVec.size() == 15); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 15); - - // test insert to middle of vector that causes growth - testTup = tuple<bool, TestObject, float>(true, TestObject(2), 2.0f); - testVec.insert(testVec.begin() + 3, { - {true, TestObject(2), 2.0f}, - testTup, - {true, TestObject(2), 2.0f - } }); - EATEST_VERIFY(testVec.size() == 18); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 18); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.get<1>()[i] == TestObject(i / 3 + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with rvalue args - { - tuple_vector<int, MoveOnlyType, TestObject> testVec; - testVec.reserve(3); - - // test insert on empty vector that doesn't cause growth - testVec.insert(testVec.begin(), 3, MoveOnlyType(3), TestObject(3)); - EATEST_VERIFY(testVec.size() == 1); - - // test insert to end of vector that doesn't cause growth - testVec.insert(testVec.end(), 5, MoveOnlyType(5), TestObject(5)); - EATEST_VERIFY(testVec.size() == 2); - - // test insert to middle of vector that doesn't cause growth - testVec.insert(testVec.begin() + 1, 4, MoveOnlyType(4), TestObject(4)); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3); - - // test insert to end of vector that causes growth - testVec.insert(testVec.end(), 6, MoveOnlyType(6), TestObject(6)); - EATEST_VERIFY(testVec.size() == 4); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 4); - - // test insert to beginning of vector that causes growth - testVec.insert(testVec.begin(), 1, MoveOnlyType(1), TestObject(1)); - EATEST_VERIFY(testVec.size() == 5); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 5); - - // test insert to middle of vector that causes growth - testVec.insert(testVec.begin() + 1, 2, MoveOnlyType(2), TestObject(2)); - EATEST_VERIFY(testVec.size() == 6); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 6); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.get<2>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with rvalue tuple - { - tuple_vector<int, MoveOnlyType, TestObject> testVec; - testVec.reserve(3); - - // test insert on empty vector that doesn't cause growth - testVec.insert(testVec.begin(), forward_as_tuple(3, MoveOnlyType(3), TestObject(3))); - EATEST_VERIFY(testVec.size() == 1); - - // test insert to end of vector that doesn't cause growth - testVec.insert(testVec.end(), forward_as_tuple(5, MoveOnlyType(5), TestObject(5))); - EATEST_VERIFY(testVec.size() == 2); - - // test insert to middle of vector that doesn't cause growth - testVec.insert(testVec.begin() + 1, forward_as_tuple(4, MoveOnlyType(4), TestObject(4))); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3); - - // test insert to end of vector that causes growth - testVec.insert(testVec.end(), forward_as_tuple(6, MoveOnlyType(6), TestObject(6))); - EATEST_VERIFY(testVec.size() == 4); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 4); - - // test insert to beginning of vector that causes growth - testVec.insert(testVec.begin(), forward_as_tuple(1, MoveOnlyType(1), TestObject(1))); - EATEST_VERIFY(testVec.size() == 5); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 5); - - // test insert to middle of vector that causes growth - testVec.insert(testVec.begin() + 1, forward_as_tuple(2, MoveOnlyType(2), TestObject(2))); - EATEST_VERIFY(testVec.size() == 6); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 6); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.get<2>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test insert with iterator range - { - tuple_vector<bool, TestObject, float> srcVec; - for (unsigned int i = 0; i < 20; ++i) - { - srcVec.push_back(true, TestObject(i), (float)i); - } - - tuple_vector<bool, TestObject, float> testVec; - testVec.reserve(10); - - // test insert on empty vector that doesn't cause growth - testVec.insert(testVec.begin(), srcVec.begin() + 6, srcVec.begin() + 9); - EATEST_VERIFY(testVec.size() == 3); - - // test insert to end of vector that doesn't cause growth - testVec.insert(testVec.end(), srcVec.begin() + 12, srcVec.begin() + 15); - EATEST_VERIFY(testVec.size() == 6); - - // test insert to middle of vector that doesn't cause growth - testVec.insert(testVec.begin() + 3, srcVec.begin() + 9, srcVec.begin() + 12); - EATEST_VERIFY(testVec.size() == 9); - EATEST_VERIFY(testVec.capacity() == 10); - - // test insert to end of vector that causes growth - testVec.insert(testVec.end(), srcVec.begin() + 15, srcVec.begin() + 18); - EATEST_VERIFY(testVec.size() == 12); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 12); - - // test insert to beginning of vector that causes growth - testVec.insert(testVec.begin(), srcVec.begin(), srcVec.begin() + 3); - EATEST_VERIFY(testVec.size() == 15); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 15); - - // test insert to middle of vector that causes growth - testVec.insert(testVec.begin() + 3, srcVec.begin() + 3, srcVec.begin() + 6); - EATEST_VERIFY(testVec.size() == 18); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 18); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - } - EATEST_VERIFY(testVec.validate()); - } - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test assign - { - { - tuple_vector<bool, TestObject, float> testVec; - - // test assign that grows the capacity - testVec.assign(20, true, TestObject(1), 1.0f); - EATEST_VERIFY(testVec.size() == 20); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(1), 1.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 20); - - // test assign that shrinks the vector - testVec.assign(10, true, TestObject(2), 2.0f); - EATEST_VERIFY(testVec.size() == 10); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(2), 2.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 10); - - // test assign for when there's enough capacity - testVec.assign(15, true, TestObject(3), 3.0f); - EATEST_VERIFY(testVec.size() == 15); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(3), 3.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 15); - } - - { - tuple<bool, TestObject, float> srcTup; - tuple_vector<bool, TestObject, float> testVec; - - // test assign from tuple that grows the capacity - srcTup = make_tuple(true, TestObject(1), 1.0f); - testVec.assign(20, srcTup); - EATEST_VERIFY(testVec.size() == 20); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcTup); - } - EATEST_VERIFY(TestObject::sTOCount == 20 + 1); - - // test assign from tuple that shrinks the vector - srcTup = make_tuple(true, TestObject(2), 2.0f); - testVec.assign(10, srcTup); - EATEST_VERIFY(testVec.size() == 10); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcTup); - } - EATEST_VERIFY(TestObject::sTOCount == 10 + 1); - - // test assign from tuple for when there's enough capacity - srcTup = make_tuple(true, TestObject(3), 3.0f); - testVec.assign(15, srcTup); - EATEST_VERIFY(testVec.size() == 15); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcTup); - } - EATEST_VERIFY(TestObject::sTOCount == 15 + 1); - } - - { - tuple_vector<bool, TestObject, float> srcVec; - for (unsigned int i = 0; i < 20; ++i) - { - srcVec.push_back(true, TestObject(i), (float)i); - } - tuple_vector<bool, TestObject, float> testVec; - - // test assign from iter range that grows the capacity - testVec.assign(srcVec.begin() + 5, srcVec.begin() + 15); - EATEST_VERIFY(testVec.size() == 10); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcVec[i+5]); - } - EATEST_VERIFY(TestObject::sTOCount == 10 + 20); - - // test assign from iter range that shrinks the vector - testVec.assign(srcVec.begin() + 2, srcVec.begin() + 7); - EATEST_VERIFY(testVec.size() == 5); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcVec[i + 2]); - } - EATEST_VERIFY(TestObject::sTOCount == 5 + 20); - - // test assign from iter range for when there's enough capacity - testVec.assign(srcVec.begin() + 5, srcVec.begin() + 15); - EATEST_VERIFY(testVec.size() == 10); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == srcVec[i + 5]); - } - EATEST_VERIFY(TestObject::sTOCount == 10 + 20); - } - - { - tuple_vector<bool, TestObject, float> testVec; - - // test assign from initList that grows the capacity - testVec.assign({ - { true, TestObject(1), 1.0f }, - { true, TestObject(2), 2.0f }, - { true, TestObject(3), 3.0f } - }); - EATEST_VERIFY(testVec.size() == 3); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 1), (float)i + 1.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 3); - - // test assign from initList that shrinks the vector - testVec.assign({ - { true, TestObject(4), 4.0f } - }); - EATEST_VERIFY(testVec.size() == 1); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 4), (float)i + 4.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 1); - - // test assign from initList for when there's enough capacity - testVec.assign({ - { true, TestObject(5), 5.0f }, - { true, TestObject(6), 6.0f } - }); - EATEST_VERIFY(testVec.size() == 2); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 5), (float)i + 5.0f)); - } - EATEST_VERIFY(TestObject::sTOCount == 2); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test erase functions - { - { - tuple_vector<bool, TestObject, float> srcVec; - for (unsigned int i = 0; i < 20; ++i) - { - srcVec.push_back(true, TestObject(i), (float)i); - } - tuple_vector<bool, TestObject, float> testVec; - - // test erase on an iter range - testVec.assign(srcVec.begin(), srcVec.end()); - auto eraseIter = testVec.erase(testVec.begin() + 5, testVec.begin() + 10); - EATEST_VERIFY(eraseIter == testVec.begin() + 5); - EATEST_VERIFY(testVec.size() == 15); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i < 5) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 5), (float)(i + 5))); - } - EATEST_VERIFY(TestObject::sTOCount == 15 + 20); - - // test erase on one position - testVec.assign(srcVec.begin(), srcVec.end()); - eraseIter = testVec.erase(testVec.begin() + 5); - EATEST_VERIFY(eraseIter == testVec.begin() + 5); - EATEST_VERIFY(testVec.size() == 19); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i < 5) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 1), (float)(i + 1))); - } - EATEST_VERIFY(TestObject::sTOCount == 19 + 20); - - // test erase_unsorted - testVec.assign(srcVec.begin(), srcVec.end()); - eraseIter = testVec.erase_unsorted(testVec.begin() + 5); - EATEST_VERIFY(eraseIter == testVec.begin() + 5); - EATEST_VERIFY(testVec.size() == 19); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i != 5) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(19), (float)(19))); - } - EATEST_VERIFY(TestObject::sTOCount == 19 + 20); - } - - // test erase again but with reverse iterators everywhere - { - tuple_vector<bool, TestObject, float> srcVec; - for (unsigned int i = 0; i < 20; ++i) - { - srcVec.push_back(true, TestObject(i), (float)i); - } - tuple_vector<bool, TestObject, float> testVec; - - // test erase on an iter range - testVec.assign(srcVec.begin(), srcVec.end()); - auto eraseIter = testVec.erase(testVec.rbegin() + 5, testVec.rbegin() + 10); - EATEST_VERIFY(eraseIter == testVec.rbegin() + 5); - EATEST_VERIFY(testVec.size() == 15); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i < 10) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 5), (float)(i + 5))); - } - EATEST_VERIFY(TestObject::sTOCount == 15 + 20); - - // test erase on one position - testVec.assign(srcVec.begin(), srcVec.end()); - eraseIter = testVec.erase(testVec.rbegin() + 5); - EATEST_VERIFY(eraseIter == testVec.rbegin() + 5); - EATEST_VERIFY(testVec.size() == 19); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i < 14) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i + 1), (float)(i + 1))); - } - EATEST_VERIFY(TestObject::sTOCount == 19 + 20); - - // test erase_unsorted - testVec.assign(srcVec.begin(), srcVec.end()); - eraseIter = testVec.erase_unsorted(testVec.rbegin() + 5); - EATEST_VERIFY(eraseIter == testVec.rbegin() + 5); - EATEST_VERIFY(testVec.size() == 19); - EATEST_VERIFY(testVec.validate()); - for (unsigned int i = 0; i < testVec.size(); ++i) - { - if (i != 14) - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(i), (float)i)); - else - EATEST_VERIFY(testVec[i] == make_tuple(true, TestObject(19), (float)(19))); - } - EATEST_VERIFY(TestObject::sTOCount == 19 + 20); - } - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test multitude of constructors - { - MallocAllocator ma; - TestObject::Reset(); - - // test ctor via initlist to prime srcVec - tuple_vector<bool, TestObject, float> srcVec({ - { true, TestObject(0), 0.0f}, - { false, TestObject(1), 1.0f}, - { false, TestObject(2), 2.0f}, - { true, TestObject(3), 3.0f}, - { false, TestObject(4), 4.0f}, - { false, TestObject(5), 5.0f}, - { true, TestObject(6), 6.0f}, - { false, TestObject(7), 7.0f}, - { false, TestObject(8), 8.0f}, - { true, TestObject(9), 9.0f} - }); - - // copy entire tuple_vector in ctor - { - tuple_vector<bool, TestObject, float> ctorFromConstRef(srcVec); - EATEST_VERIFY(ctorFromConstRef.size() == 10); - EATEST_VERIFY(ctorFromConstRef.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromConstRef.get<0>()[i] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromConstRef.get<1>()[i] == TestObject(i)); - EATEST_VERIFY(ctorFromConstRef.get<2>()[i] == (float)i); - } - } - - // copy entire tuple_vector via assignment - { - tuple_vector<bool, TestObject, float> ctorFromAssignment; - ctorFromAssignment = srcVec; - EATEST_VERIFY(ctorFromAssignment.size() == 10); - EATEST_VERIFY(ctorFromAssignment.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromAssignment.get<0>()[i] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromAssignment.get<1>()[i] == TestObject(i)); - EATEST_VERIFY(ctorFromAssignment.get<2>()[i] == (float)i); - } - } - - // copy entire tuple_vector via assignment of init-list - { - tuple_vector<bool, TestObject, float> ctorFromAssignment; - ctorFromAssignment = { - { true, TestObject(0), 0.0f}, - { false, TestObject(1), 1.0f}, - { false, TestObject(2), 2.0f}, - { true, TestObject(3), 3.0f}, - { false, TestObject(4), 4.0f}, - { false, TestObject(5), 5.0f}, - { true, TestObject(6), 6.0f}, - { false, TestObject(7), 7.0f}, - { false, TestObject(8), 8.0f}, - { true, TestObject(9), 9.0f} - }; - EATEST_VERIFY(ctorFromAssignment.size() == 10); - EATEST_VERIFY(ctorFromAssignment.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromAssignment.get<0>()[i] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromAssignment.get<1>()[i] == TestObject(i)); - EATEST_VERIFY(ctorFromAssignment.get<2>()[i] == (float)i); - } - } - - // ctor tuple_vector with iterator range - { - tuple_vector<bool, TestObject, float> ctorFromIters(srcVec.begin() + 2, srcVec.begin() + 7); - EATEST_VERIFY(ctorFromIters.size() == 5); - EATEST_VERIFY(ctorFromIters.validate()); - for (int i = 2; i < 7; ++i) - { - EATEST_VERIFY(ctorFromIters.get<0>()[i - 2] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromIters.get<1>()[i - 2] == TestObject(i)); - EATEST_VERIFY(ctorFromIters.get<2>()[i - 2] == (float)i); - } - } - - // ctor tuple_vector with initial size - { - tuple_vector<bool, TestObject, float> ctorFromFill(10); - EATEST_VERIFY(ctorFromFill.size() == 10); - EATEST_VERIFY(ctorFromFill.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromFill.get<0>()[i] == false); - EATEST_VERIFY(ctorFromFill.get<1>()[i] == TestObject()); - EATEST_VERIFY(ctorFromFill.get<2>()[i] == 0.0f); - } - } - - // ctor tuple_vector with initial size and args - { - tuple_vector<bool, TestObject, float> ctorFromFillArgs(10, true, TestObject(5), 5.0f); - EATEST_VERIFY(ctorFromFillArgs.size() == 10); - EATEST_VERIFY(ctorFromFillArgs.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromFillArgs.get<0>()[i] == true); - EATEST_VERIFY(ctorFromFillArgs.get<1>()[i] == TestObject(5)); - EATEST_VERIFY(ctorFromFillArgs.get<2>()[i] == 5.0f); - } - } - - // ctor tuple_vector with initial size and tuple - { - tuple<bool, TestObject, float> tup(true, TestObject(5), 5.0f); - tuple_vector<bool, TestObject, float> ctorFromFillTup(10, tup); - EATEST_VERIFY(ctorFromFillTup.size() == 10); - EATEST_VERIFY(ctorFromFillTup.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromFillTup.get<0>()[i] == true); - EATEST_VERIFY(ctorFromFillTup.get<1>()[i] == TestObject(5)); - EATEST_VERIFY(ctorFromFillTup.get<2>()[i] == 5.0f); - } - } - - // ctor tuple_Vector with custom mallocator - { - tuple_vector_alloc<MallocAllocator, bool, TestObject, float> ctorWithAlloc(ma); - tuple_vector<bool, TestObject, float> ctorDefault; - - ctorWithAlloc.push_back(); - ctorDefault.push_back(); - - EATEST_VERIFY(ctorWithAlloc == ctorDefault); - EATEST_VERIFY(ctorWithAlloc.validate()); - } - - // ctor tuple_vector_alloc with copy (from diff. allocator) - { - tuple_vector_alloc<MallocAllocator, bool, TestObject, float> ctorFromConstRef(srcVec, ma); - EATEST_VERIFY(ctorFromConstRef.size() == 10); - EATEST_VERIFY(ctorFromConstRef.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromConstRef.get<0>()[i] == (i % 3 == 0)); - EATEST_VERIFY(ctorFromConstRef.get<1>()[i] == TestObject(i)); - EATEST_VERIFY(ctorFromConstRef.get<2>()[i] == (float)i); - } - EATEST_VERIFY(ctorFromConstRef.validate()); - } - - // ctor tuple_vector with initial size and args - { - tuple_vector_alloc<MallocAllocator, bool, TestObject, float> ctorFromFillArgs(10, true, TestObject(5), 5.0f, ma); - EATEST_VERIFY(ctorFromFillArgs.size() == 10); - EATEST_VERIFY(ctorFromFillArgs.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromFillArgs.get<0>()[i] == true); - EATEST_VERIFY(ctorFromFillArgs.get<1>()[i] == TestObject(5)); - EATEST_VERIFY(ctorFromFillArgs.get<2>()[i] == 5.0f); - } - } - - // ctor tuple_vector via move - { - tuple_vector<int, MoveOnlyType, TestObject> srcMoveVec; - for (int i = 0; i < 10; ++i) - { - srcMoveVec.emplace_back(move(i), MoveOnlyType(i), TestObject(i)); - } - - tuple_vector<int, MoveOnlyType, TestObject> ctorFromMove(move(srcMoveVec)); - - EATEST_VERIFY(ctorFromMove.size() == 10); - EATEST_VERIFY(ctorFromMove.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromMove.get<0>()[i] == i); - EATEST_VERIFY(ctorFromMove.get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(ctorFromMove.get<2>()[i] == TestObject(i)); - } - EATEST_VERIFY(srcMoveVec.size() == 0); - EATEST_VERIFY(srcMoveVec.validate()); - } - - // ctor tuple_vector via move (from diff. allocator) - { - tuple_vector_alloc<MallocAllocator, int, MoveOnlyType, TestObject> srcMoveVec; - for (int i = 0; i < 10; ++i) - { - srcMoveVec.emplace_back(move(i), MoveOnlyType(i), TestObject(i)); - } - - MallocAllocator otherMa; - tuple_vector_alloc<MallocAllocator, int, MoveOnlyType, TestObject> ctorFromMove(move(srcMoveVec), otherMa); - - EATEST_VERIFY(ctorFromMove.size() == 10); - EATEST_VERIFY(ctorFromMove.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromMove.get<0>()[i] == i); - EATEST_VERIFY(ctorFromMove.get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(ctorFromMove.get<2>()[i] == TestObject(i)); - } - EATEST_VERIFY(srcMoveVec.size() == 0); - EATEST_VERIFY(srcMoveVec.validate()); - - // bonus test for specifying a custom allocator, but using the same one as above - tuple_vector_alloc<MallocAllocator, int, MoveOnlyType, TestObject> ctorFromMoveSameAlloc(move(ctorFromMove), otherMa); - EATEST_VERIFY(ctorFromMoveSameAlloc.size() == 10); - EATEST_VERIFY(ctorFromMoveSameAlloc.validate()); - for (int i = 0; i < 10; ++i) - { - EATEST_VERIFY(ctorFromMoveSameAlloc.get<0>()[i] == i); - EATEST_VERIFY(ctorFromMoveSameAlloc.get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(ctorFromMoveSameAlloc.get<2>()[i] == TestObject(i)); - } - EATEST_VERIFY(ctorFromMove.size() == 0); - EATEST_VERIFY(ctorFromMove.validate()); - } - - // ctor tuple_vector via move-iters - { - tuple_vector<int, MoveOnlyType, TestObject> srcMoveVec; - for (int i = 0; i < 10; ++i) - { - srcMoveVec.emplace_back(move(i), MoveOnlyType(i), TestObject(i)); - } - - tuple_vector<int, MoveOnlyType, TestObject> ctorFromMove(make_move_iterator(srcMoveVec.begin() + 2), make_move_iterator(srcMoveVec.begin() + 7)); - - EATEST_VERIFY(ctorFromMove.size() == 5); - EATEST_VERIFY(ctorFromMove.validate()); - for (int i = 2; i < 7; ++i) - { - EATEST_VERIFY(ctorFromMove.get<0>()[i-2] == i); - EATEST_VERIFY(ctorFromMove.get<1>()[i-2] == MoveOnlyType(i)); - EATEST_VERIFY(ctorFromMove.get<2>()[i-2] == TestObject(i)); - } - EATEST_VERIFY(srcMoveVec.size() == 10); - EATEST_VERIFY(srcMoveVec.validate()); - for (int i = 0; i < 2; ++i) - { - EATEST_VERIFY(srcMoveVec.get<0>()[i] == i); - EATEST_VERIFY(srcMoveVec.get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(srcMoveVec.get<2>()[i] == TestObject(i)); - } - for (int i = 2; i < 7; ++i) - { - EATEST_VERIFY(srcMoveVec.get<0>()[i] == i); // int's just get copied because they're POD - EATEST_VERIFY(srcMoveVec.get<1>()[i] == MoveOnlyType(0)); - EATEST_VERIFY(srcMoveVec.get<2>()[i] == TestObject(0)); - } - for (int i = 7; i < 10; ++i) - { - EATEST_VERIFY(srcMoveVec.get<0>()[i] == i); - EATEST_VERIFY(srcMoveVec.get<1>()[i] == MoveOnlyType(i)); - EATEST_VERIFY(srcMoveVec.get<2>()[i] == TestObject(i)); - } - } - - srcVec.clear(); - EATEST_VERIFY(TestObject::IsClear()); - - TestObject::Reset(); - } - - // Test swap - { - tuple_vector<int, float, bool> complexVec; - complexVec.push_back(3, 2.0f, true); - complexVec.push_back(1, 4.0f, false); - complexVec.push_back(2, 1.0f, true); - complexVec.push_back(4, 3.0f, false); - - tuple_vector<int, float, bool> otherComplexVec; - complexVec.swap(otherComplexVec); - - EATEST_VERIFY(complexVec.size() == 0); - EATEST_VERIFY(complexVec.validate()); - EATEST_VERIFY(otherComplexVec.validate()); - EATEST_VERIFY(otherComplexVec.get<0>()[0] == 3); - EATEST_VERIFY(otherComplexVec.get<float>()[1] == 4.0f); - - complexVec.push_back(10, 10.0f, true); - swap(complexVec, otherComplexVec); - - EATEST_VERIFY(complexVec.validate()); - EATEST_VERIFY(*(complexVec.get<0>()) == 3); - EATEST_VERIFY(complexVec.get<float>()[1] == 4.0f); - - EATEST_VERIFY(otherComplexVec.validate()); - EATEST_VERIFY(otherComplexVec.get<float>()[0] == 10.0f); - EATEST_VERIFY(otherComplexVec.size() == 1); - - } - - - // Test tuple_Vector in a ranged for, and other large-scale iterator testing - { - tuple_vector<int, float, int> tripleElementVec; - tripleElementVec.push_back(1, 2.0f, 6); - tripleElementVec.push_back(2, 3.0f, 7); - tripleElementVec.push_back(3, 4.0f, 8); - tripleElementVec.push_back(4, 5.0f, 9); - tripleElementVec.push_back(5, 6.0f, 10); - - - // test copyConstructible, copyAssignable, swappable, prefix inc, !=, reference convertible to value_type (InputIterator!) - { - tuple_vector<int, float, int>::iterator iter = tripleElementVec.begin(); - ++iter; - auto copiedIter(iter); - EATEST_VERIFY(get<2>(*copiedIter) == 7); - EATEST_VERIFY(copiedIter == iter); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(copiedIter) != isf_none); - - ++iter; - copiedIter = iter; - EATEST_VERIFY(get<2>(*copiedIter) == 8); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(copiedIter) != isf_none); - - ++iter; - swap(iter, copiedIter); - EATEST_VERIFY(get<2>(*iter) == 8); - EATEST_VERIFY(get<2>(*copiedIter) == 9); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(copiedIter) != isf_none); - - EATEST_VERIFY(copiedIter != iter); - - tuple<const int&, const float&, const int&> ref(*iter); - tuple<int, float, int> value(*iter); - EATEST_VERIFY(get<2>(ref) == get<2>(value)); - } - - // test postfix increment, default constructible (ForwardIterator) - { - tuple_vector<int, float, int>::iterator iter = tripleElementVec.begin(); - auto prefixIter = ++iter; - - tuple_vector<int, float, int>::iterator postfixIter; - postfixIter = iter++; - EATEST_VERIFY(prefixIter == postfixIter); - EATEST_VERIFY(get<2>(*prefixIter) == 7); - EATEST_VERIFY(get<2>(*iter) == 8); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(prefixIter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(postfixIter) != isf_none); - } - - // test prefix decrement and postfix decrement (BidirectionalIterator) - { - tuple_vector<int, float, int>::iterator iter = tripleElementVec.end(); - auto prefixIter = --iter; - - tuple_vector<int, float, int>::iterator postfixIter; - postfixIter = iter--; - EATEST_VERIFY(prefixIter == postfixIter); - EATEST_VERIFY(get<2>(*prefixIter) == 10); - EATEST_VERIFY(get<2>(*iter) == 9); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(prefixIter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(postfixIter) != isf_none); - } - - // test many arithmetic operations (RandomAccessIterator) - { - tuple_vector<int, float, int>::iterator iter = tripleElementVec.begin(); - auto symmetryOne = iter + 2; - auto symmetryTwo = 2 + iter; - iter += 2; - EATEST_VERIFY(symmetryOne == symmetryTwo); - EATEST_VERIFY(symmetryOne == iter); - - symmetryOne = iter - 2; - symmetryTwo = 2 - iter; - iter -= 2; - EATEST_VERIFY(symmetryOne == symmetryTwo); - EATEST_VERIFY(symmetryOne == iter); - - iter += 2; - EATEST_VERIFY(iter - symmetryOne == 2); - - tuple<int&, float&, int&> symmetryRef = symmetryOne[2]; - EATEST_VERIFY(get<2>(symmetryRef) == get<2>(*iter)); - - EATEST_VERIFY(symmetryOne < iter); - EATEST_VERIFY(iter > symmetryOne); - EATEST_VERIFY(symmetryOne >= symmetryTwo && iter >= symmetryOne); - EATEST_VERIFY(symmetryOne <= symmetryTwo && symmetryOne <= iter); - EATEST_VERIFY(tripleElementVec.validate_iterator(iter) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(symmetryOne) != isf_none); - EATEST_VERIFY(tripleElementVec.validate_iterator(symmetryTwo) != isf_none); - } - - // test simple iteration, and reverse iteration - { - float i = 0; - int j = 0; - EATEST_VERIFY(&get<0>(*tripleElementVec.begin()) == tripleElementVec.get<0>()); - EATEST_VERIFY(&get<1>(*tripleElementVec.begin()) == tripleElementVec.get<1>()); - for (auto iter : tripleElementVec) - { - i += get<1>(iter); - j += get<2>(iter); - } - EATEST_VERIFY(i == 20.0f); - EATEST_VERIFY(j == 40); - - float reverse_i = 0; - int reverse_j = 0; - - eastl::for_each(tripleElementVec.rbegin(), tripleElementVec.rend(), - [&](const tuple<int, float, int> tup) - { - reverse_i += get<1>(tup); - reverse_j += get<2>(tup); - }); - EATEST_VERIFY(i == reverse_i); - EATEST_VERIFY(j == reverse_j); - EATEST_VERIFY(get<0>(*tripleElementVec.rbegin()) == 5); - } - } - - // Test move operations - { - TestObject::Reset(); - - // test emplace - { - tuple_vector<int, MoveOnlyType, TestObject> testVec; - testVec.reserve(3); - - // test emplace on empty vector that doesn't cause growth - testVec.emplace(testVec.begin(), 3, MoveOnlyType(3), TestObject(3)); - EATEST_VERIFY(testVec.size() == 1); - - // test emplace to end of vector that doesn't cause growth - testVec.emplace(testVec.end(), 5, MoveOnlyType(5), TestObject(5)); - EATEST_VERIFY(testVec.size() == 2); - - // test emplace to middle of vector that doesn't cause growth - testVec.emplace(testVec.begin() + 1, 4, MoveOnlyType(4), TestObject(4)); - EATEST_VERIFY(testVec.size() == 3); - EATEST_VERIFY(testVec.capacity() == 3); - - // test emplace to end of vector that causes growth - testVec.emplace(testVec.end(), 6, MoveOnlyType(6), TestObject(6)); - EATEST_VERIFY(testVec.size() == 4); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 4); - - // test emplace to beginning of vector that causes growth - testVec.emplace(testVec.begin(), 1, MoveOnlyType(1), TestObject(1)); - EATEST_VERIFY(testVec.size() == 5); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 5); - - // test emplace to middle of vector that causes growth - testVec.emplace(testVec.begin() + 1, 2, MoveOnlyType(2), TestObject(2)); - EATEST_VERIFY(testVec.size() == 6); - testVec.shrink_to_fit(); - EATEST_VERIFY(testVec.capacity() == 6); - - for (unsigned int i = 0; i < testVec.size(); ++i) - { - EATEST_VERIFY(testVec.get<2>()[i] == TestObject(i + 1)); - } - EATEST_VERIFY(testVec.validate()); - } - - // test some other miscellania around rvalues, including... - // push_back with rvalue args, push_back with rvalue tuple, - // emplace_back with args, and emplace_back with tup - { - tuple_vector<int, MoveOnlyType, TestObject> v1; - tuple_vector<int, MoveOnlyType, TestObject> v2; - // add some data in the vector so we can move it to the other vector. - v1.reserve(5); - auto emplacedTup = v1.emplace_back(1, MoveOnlyType(1), TestObject(1)); - EATEST_VERIFY(emplacedTup == v1.back()); - v1.push_back(3, MoveOnlyType(3), TestObject(3)); - v1.emplace_back(forward_as_tuple(5, MoveOnlyType(5), TestObject(5))); - v1.push_back(forward_as_tuple(6, MoveOnlyType(6), TestObject(6))); - v1.emplace(v1.begin() + 1, 2, MoveOnlyType(2), TestObject(2)); - v1.emplace(v1.begin() + 3, make_tuple(4, MoveOnlyType(4), TestObject(4))); - - tuple<int&, MoveOnlyType&, TestObject&> movedTup = v1.at(0); - EATEST_VERIFY(v1.validate()); - EATEST_VERIFY(get<0>(movedTup) == 1); - EATEST_VERIFY(get<0>(*v1.begin()) == 1); - - for (int i = 0; i < static_cast<int>(v1.size()); ++i) - { - EATEST_VERIFY(v1.get<0>()[i] == i + 1); - } - EATEST_VERIFY(!v1.empty() && v2.empty()); - v2 = eastl::move(v1); - EATEST_VERIFY(v2.validate()); - EATEST_VERIFY(v1.empty() && !v2.empty()); - v1.swap(v2); - EATEST_VERIFY(v1.validate()); - EATEST_VERIFY(v2.validate()); - EATEST_VERIFY(!v1.empty() && v2.empty()); - } - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test comparisons - { - MallocAllocator ma; - tuple_vector<bool, TestObject, float> equalsVec1, equalsVec2; - for (int i = 0; i < 10; ++i) - { - equalsVec1.push_back(i % 3 == 0, TestObject(i), (float)i); - equalsVec2.push_back(i % 3 == 0, TestObject(i), (float)i); - } - EATEST_VERIFY(equalsVec1 == equalsVec2); - - tuple_vector<bool, TestObject, float> smallSizeVec(5); - tuple_vector<bool, TestObject, float> lessThanVec(10); - tuple_vector_alloc<MallocAllocator, bool, TestObject, float> greaterThanVec(10, ma); - for (int i = 0; i < 10; ++i) - { - lessThanVec.push_back(i % 3 == 0, TestObject(i), (float)i); - greaterThanVec.push_back(i % 3 == 0, TestObject(i * 2), (float)i * 2); - } - EATEST_VERIFY(equalsVec1 != smallSizeVec); - EATEST_VERIFY(equalsVec1 != lessThanVec); - EATEST_VERIFY(equalsVec1 != greaterThanVec); - EATEST_VERIFY(lessThanVec < greaterThanVec); - EATEST_VERIFY(greaterThanVec > lessThanVec); - EATEST_VERIFY(lessThanVec <= greaterThanVec); - EATEST_VERIFY(equalsVec1 <= equalsVec2); - EATEST_VERIFY(equalsVec1 >= equalsVec2); - } - - // Test partition - { - { - tuple_vector<bool, TestObject, float, MoveOnlyType> vec; - for (int i = 0; i < 10; ++i) - { - vec.push_back(i % 3 == 0, TestObject(i), (float)i, MoveOnlyType(i)); - } - - eastl::partition(vec.begin(), vec.end(), [](tuple<bool&, TestObject&, float&, MoveOnlyType&> a) - { return get<0>(a) == true; }); - - // partition will split the array into 4 elements where the bool property is true, and 6 where it's false - for (int i = 0; i < 4; ++i) - EATEST_VERIFY(vec.get<0>()[i] == true); - for (int i = 4; i < 10; ++i) - EATEST_VERIFY(vec.get<0>()[i] == false); - - EATEST_VERIFY(vec.validate()); - EATEST_VERIFY(TestObject::sTOCount == 10); - } - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - // Test allocator manipulation - { - InstanceAllocator ia0((uint8_t)0), ia1((uint8_t)1); - tuple_vector_alloc<InstanceAllocator, int> vec(ia0); - - // private vector allocator was copied from ia0 and should have matching id - EATEST_VERIFY(vec.get_allocator() == ia0); - - // Assigning allocator - vec.set_allocator(ia1); - EATEST_VERIFY(vec.get_allocator() == ia1); - } - - return nErrorCount; -} - - diff --git a/test/source/TestTypeTraits.cpp b/test/source/TestTypeTraits.cpp deleted file mode 100644 index 2670e24..0000000 --- a/test/source/TestTypeTraits.cpp +++ /dev/null @@ -1,2439 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/type_traits.h> -#include <EASTL/vector.h> -#include <EAStdC/EAAlignment.h> -#include "ConceptImpls.h" - - - -using namespace eastl; - - -bool GetType(const true_type&) -{ - return true; -} - -bool GetType(const false_type&) -{ - return false; -} - -int GetType(const integral_constant<size_t, (size_t)4>&) -{ - return 4; -} - -int GetType(const integral_constant<size_t, (size_t)8>&) -{ - return 8; -} - -int GetType(const integral_constant<size_t, (size_t)16>&) -{ - return 16; -} - -int GetType(const integral_constant<size_t, (size_t)32>&) -{ - return 32; -} - -#ifdef _MSC_VER - __declspec(align(32)) class ClassAlign32{ }; -#else - class ClassAlign32{ } __attribute__((aligned(32))); -#endif - - -struct Struct -{ - // Empty -}; - -class Class -{ - // Empty -}; - -class Subclass : public Class -{ - // Empty -}; - -class ClassEmpty -{ - // Empty -}; - -class ClassNonEmpty -{ -public: - int x; -}; - -enum Enum -{ - kValue1 -}; - -union Union -{ - int x; - short y; -}; - -struct FinalStruct final -{ -}; - -class FinalClass final -{ -}; - -#if !EASTL_TYPE_TRAIT_is_union_CONFORMANCE - EASTL_DECLARE_UNION(Union) // We have to do this because is_union simply cannot work without user help. -#endif - - - -// Used for union_cast tests below. -// C++11 allows for PodA/PodB to have a trivial default (i.e. compiler-generated) constructor, -// but as of this writing (3/2012) most C++ compilers don't have support for this yet. -struct PodA{ - int mX; -}; - -struct PodB{ - int mX; -}; - -bool operator ==(const PodA& a1, const PodA& a2) { return (a1.mX == a2.mX); } - - -// std::tr1::is_volatile<T>::value == true if and only if, for a given type T: -// * std::tr1::is_scalar<T>::value == true, or -// * T is a class or struct that has no user-defined copy assignment operator or destructor, -// and T has no non-static data members M for which is_pod<M>::value == false, and no members of reference type, or -// * T is the type of an array of objects E for which is_pod<E>::value == true -// is_pod may only be applied to complete types. - -struct Pod1 -{ - // Empty -}; -#if !EASTL_TYPE_TRAIT_is_pod_CONFORMANCE - EASTL_DECLARE_POD(Pod1) // We have to do this because is_pod simply cannot work without user help. -#endif -#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE - EASTL_DECLARE_STANDARD_LAYOUT(Pod1) // We have to do this because is_standard_layout simply cannot work without user help. -#endif - - -struct Pod2 -{ - int mX; - Pod1 mPod1; -}; -#if !EASTL_TYPE_TRAIT_is_pod_CONFORMANCE - EASTL_DECLARE_POD(Pod2) -#endif -#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE - EASTL_DECLARE_STANDARD_LAYOUT(Pod2) -#endif - -struct Pod3 -{ - Pod2 mPod2; - int mX; - Pod1 mPod1; -}; -#if !EASTL_TYPE_TRAIT_is_pod_CONFORMANCE - EASTL_DECLARE_POD(Pod3) -#endif -#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE - EASTL_DECLARE_STANDARD_LAYOUT(Pod3) -#endif - - -struct NonPod1 -{ - NonPod1(){} - virtual ~NonPod1(){} -}; - -struct NonPod2 -{ - virtual ~NonPod2(){} - virtual void Function(){} -}; - -struct HasIncrementOperator { HasIncrementOperator& operator++() { return *this; } }; - -template <class T> -using has_increment_operator_detection = decltype(++eastl::declval<T>()); - -template<typename, typename = eastl::void_t<>> -struct has_increment_operator_using_void_t : eastl::false_type {}; - -template <typename T> -struct has_increment_operator_using_void_t<T, eastl::void_t<has_increment_operator_detection<T>>> : eastl::true_type {}; - - -// We use this for the is_copy_constructible test in order to verify that -// is_copy_constructible in fact returns false for this type and not true. -// std::is_copy_constructible specification: std::is_constructible<T, const T&>::value is true. -// Note that the specification refers to const T& and not T&. So we rig our class to -// accept T& and not const T&. This situation is significant because as of this -// writing the clang <type_traits> implementation appears to be broken and mis-implements -// the is_copy_constructible type trait to return true for ConstructibleOnlyWithNonConstReference -// when in fact it should return false. -EA_DISABLE_VC_WARNING(4521) // disable warning : "multiple copy constructors specified" -struct ConstructibleOnlyWithNonConstReference -{ - ConstructibleOnlyWithNonConstReference(ConstructibleOnlyWithNonConstReference&) {} - - #if defined(EA_COMPILER_NO_DELETED_FUNCTIONS) - private: ConstructibleOnlyWithNonConstReference() {} - private: ConstructibleOnlyWithNonConstReference(const ConstructibleOnlyWithNonConstReference&) {} - #else - ConstructibleOnlyWithNonConstReference() = delete; - ConstructibleOnlyWithNonConstReference(const ConstructibleOnlyWithNonConstReference&) = delete; - #endif -}; -EA_RESTORE_VC_WARNING() - -#if defined(EA_COMPILER_NO_NOEXCEPT) - //This is needed because VS2013 supports is_nothrow__xxx type traits but doesn't support C++11 noexcept. - //So we use throw() to allow the is_nothrow_xxxx and similiar tests to work in VS2013 - #define EASTL_TEST_NOEXCEPT throw() -#else - #define EASTL_TEST_NOEXCEPT EA_NOEXCEPT -#endif - -struct ThrowConstructibleTest -{ - ThrowConstructibleTest(const int = 0) EASTL_TEST_NOEXCEPT { } - ThrowConstructibleTest(const float) EA_NOEXCEPT_IF(false) { } -}; - - - -struct NoThrowAssignable { }; - -struct ThrowAssignableTest -{ - void operator=(const NoThrowAssignable&) EASTL_TEST_NOEXCEPT { } - void operator=(const ThrowAssignableTest&) { } -}; - - -struct NoThrowDestructible -{ - ~NoThrowDestructible() EASTL_TEST_NOEXCEPT {} -}; - -#if !defined(EA_COMPILER_NO_EXCEPTIONS) - struct ThrowDestructible - { - ~ThrowDestructible() noexcept(false) { throw(int()); } - }; - - struct ThrowDestructibleNoexceptFalse - { - virtual ~ThrowDestructibleNoexceptFalse() EA_NOEXCEPT_IF(false) { } - }; -#endif - - -struct HasTrivialConstructor -{ - int x; -}; -#if !EASTL_TYPE_TRAIT_has_trivial_constructor_CONFORMANCE - EASTL_DECLARE_TRIVIAL_CONSTRUCTOR(HasTrivialConstructor) // We have to do this because has_trivial_constructor simply cannot work without user help. -#endif -#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE - EASTL_DECLARE_STANDARD_LAYOUT(HasTrivialConstructor) -#endif - - -struct NoTrivialConstructor -{ - NoTrivialConstructor() { px = &x; } - int x; - int* px; -}; -#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE - EASTL_DECLARE_STANDARD_LAYOUT(NoTrivialConstructor) -#endif - - -struct HasTrivialCopy -{ - void Function(){} - int x; -}; -#if !EASTL_TYPE_TRAIT_has_trivial_constructor_CONFORMANCE - EASTL_DECLARE_TRIVIAL_COPY(HasTrivialCopy) // We have to do this because has_trivial_copy simply cannot work without user help. -#endif - - -#if defined(EA_COMPILER_MSVC) && (_MSC_VER == 1900) - // http://blogs.msdn.com/b/vcblog/archive/2014/06/06/c-14-stl-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1.aspx - // VS2015-preview has a bug regarding C++14 implicit noexcept rules for destructors. We explicitly define noexcept below for VS2015-preview only. - // - // Re-evaluate when VS2015 RTM has been released. - // - struct NoTrivialCopy1 - { - virtual ~NoTrivialCopy1() EASTL_TEST_NOEXCEPT {} - virtual void Function(){} - }; -#else - struct NoTrivialCopy1 - { - virtual ~NoTrivialCopy1() {} - virtual void Function(){} - }; -#endif - -struct NoTrivialCopy2 -{ - NoTrivialCopy1 ntv; -}; - -struct NonCopyable -{ - NonCopyable() : mX(0) {} - NonCopyable(int x) : mX(x) {} - - int mX; - - EA_NON_COPYABLE(NonCopyable) -}; - -struct HasTrivialAssign -{ - void Function(){} - int x; -}; -#if !EASTL_TYPE_TRAIT_has_trivial_assign_CONFORMANCE - EASTL_DECLARE_TRIVIAL_ASSIGN(HasTrivialAssign) // We have to do this because has_trivial_assign simply cannot work without user help. -#endif - -struct NoTrivialAssign1 -{ - virtual ~NoTrivialAssign1(){} - virtual void Function(){} -}; - -struct NoTrivialAssign2 -{ - NoTrivialAssign1 nta; -}; - -struct Polymorphic1 -{ - virtual ~Polymorphic1(){} - virtual void Function(){} -}; - -struct Polymorphic2 : public Polymorphic1 -{ - // Empty -}; - -struct Polymorphic3 -{ - virtual ~Polymorphic3(){} - virtual void Function() = 0; -}; - -struct NonPolymorphic1 -{ - void Function(){} -}; - -// Disable the following warning: -// warning: ‘struct Abstract’ has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor] -// We explicitly want this class not to have a virtual destructor to test our type traits. -EA_DISABLE_VC_WARNING(4265) -EA_DISABLE_CLANG_WARNING(-Wnon-virtual-dtor) -EA_DISABLE_GCC_WARNING(-Wnon-virtual-dtor) -struct Abstract -{ - virtual void Function() = 0; -}; -EA_RESTORE_GCC_WARNING() -EA_RESTORE_CLANG_WARNING() -EA_RESTORE_VC_WARNING() - -struct AbstractWithDtor -{ - virtual ~AbstractWithDtor(){} - virtual void Function() = 0; -}; - -struct DeletedDtor -{ - #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) - ~DeletedDtor() = delete; - #endif -}; - -#if (EASTL_TYPE_TRAIT_is_destructible_CONFORMANCE == 0) - EASTL_DECLARE_IS_DESTRUCTIBLE(DeletedDtor, false) -#endif - -struct Assignable -{ - void operator=(const Assignable&){} - void operator=(const Pod1&){} -}; - -class HiddenAssign -{ -public: - HiddenAssign(); - -private: - HiddenAssign(const HiddenAssign& x); - HiddenAssign& operator=(const HiddenAssign& x); -}; - -#if !EASTL_TYPE_TRAIT_has_trivial_assign_CONFORMANCE - EASTL_DECLARE_TRIVIAL_ASSIGN(HiddenAssign) -#endif - - - -// This class exercises is_convertible for the case that the class has an explicit copy constructor. -struct IsConvertibleTest1 -{ - IsConvertibleTest1() {} - IsConvertibleTest1(int, int) {} - explicit IsConvertibleTest1(const IsConvertibleTest1&) {} - ~IsConvertibleTest1(){} -}; - - - -// Helpers for enable_if tests -template<typename T> -typename eastl::enable_if<eastl::is_floating_point<T>::value, T>::type EnableIfTestFunction(T) - { return 999; } - -template<typename T> -typename eastl::enable_if<eastl::is_integral<T>::value, T>::type EnableIfTestFunction(T) - { return 888; } - -template<typename T> -typename eastl::disable_if<eastl::is_signed<T>::value, T>::type EnableIfTestFunction(T) - { return 777; } - - - -// Test that EASTL_DECLARE_TRIVIAL_ASSIGN can be used to get around case whereby -// the copy constructor and operator= are private. Normally vector requires this. -// ** This is disabled because it turns out that vector in fact requires the -// constructor for some uses. But we have code below which tests just part of vector. -// template class eastl::vector<HiddenAssign>; - - -typedef char Array[32]; -typedef const char ArrayConst[32]; - - -typedef Class& Reference; -typedef const Class& ConstReference; - - -typedef const int ConstInt; -typedef int Int; -typedef volatile int VolatileInt; -typedef const volatile int ConstVolatileInt; -typedef int& IntReference; -typedef const int& ConstIntReference; // Note here that the int is const, not the reference to the int. -typedef const volatile int& ConstVolatileIntReference; // Note here that the int is const, not the reference to the int. - - -typedef void FunctionVoidVoid(); -typedef int FunctionIntVoid(); -typedef int FunctionIntFloat(float); -typedef void (*FunctionVoidVoidPtr)(); - -namespace -{ - const eastl::string gEmptyStringInstance(""); - - const eastl::integral_constant<int*, nullptr> gIntNullptrConstant; - static_assert(gIntNullptrConstant() == nullptr, ""); -} - -int TestTypeTraits() -{ - int nErrorCount = 0; - - - // static_min / static_max - #if EASTL_TYPE_TRAIT_static_min_CONFORMANCE - static_assert((static_min<3, 7, 1, 5>::value == 1), "static_min failure"); - static_assert((static_max<3, 7, 1, 5>::value == 7), "static_max failure"); - #else - static_assert((static_min<7, 1>::value == 1), "static_min failure"); - static_assert((static_max<7, 1>::value == 7), "static_max failure"); - #endif - - // enable_if, disable_if. - EATEST_VERIFY((EnableIfTestFunction((double)1.1) == 999)); - EATEST_VERIFY((EnableIfTestFunction((int)1) == 888)); - EATEST_VERIFY((EnableIfTestFunction((int)-4) == 888)); - - - // conditional - static_assert(sizeof(conditional<true, int8_t, int16_t>::type) == sizeof(int8_t), "conditional failure"); - static_assert(sizeof(conditional<false, int8_t, int16_t>::type) == sizeof(int16_t), "conditional failure"); - - // bool_constant - static_assert(bool_constant<is_same<int, int>::value>::value == true, "bool_constant failure"); - static_assert(bool_constant<is_same<int, short>::value>::value == false, "bool_constant failure"); - static_assert(is_same<bool_constant<false>::type, integral_constant<bool, false>::type>::value, "bool_constant failure"); - - - - // identity - static_assert(sizeof(identity<int>::type) == sizeof(int), "identity failure"); - static_assert((is_same<int, identity<int>::type >::value == true), "identity failure"); - - // type_identity - static_assert(sizeof(type_identity<int>::type) == sizeof(int), "type_identity failure"); - static_assert((is_same<int, type_identity<int>::type >::value == true), "type_identity failure"); - static_assert(sizeof(type_identity_t<int>) == sizeof(int), "type_identity failure"); - static_assert((is_same_v<int, type_identity_t<int>> == true), "type_identity failure"); - - - - // is_void - static_assert(is_void<void>::value == true, "is_void failure"); - static_assert(is_void<const void>::value == true, "is_void failure"); - static_assert(is_void<int>::value == false, "is_void failure"); - - - // is_null_pointer - #if defined(EA_COMPILER_CPP11_ENABLED) - #if !defined(EA_COMPILER_NO_DECLTYPE) && !defined(_MSC_VER) // VS2012 is broken for just the case of decltype(nullptr). - static_assert(is_null_pointer<decltype(nullptr)>::value == true, "is_null_pointer failure"); - static_assert(is_null_pointer<decltype(NULL)>::value == false, "is_null_pointer failure"); - #endif - #if defined(EA_HAVE_nullptr_t_IMPL) - static_assert(is_null_pointer<std::nullptr_t>::value == true, "is_null_pointer failure"); // Can't enable this until we are using an updated <EABase/nullptr.h> that is savvy to C++11 clang (defines nullptr) being used with C++98 GNU libstdc++ (defines std::nullptr_t). - #endif - static_assert(is_null_pointer<void*>::value == false, "is_null_pointer failure"); - static_assert(is_null_pointer<intptr_t>::value == false, "is_null_pointer failure"); - #endif - - // is_integral - static_assert(is_integral<int>::value == true, "is_integral failure"); - EATEST_VERIFY(GetType(is_integral<int>()) == true); - - static_assert(is_integral<const int>::value == true, "is_integral failure"); - EATEST_VERIFY(GetType(is_integral<const int>()) == true); - - static_assert(is_integral<float>::value == false, "is_integral failure"); - EATEST_VERIFY(GetType(is_integral<float>()) == false); - - static_assert(is_integral<bool>::value, "is_integral failure"); - static_assert(is_integral<char8_t>::value, "is_integral failure"); - static_assert(is_integral<char16_t>::value, "is_integral failure"); - static_assert(is_integral<char32_t>::value, "is_integral failure"); - static_assert(is_integral<char>::value, "is_integral failure"); - static_assert(is_integral<int>::value, "is_integral failure"); - static_assert(is_integral<long long>::value, "is_integral failure"); - static_assert(is_integral<long>::value, "is_integral failure"); - static_assert(is_integral<short>::value, "is_integral failure"); - static_assert(is_integral<signed char>::value, "is_integral failure"); - static_assert(is_integral<unsigned char>::value, "is_integral failure"); - static_assert(is_integral<unsigned int>::value, "is_integral failure"); - static_assert(is_integral<unsigned long long>::value, "is_integral failure"); - static_assert(is_integral<unsigned long>::value, "is_integral failure"); - static_assert(is_integral<unsigned short>::value, "is_integral failure"); -#ifndef EA_WCHAR_T_NON_NATIVE // If wchar_t is a native type instead of simply a define to an existing type which is already handled... - static_assert(is_integral<wchar_t>::value, "is_integral failure"); -#endif - - - // is_floating_point - static_assert(is_floating_point<double>::value == true, "is_floating_point failure"); - EATEST_VERIFY(GetType(is_floating_point<double>()) == true); - - static_assert(is_floating_point<const double>::value == true, "is_floating_point failure"); - EATEST_VERIFY(GetType(is_floating_point<const double>()) == true); - - static_assert(is_floating_point<int>::value == false, "is_floating_point failure"); - EATEST_VERIFY(GetType(is_floating_point<int>()) == false); - - - // is_arithmetic - static_assert(is_arithmetic<float>::value == true, "is_arithmetic failure"); - static_assert(is_arithmetic_v<float> == true, "is_arithmetic failure"); - EATEST_VERIFY(GetType(is_arithmetic<float>()) == true); - - static_assert(is_arithmetic<Class>::value == false, "is_arithmetic failure"); - static_assert(is_arithmetic_v<Class> == false, "is_arithmetic failure"); - EATEST_VERIFY(GetType(is_arithmetic<Class>()) == false); - - - // is_fundamental - static_assert(is_fundamental<void>::value == true, "is_fundamental failure"); - static_assert(is_fundamental_v<void> == true, "is_fundamental failure"); - EATEST_VERIFY(GetType(is_fundamental<void>()) == true); - - #ifndef EA_WCHAR_T_NON_NATIVE // If wchar_t is a native type instead of simply a define to an existing type which is already handled... - static_assert(is_fundamental<wchar_t>::value == true, "is_fundamental failure"); - static_assert(is_fundamental_v<wchar_t> == true, "is_fundamental failure"); - EATEST_VERIFY(GetType(is_fundamental<wchar_t>()) == true); - #endif - - static_assert(is_fundamental<Class>::value == false, "is_fundamental failure"); - static_assert(is_fundamental_v<Class> == false, "is_fundamental failure"); - EATEST_VERIFY(GetType(is_fundamental<Class>()) == false); - - static_assert(is_fundamental<std::nullptr_t>::value == true, "is_fundamental failure"); - static_assert(is_fundamental_v<std::nullptr_t> == true, "is_fundamental failure"); - - - // is_array - static_assert(is_array<Array>::value == true, "is_array failure"); - EATEST_VERIFY(GetType(is_array<Array>()) == true); - - static_assert(is_array<ArrayConst>::value == true, "is_array failure"); - EATEST_VERIFY(GetType(is_array<ArrayConst>()) == true); - - static_assert(is_array<int[]>::value == true, "is_array failure"); - - static_assert(is_array<uint32_t>::value == false, "is_array failure"); - EATEST_VERIFY(GetType(is_array<uint32_t>()) == false); - - static_assert(is_array<uint32_t*>::value == false, "is_array failure"); - EATEST_VERIFY(GetType(is_array<uint32_t*>()) == false); - - - //is_bounded_array - static_assert(is_bounded_array<Array>::value == true, "is_bounded_array failure"); - EATEST_VERIFY(GetType(is_bounded_array<Array>()) == true); - - static_assert(is_bounded_array<ArrayConst>::value == true, "is_bounded_array failure"); - EATEST_VERIFY(GetType(is_bounded_array<ArrayConst>()) == true); - - static_assert(is_bounded_array<int>::value == false, "is_bounded_array failure"); - static_assert(is_bounded_array<int[32]>::value == true, "is_bounded_array failure"); - static_assert(is_bounded_array<int[]>::value == false, "is_bounded_array failure"); - - static_assert(is_bounded_array<uint32_t>::value == false, "is_bounded_array failure"); - EATEST_VERIFY(GetType(is_bounded_array<uint32_t>()) == false); - - static_assert(is_bounded_array<uint32_t*>::value == false, "is_bounded_array failure"); - EATEST_VERIFY(GetType(is_bounded_array<uint32_t*>()) == false); - - - //is_unbounded_array - static_assert(is_unbounded_array<Array>::value == false, "is_unbounded_array failure"); - EATEST_VERIFY(GetType(is_unbounded_array<Array>()) == false); - - static_assert(is_unbounded_array<ArrayConst>::value == false, "is_unbounded_array failure"); - EATEST_VERIFY(GetType(is_unbounded_array<ArrayConst>()) == false); - - static_assert(is_unbounded_array<int>::value == false, "is_unbounded_array failure"); - static_assert(is_unbounded_array<int[32]>::value == false, "is_unbounded_array failure"); - static_assert(is_unbounded_array<int[]>::value == true, "is_unbounded_array failure"); - - static_assert(is_unbounded_array<uint32_t>::value == false, "is_unbounded_array failure"); - EATEST_VERIFY(GetType(is_unbounded_array<uint32_t>()) == false); - - static_assert(is_unbounded_array<uint32_t*>::value == false, "is_unbounded_array failure"); - EATEST_VERIFY(GetType(is_unbounded_array<uint32_t*>()) == false); - - - // is_reference - static_assert(is_reference<Class&>::value == true, "is_reference failure"); - EATEST_VERIFY(GetType(is_reference<Class&>()) == true); - - static_assert(is_reference<Class&&>::value == true, "is_reference failure"); - EATEST_VERIFY(GetType(is_reference<Class&&>()) == true); - - static_assert(is_reference<const Class&>::value == true, "is_reference failure"); - EATEST_VERIFY(GetType(is_reference<const Class&>()) == true); - - static_assert(is_reference<const Class&&>::value == true, "is_reference failure"); - EATEST_VERIFY(GetType(is_reference<const Class&&>()) == true); - - static_assert(is_reference<Class>::value == false, "is_reference failure"); - EATEST_VERIFY(GetType(is_reference<Class>()) == false); - - static_assert(is_reference<const Class*>::value == false, "is_reference failure"); - EATEST_VERIFY(GetType(is_reference<const Class*>()) == false); - - - // is_member_function_pointer - static_assert(is_member_function_pointer<int>::value == false, "is_member_function_pointer failure"); - static_assert(is_member_function_pointer<int(Class::*)>::value == false, "is_member_function_pointer failure"); - static_assert(is_member_function_pointer<int(Class::*)()>::value == true, "is_member_function_pointer failure"); - static_assert(is_member_function_pointer<int(Class::*)(...)>::value == true, "is_member_function_pointer failure"); - static_assert(is_member_function_pointer<int(Class::*)() noexcept>::value == true, "is_member_function_pointer failure"); - static_assert(is_member_function_pointer<int(Class::*)() &>::value == true, "is_member_function_pointer failure"); - static_assert(is_member_function_pointer<int(Class::*)() &&>::value == true, "is_member_function_pointer failure"); - - - // is_member_object_pointer - static_assert(is_member_object_pointer<int>::value == false, "is_member_object_pointer failure"); - static_assert(is_member_object_pointer<int(Class::*)>::value == true, "is_member_object_pointer failure"); - static_assert(is_member_object_pointer<int(Class::*)()>::value == false, "is_member_object_pointer failure"); - - - // is_member_pointer - static_assert(is_member_pointer<int>::value == false, "is_member_pointer failure"); - static_assert(is_member_pointer<int(Class::*)>::value == true, "is_member_pointer failure"); - static_assert(is_member_pointer<int(Class::*)()>::value == true, "is_member_pointer failure"); - static_assert(is_member_pointer<int(Class::* const)>::value == true, "is_member_pointer failure"); - static_assert(is_member_pointer<int(Class::* volatile)>::value == true, "is_member_pointer failure"); - static_assert(is_member_pointer<int(Class::* const volatile)>::value == true, "is_member_pointer failure"); - - - // is_pointer - static_assert(is_pointer<Class*>::value == true, "is_pointer failure"); - static_assert(is_pointer<const Class*>::value == true, "is_pointer failure"); - static_assert(is_pointer<Class>::value == false, "is_pointer failure"); - static_assert(is_pointer<const Class&>::value == false, "is_pointer failure"); - #if defined(EA_HAVE_nullptr_t_IMPL) - static_assert(is_pointer<std::nullptr_t>::value == false, "is_pointer failure"); - #endif - - // is_enum - static_assert(is_enum<Enum>::value == true, "is_enum failure "); - static_assert(is_enum_v<Enum> == true, "is_enum failure "); - EATEST_VERIFY(GetType(is_enum<Enum>()) == true); - - static_assert(is_enum<const Enum>::value == true, "is_enum failure "); - static_assert(is_enum_v<const Enum> == true, "is_enum failure "); - EATEST_VERIFY(GetType(is_enum<const Enum>()) == true); - - static_assert(is_enum<Enum*>::value == false, "is_enum failure "); - static_assert(is_enum_v<Enum*> == false, "is_enum failure "); - EATEST_VERIFY(GetType(is_enum<Enum*>()) == false); - - static_assert(is_enum<Class>::value == false, "is_enum failure "); - static_assert(is_enum_v<Class> == false, "is_enum failure "); - EATEST_VERIFY(GetType(is_enum<Class>()) == false); - - static_assert(is_enum<Enum&>::value == false, "is_enum failure "); - static_assert(is_enum_v<Enum&> == false, "is_enum failure "); - EATEST_VERIFY(GetType(is_enum<Enum&>()) == false); - - static_assert(is_enum<Enum&&>::value == false, "is_enum failure "); - static_assert(is_enum_v<Enum&&> == false, "is_enum failure "); - EATEST_VERIFY(GetType(is_enum<Enum&&>()) == false); - - - // is_union - static_assert(is_union<Union>::value == true, "is_union failure"); - static_assert(is_union_v<Union> == true, "is_union failure"); - EATEST_VERIFY(GetType(is_union<Union>()) == true); - - static_assert(is_union<int>::value == false, "is_union failure"); - static_assert(is_union_v<int> == false, "is_union failure"); - EATEST_VERIFY(GetType(is_union<int>()) == false); - - - // is_class - static_assert(is_class<Class>::value == true, "is_class failure"); - EATEST_VERIFY(GetType(is_class<Class>()) == true); - - static_assert(is_class<Struct>::value == true, "is_class failure"); - EATEST_VERIFY(GetType(is_class<Struct>()) == true); - - static_assert(is_class<Union>::value == false, "is_class failure"); - EATEST_VERIFY(GetType(is_class<Union>()) == false); - - static_assert(is_class<Enum>::value == false, "is_class failure"); - EATEST_VERIFY(GetType(is_class<Enum>()) == false); - - static_assert(is_class<int*>::value == false, "is_class failure"); - EATEST_VERIFY(GetType(is_class<int*>()) == false); - - - // is_function - static_assert(is_function<void>::value == false, "is_function failure"); - static_assert(is_function<FunctionVoidVoid>::value == true, "is_function failure"); - static_assert(is_function<FunctionVoidVoid&>::value == false, "is_function failure"); - static_assert(is_function<FunctionIntVoid>::value == true, "is_function failure"); - static_assert(is_function<FunctionIntFloat>::value == true, "is_function failure"); - static_assert(is_function<FunctionVoidVoidPtr>::value == false, "is_function failure"); - static_assert(is_function<int>::value == false, "is_function failure"); - static_assert(is_function<int[3]>::value == false, "is_function failure"); - static_assert(is_function<int[]>::value == false, "is_function failure"); - static_assert(is_function<Class>::value == false, "is_function failure"); - #if EASTL_TYPE_TRAIT_is_function_CONFORMANCE - // typedef int PrintfConst(const char*, ...) const; - static_assert(is_function<int (const char*, ...)>::value == true, "is_function failure"); // This is the signature of printf. - #endif - - static_assert(is_function<int (float)>::value == true, "is_function failure"); - static_assert(is_function<int (float) const>::value == true, "is_function failure"); - static_assert(is_function<int(float) volatile>::value == true, "is_function failure"); - static_assert(is_function<int(float) const volatile>::value == true, "is_function failure"); - static_assert(is_function<int(float)&>::value == true, "is_function failure"); - static_assert(is_function<int(float)&&>::value == true, "is_function failure"); - static_assert(is_function<int(float) noexcept>::value == true, "is_function failure"); - static_assert(is_function<FunctionIntFloat &>::value == false, "is_function failure"); // reference to function, not a l-value reference qualified function - static_assert(is_function<FunctionIntFloat &&>::value == false, "is_function failure"); - - static_assert(is_function_v<void> == false, "is_function failure"); - static_assert(is_function_v<FunctionVoidVoid> == true, "is_function failure"); - static_assert(is_function_v<FunctionVoidVoid&> == false, "is_function failure"); - static_assert(is_function_v<FunctionIntVoid> == true, "is_function failure"); - static_assert(is_function_v<FunctionIntFloat> == true, "is_function failure"); - static_assert(is_function_v<FunctionVoidVoidPtr> == false, "is_function failure"); - static_assert(is_function_v<int> == false, "is_function failure"); - static_assert(is_function_v<int[3]> == false, "is_function failure"); - static_assert(is_function_v<int[]> == false, "is_function failure"); - static_assert(is_function_v<Class> == false, "is_function failure"); - #if EASTL_TYPE_TRAIT_is_function_CONFORMANCE - // typedef int PrintfConst(const char*, ...) const; - static_assert(is_function_v<int (const char*, ...)> == true, "is_function failure"); // This is the signature of printf. - #endif - - - // is_object - static_assert(is_object<int>::value == true, "is_object failure"); - EATEST_VERIFY(GetType(is_object<int>()) == true); - - static_assert(is_object<Class>::value == true, "is_object failure"); - EATEST_VERIFY(GetType(is_object<Class>()) == true); - - static_assert(is_object<Class*>::value == true, "is_object failure"); - EATEST_VERIFY(GetType(is_object<Class*>()) == true); - - static_assert(is_object<Class&>::value == false, "is_object failure"); - EATEST_VERIFY(GetType(is_object<Class&>()) == false); - - static_assert(is_object<Class&&>::value == false, "is_object failure"); - EATEST_VERIFY(GetType(is_object<Class&&>()) == false); - - - // is_scalar - static_assert(is_scalar<int>::value == true, "is_scalar failure"); - EATEST_VERIFY(GetType(is_scalar<int>()) == true); - - static_assert(is_scalar<double>::value == true, "is_scalar failure"); - EATEST_VERIFY(GetType(is_scalar<double>()) == true); - - static_assert(is_scalar<Enum>::value == true, "is_scalar failure"); - EATEST_VERIFY(GetType(is_scalar<Enum>()) == true); - - static_assert(is_scalar<const Class*>::value == true, "is_scalar failure"); - EATEST_VERIFY(GetType(is_scalar<const Class*>()) == true); - - static_assert(is_scalar<std::nullptr_t>::value == true, "is_scalar failure"); - - - // is_compound - static_assert(is_compound<Class>::value == true, "is_compound failure"); - EATEST_VERIFY(GetType(is_compound<Class>()) == true); - - static_assert(is_compound<const Class&>::value == true, "is_compound failure"); - EATEST_VERIFY(GetType(is_compound<const Class&>()) == true); - - static_assert(is_compound<int*>::value == true, "is_compound failure"); - EATEST_VERIFY(GetType(is_compound<int*>()) == true); - - static_assert(is_compound<float>::value == false, "is_compound failure"); - EATEST_VERIFY(GetType(is_compound<float>()) == false); - - static_assert(is_compound<bool>::value == false, "is_compound failure"); - EATEST_VERIFY(GetType(is_compound<bool>()) == false); - - - // is_const - static_assert(is_const<Int>::value == false, "is_const failure"); - EATEST_VERIFY(GetType(is_const<Int>()) == false); - - static_assert(is_const<ConstInt>::value == true, "is_const failure"); - EATEST_VERIFY(GetType(is_const<ConstInt>()) == true); - - static_assert(is_const<VolatileInt>::value == false, "is_const failure"); - EATEST_VERIFY(GetType(is_const<VolatileInt>()) == false); - - static_assert(is_const<ConstVolatileInt>::value == true, "is_const failure"); - EATEST_VERIFY(GetType(is_const<ConstVolatileInt>()) == true); - - static_assert(is_const<IntReference>::value == false, "is_const failure"); - EATEST_VERIFY(GetType(is_const<IntReference>()) == false); - - static_assert(is_const<ConstIntReference>::value == false, "is_const failure"); // Note here that the int is const, not the reference to the int. - EATEST_VERIFY(GetType(is_const<ConstIntReference>()) == false); - - static_assert(is_const<ConstVolatileIntReference>::value == false, "is_const failure"); // Note here that the int is const, not the reference to the int. - EATEST_VERIFY(GetType(is_const<ConstVolatileIntReference>()) == false); - - static_assert(is_const<void() const>::value == false, "is_const failure"); - EATEST_VERIFY(GetType(is_const<void() const>()) == false); - - // is_volatile - static_assert(is_volatile<Int>::value == false, "is_volatile failure"); - EATEST_VERIFY(GetType(is_volatile<Int>()) == false); - - static_assert(is_volatile<ConstInt>::value == false, "is_volatile failure"); - EATEST_VERIFY(GetType(is_volatile<ConstInt>()) == false); - - static_assert(is_volatile<VolatileInt>::value == true, "is_volatile failure"); - EATEST_VERIFY(GetType(is_volatile<VolatileInt>()) == true); - - static_assert(is_volatile<ConstVolatileInt>::value == true, "is_volatile failure"); - EATEST_VERIFY(GetType(is_volatile<ConstVolatileInt>()) == true); - - static_assert(is_volatile<IntReference>::value == false, "is_volatile failure"); - EATEST_VERIFY(GetType(is_volatile<IntReference>()) == false); - - static_assert(is_volatile<ConstIntReference>::value == false, "is_volatile failure"); - EATEST_VERIFY(GetType(is_volatile<ConstIntReference>()) == false); - - static_assert(is_volatile<ConstVolatileIntReference>::value == false, "is_volatile failure"); // Note here that the int is volatile, not the reference to the int. - EATEST_VERIFY(GetType(is_volatile<ConstVolatileIntReference>()) == false); - - static_assert(is_volatile<void() const>::value == false, "is_volatile failure"); - EATEST_VERIFY(GetType(is_volatile<void() const>()) == false); - - - // underlying_type and to_underlying - #if EASTL_TYPE_TRAIT_underlying_type_CONFORMANCE && !defined(EA_COMPILER_NO_STRONGLY_TYPED_ENUMS) // If we can execute this test... - enum UnderlyingTypeTest : uint16_t { firstVal = 0, secondVal = 1 }; - - constexpr bool isUnderlyingTypeCorrect = is_same_v<underlying_type_t<UnderlyingTypeTest>, uint16_t>; - static_assert(isUnderlyingTypeCorrect, "Wrong type for underlying_type_t."); - EATEST_VERIFY(isUnderlyingTypeCorrect); - - auto v1 = to_underlying(UnderlyingTypeTest::firstVal); - auto v2 = to_underlying(UnderlyingTypeTest::secondVal); - - constexpr bool isToUnderlyingReturnTypeCorrect = is_same_v<decltype(v1), uint16_t>; - static_assert(isToUnderlyingReturnTypeCorrect, "Wrong return type for to_underlying."); - EATEST_VERIFY(isToUnderlyingReturnTypeCorrect); - - EATEST_VERIFY(v1 == 0 && v2 == 1); - #endif - - - // is_literal_type - static_assert((is_literal_type<int>::value == true), "is_literal_type failure"); - static_assert((is_literal_type<Enum>::value == true), "is_literal_type failure"); - #if EASTL_TYPE_TRAIT_is_literal_type_CONFORMANCE - static_assert((is_literal_type<PodA>::value == true), "is_literal_type failure"); - static_assert((is_literal_type<NonPod1>::value == false), "is_literal_type failure"); - #endif - - - // is_trivial - // is_trivially_copyable - // is_trivially_default_constructible - #if EASTL_TYPE_TRAIT_is_trivial_CONFORMANCE - static_assert(is_trivial<Pod1>::value == true, "is_trivial failure"); - static_assert(is_trivial<NonPod1>::value == false, "is_trivial failure"); - #endif - - - // is_pod - static_assert(is_pod<Pod1>::value == true, "is_pod failure"); - EATEST_VERIFY(GetType(is_pod<Pod1>()) == true); - - static_assert(is_pod<Pod2>::value == true, "is_pod failure"); - EATEST_VERIFY(GetType(is_pod<Pod2>()) == true); - - static_assert(is_pod<Pod3>::value == true, "is_pod failure"); - EATEST_VERIFY(GetType(is_pod<Pod3>()) == true); - - static_assert(is_pod<float>::value == true, "is_pod failure"); - EATEST_VERIFY(GetType(is_pod<float>()) == true); - - static_assert(is_pod<Pod1*>::value == true, "is_pod failure"); - EATEST_VERIFY(GetType(is_pod<Pod1*>()) == true); - - static_assert(is_pod<NonPod1>::value == false, "is_pod failure"); - EATEST_VERIFY(GetType(is_pod<NonPod1>()) == false); - - static_assert(is_pod<NonPod2>::value == false, "is_pod failure"); - EATEST_VERIFY(GetType(is_pod<NonPod2>()) == false); - - - // is_standard_layout - static_assert(is_standard_layout<Pod1>::value == true, "is_standard_layout<Pod1> failure"); - static_assert(is_standard_layout_v<Pod1> == true, "is_standard_layout<Pod1> failure"); - EATEST_VERIFY(GetType(is_standard_layout<Pod1>()) == true); - - static_assert(is_standard_layout<Pod2>::value == true, "is_standard_layout<Pod2> failure"); - static_assert(is_standard_layout_v<Pod2> == true, "is_standard_layout<Pod2> failure"); - EATEST_VERIFY(GetType(is_standard_layout<Pod2>()) == true); - - static_assert(is_standard_layout<Pod3>::value == true, "is_standard_layout<Pod3> failure"); - static_assert(is_standard_layout_v<Pod3> == true, "is_standard_layout<Pod3> failure"); - EATEST_VERIFY(GetType(is_standard_layout<Pod3>()) == true); - - static_assert(is_standard_layout<float>::value == true, "is_standard_layout<float> failure"); - static_assert(is_standard_layout_v<float> == true, "is_standard_layout<float> failure"); - EATEST_VERIFY(GetType(is_standard_layout<float>()) == true); - - static_assert(is_standard_layout<Pod1*>::value == true, "is_standard_layout<Pod1*> failure"); - static_assert(is_standard_layout_v<Pod1*> == true, "is_standard_layout<Pod1*> failure"); - EATEST_VERIFY(GetType(is_standard_layout<Pod1*>()) == true); - - static_assert(is_standard_layout<NonPod1>::value == false, "is_standard_layout<NonPod1> failure"); - static_assert(is_standard_layout_v<NonPod1> == false, "is_standard_layout<NonPod1> failure"); - EATEST_VERIFY(GetType(is_standard_layout<NonPod1>()) == false); - - static_assert(is_standard_layout<NonPod2>::value == false, "is_standard_layout<NonPod2> failure"); - static_assert(is_standard_layout_v<NonPod2> == false, "is_standard_layout<NonPod2> failure"); - EATEST_VERIFY(GetType(is_standard_layout<NonPod2>()) == false); - - static_assert(is_standard_layout<HasTrivialConstructor>::value == true, "is_standard_layout<HasTrivialConstructor> failure"); - static_assert(is_standard_layout_v<HasTrivialConstructor> == true, "is_standard_layout<HasTrivialConstructor> failure"); - EATEST_VERIFY(GetType(is_standard_layout<HasTrivialConstructor>()) == true); - - static_assert(is_standard_layout<NoTrivialConstructor>::value == true, "is_standard_layout<NoTrivialConstructor> failure"); // A key difference between a POD and Standard Layout is that the latter is true if there is a constructor. - static_assert(is_standard_layout_v<NoTrivialConstructor> == true, "is_standard_layout<NoTrivialConstructor> failure"); // A key difference between a POD and Standard Layout is that the latter is true if there is a constructor. - EATEST_VERIFY(GetType(is_standard_layout<NoTrivialConstructor>()) == true); - - - // is_empty - static_assert(is_empty<ClassEmpty>::value == true, "is_empty failure"); - EATEST_VERIFY(GetType(is_empty<ClassEmpty>()) == true); - - static_assert(is_empty<ClassNonEmpty>::value == false, "is_empty failure"); - EATEST_VERIFY(GetType(is_empty<ClassNonEmpty>()) == false); - - static_assert(is_empty<int>::value == false, "is_empty failure"); - EATEST_VERIFY(GetType(is_empty<int>()) == false); - - static_assert(is_empty<Enum>::value == false, "is_empty failure"); - EATEST_VERIFY(GetType(is_empty<Enum>()) == false); - - - // is_polymorphic - static_assert(is_polymorphic<Polymorphic1>::value == true, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(is_polymorphic<Polymorphic1>()) == true); - - static_assert(is_polymorphic<Polymorphic2>::value == true, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(is_polymorphic<Polymorphic2>()) == true); - - static_assert(is_polymorphic<Polymorphic3>::value == true, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(is_polymorphic<Polymorphic3>()) == true); - - static_assert(is_polymorphic<NonPolymorphic1>::value == false, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(is_polymorphic<NonPolymorphic1>()) == false); - - static_assert(is_polymorphic<int>::value == false, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(is_polymorphic<int>()) == false); - - static_assert(is_polymorphic<Polymorphic1*>::value == false, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(is_polymorphic<Polymorphic1*>()) == false); - - - // has_trivial_constructor - static_assert(has_trivial_constructor<int>::value == true, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(has_trivial_constructor<int>()) == true); - - static_assert(has_trivial_constructor<int*>::value == true, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(has_trivial_constructor<int*>()) == true); - - static_assert(has_trivial_constructor<HasTrivialConstructor>::value == true, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(has_trivial_constructor<HasTrivialConstructor>()) == true); - - static_assert(has_trivial_constructor<NoTrivialConstructor>::value == false, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(has_trivial_constructor<NoTrivialConstructor>()) == false); - - static_assert(has_trivial_constructor<int&>::value == false, "has_trivial_constructor failure"); - EATEST_VERIFY(GetType(has_trivial_constructor<int&>()) == false); - - - // has_trivial_copy - static_assert(has_trivial_copy<int>::value == true, "has_trivial_copy failure"); - EATEST_VERIFY(GetType(has_trivial_copy<int>()) == true); - - static_assert(has_trivial_copy<int*>::value == true, "has_trivial_copy failure"); - EATEST_VERIFY(GetType(has_trivial_copy<int*>()) == true); - - static_assert(has_trivial_copy<HasTrivialCopy>::value == true, "has_trivial_copy failure"); - EATEST_VERIFY(GetType(has_trivial_copy<HasTrivialCopy>()) == true); - - static_assert(has_trivial_copy<NoTrivialCopy1>::value == false, "has_trivial_copy failure"); - EATEST_VERIFY(GetType(has_trivial_copy<NoTrivialCopy1>()) == false); - - static_assert(has_trivial_copy<NoTrivialCopy2>::value == false, "has_trivial_copy failure"); - EATEST_VERIFY(GetType(has_trivial_copy<NoTrivialCopy2>()) == false); - - - // has_trivial_assign - static_assert(has_trivial_assign<int>::value == true, "has_trivial_assign failure"); - EATEST_VERIFY(GetType(has_trivial_assign<int>()) == true); - - static_assert(has_trivial_assign<int*>::value == true, "has_trivial_assign failure"); - EATEST_VERIFY(GetType(has_trivial_assign<int*>()) == true); - - static_assert(has_trivial_assign<HasTrivialAssign>::value == true, "has_trivial_assign failure"); - EATEST_VERIFY(GetType(has_trivial_assign<HasTrivialAssign>()) == true); - - static_assert(has_trivial_assign<NoTrivialAssign1>::value == false, "has_trivial_assign failure"); - EATEST_VERIFY(GetType(has_trivial_assign<NoTrivialAssign1>()) == false); - - static_assert(has_trivial_assign<NoTrivialAssign2>::value == false, "has_trivial_assign failure"); - EATEST_VERIFY(GetType(has_trivial_assign<NoTrivialAssign2>()) == false); - - - // has_trivial_destructor - static_assert(has_trivial_assign<int>::value == true, "has_trivial_relocate failure"); - EATEST_VERIFY(GetType(has_trivial_assign<int>()) == true); - - static_assert(has_trivial_assign<int*>::value == true, "has_trivial_relocate failure"); - EATEST_VERIFY(GetType(has_trivial_assign<int*>()) == true); - - - // has_trivial_relocate - static_assert(has_trivial_relocate<int>::value == true, "has_trivial_relocate failure"); - EATEST_VERIFY(GetType(has_trivial_relocate<int>()) == true); - - static_assert(has_trivial_relocate<int*>::value == true, "has_trivial_relocate failure"); - EATEST_VERIFY(GetType(has_trivial_relocate<int*>()) == true); - - - // is_signed - static_assert(is_signed<int>::value == true, "is_signed failure "); - static_assert(is_signed_v<int> == true, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<int>()) == true); - - static_assert(is_signed<const int64_t>::value == true, "is_signed failure "); - static_assert(is_signed_v<const int64_t> == true, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<const int64_t>()) == true); - - static_assert(is_signed<uint32_t>::value == false, "is_signed failure "); - static_assert(is_signed_v<uint32_t> == false, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<uint32_t>()) == false); - - static_assert(is_signed<bool>::value == false, "is_signed failure "); - static_assert(is_signed_v<bool> == false, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<bool>()) == false); - - static_assert(is_signed<float>::value == true, "is_signed failure "); - static_assert(is_signed_v<float> == true, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<float>()) == true); - - static_assert(is_signed<double>::value == true, "is_signed failure "); - static_assert(is_signed_v<double> == true, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<double>()) == true); - - static_assert(is_signed<char16_t>::value == false, "is_signed failure "); - static_assert(is_signed_v<char16_t> == false, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<char16_t>()) == false); - - static_assert(is_signed<char32_t>::value == false, "is_signed failure "); - static_assert(is_signed_v<char32_t> == false, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<char32_t>()) == false); - -#if EASTL_GCC_STYLE_INT128_SUPPORTED - static_assert(is_signed<__int128_t>::value == true, "is_signed failure "); - static_assert(is_signed_v<__int128_t> == true, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<__int128_t>()) == true); - - static_assert(is_signed<__uint128_t>::value == false, "is_signed failure "); - static_assert(is_signed_v<__uint128_t> == false, "is_signed failure "); - EATEST_VERIFY(GetType(is_signed<__uint128_t>()) == false); -#endif - - // is_unsigned - static_assert(is_unsigned<unsigned int>::value == true, "is_unsigned failure "); - static_assert(is_unsigned_v<unsigned int> == true, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<unsigned int>()) == true); - - static_assert(is_unsigned<const uint64_t>::value == true, "is_unsigned failure "); - static_assert(is_unsigned_v<const uint64_t> == true, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<const uint64_t>()) == true); - - static_assert(is_unsigned<int32_t>::value == false, "is_unsigned failure "); - static_assert(is_unsigned_v<int32_t> == false, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<int32_t>()) == false); - - static_assert(is_unsigned<bool>::value == true, "is_unsigned failure "); - static_assert(is_unsigned_v<bool> == true, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<bool>()) == true); - - static_assert(is_unsigned<float>::value == false, "is_unsigned failure "); - static_assert(is_unsigned_v<float> == false, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<float>()) == false); - - static_assert(is_unsigned<double>::value == false, "is_unsigned failure "); - static_assert(is_unsigned_v<double> == false, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<double>()) == false); - - static_assert(is_unsigned<char16_t>::value == true, "is_unsigned failure "); - static_assert(is_unsigned_v<char16_t> == true, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<char16_t>()) == true); - - static_assert(is_unsigned<char32_t>::value == true, "is_unsigned failure "); - static_assert(is_unsigned_v<char32_t> == true, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<char32_t>()) == true); - -#if EASTL_GCC_STYLE_INT128_SUPPORTED - static_assert(is_unsigned<__int128_t>::value == false, "is_unsigned failure "); - static_assert(is_unsigned_v<__int128_t> == false, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<__int128_t>()) == false); - - static_assert(is_unsigned<__uint128_t>::value == true, "is_unsigned failure "); - static_assert(is_unsigned_v<__uint128_t> == true, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<__uint128_t>()) == true); -#endif - - - // is_lvalue_reference - static_assert((is_lvalue_reference<Class>::value == false), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference<Class&>::value == true), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference<Class&&>::value == false), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference<int>::value == false), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference<int&>::value == true), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference<int&&>::value == false), "is_lvalue_reference failure"); - - static_assert((is_lvalue_reference_v<Class> == false), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference_v<Class&> == true), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference_v<Class&&> == false), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference_v<int> == false), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference_v<int&> == true), "is_lvalue_reference failure"); - static_assert((is_lvalue_reference_v<int&&> == false), "is_lvalue_reference failure"); - - - // is_rvalue_reference - static_assert((is_rvalue_reference<Class>::value == false), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference<Class&>::value == false), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference<Class&&>::value == true), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference<int>::value == false), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference<int&>::value == false), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference<int&&>::value == true), "is_rvalue_reference failure"); - - static_assert((is_rvalue_reference_v<Class> == false), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference_v<Class&> == false), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference_v<Class&&> == true), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference_v<int> == false), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference_v<int&> == false), "is_rvalue_reference failure"); - static_assert((is_rvalue_reference_v<int&&> == true), "is_rvalue_reference failure"); - - - // is_assignable - // See the documentation for is_assignable to understand the results below are as they are. - static_assert((eastl::is_assignable<int&, int>::value == true), "is_assignable failure"); - static_assert((eastl::is_assignable<const int&, int>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<char*, int*>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<char*, const char*>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<PodA, PodB*>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<Assignable, Pod2>::value == false), "is_assignable failure"); - - #if EASTL_TYPE_TRAIT_is_assignable_CONFORMANCE - // These might not succeed unless the implementation is conforming. - static_assert((eastl::is_assignable<Assignable, Assignable>::value == true), "is_assignable failure"); - static_assert((eastl::is_assignable<Assignable, Pod1>::value == true), "is_assignable failure"); - static_assert((eastl::is_assignable<PodA&, PodA>::value == true), "is_assignable failure"); - - // These cannot succeed unless the implementation is conforming. - static_assert((eastl::is_assignable<void, void>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<int, int>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<int, const int>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<const int, int>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<int, int&>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<int64_t, int8_t>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<bool, bool>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<char*, char*>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<int, float>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<const char*, char*>::value == false), "is_assignable failure"); - static_assert((eastl::is_assignable<int[], int[]>::value == false), "is_assignable failure"); - #endif - - - // is_lvalue_assignable - static_assert((eastl::is_lvalue_assignable<int&, int>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<char*, int*>::value == false), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<char*, const char*>::value == false), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<PodA, PodB*>::value == false), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<Assignable, Pod2>::value == false), "is_lvalue_assignable failure"); - - #if EASTL_TYPE_TRAIT_is_lvalue_assignable_CONFORMANCE - // These might not succeed unless the implementation is conforming. - static_assert((eastl::is_lvalue_assignable<Assignable, Assignable>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<Assignable, Pod1>::value == true), "is_lvalue_assignable failure"); - - // These cannot succeed unless the implementation is conforming. - static_assert((eastl::is_lvalue_assignable<void, void>::value == false), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<int, int>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<int, const int>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<const int, int>::value == false), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<int, int&>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<int64_t, int8_t>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<bool, bool>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<char*, char*>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<const char*, char*>::value == true), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<int[], int[]>::value == false), "is_lvalue_assignable failure"); - static_assert((eastl::is_lvalue_assignable<int[3], int[3]>::value == false), "is_lvalue_assignable failure"); // Despite that you can memcpy these, C++ syntax doesn't all =-based assignment. - - #if !defined(EA_COMPILER_EDG) // EDG (and only EDG) is issuing int8_t->double conversion warnings from the decltype expression inside this trait. That's probably a compiler bug, though we need to verify. - static_assert((eastl::is_lvalue_assignable<double, int8_t>::value == true), "is_lvalue_assignable failure"); // Sure this might generate a warning, but it's valid syntax. - #endif - #endif - - - // is_copy_assignable - static_assert((eastl::is_copy_assignable<int&>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<char>::value == true), "is_copy_assignable failure"); - - #if EASTL_TYPE_TRAIT_is_assignable_CONFORMANCE - // These might not succeed unless the implementation is conforming. - static_assert((eastl::is_copy_assignable<Assignable>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<Assignable>::value == true), "is_copy_assignable failure"); - - // These cannot succeed unless the implementation is conforming. - static_assert((eastl::is_copy_assignable<char*>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<PodA>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<Assignable>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<void>::value == false), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<int>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<const int>::value == false), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<int64_t>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<bool>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<char*>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<const char*>::value == true), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<int[3]>::value == false), "is_copy_assignable failure"); - static_assert((eastl::is_copy_assignable<int[]>::value == false), "is_copy_assignable failure"); - #endif - - - // is_trivially_assignable - static_assert((eastl::is_trivially_assignable<int&, int>::value == true), "is_trivially_assignable failure"); - static_assert((eastl::is_trivially_assignable<char*, int*>::value == false), "is_trivially_assignable failure"); - static_assert((eastl::is_trivially_assignable<char*, const char*>::value == false), "is_trivially_assignable failure"); - static_assert((eastl::is_trivially_assignable<PodA, PodB*>::value == false), "is_trivially_assignable failure"); - static_assert((eastl::is_trivially_assignable<Assignable, Assignable>::value == false), "is_trivially_assignable failure"); // False because not trivial. - static_assert((eastl::is_trivially_assignable<Assignable, Pod1>::value == false), "is_trivially_assignable failure"); // False because not trivial. - static_assert((eastl::is_trivially_assignable<Assignable, Pod2>::value == false), "is_trivially_assignable failure"); - - // is_nothrow_assignable - static_assert((is_nothrow_assignable<void, void>::value == false), "is_nothrow_assignable failure"); - static_assert((is_nothrow_assignable<int32_t, int32_t>::value == false), "is_nothrow_assignable failure"); // See is_assignable for why this is so. - static_assert((is_nothrow_assignable<int32_t&, int32_t>::value == true), "is_nothrow_assignable failure"); - static_assert((is_nothrow_assignable<int32_t, int8_t>::value == false), "is_nothrow_assignable failure"); - #if EASTL_TYPE_TRAIT_is_nothrow_assignable_CONFORMANCE - static_assert((is_nothrow_assignable<int32_t&, int8_t>::value == true), "is_nothrow_assignable failure"); - static_assert((is_nothrow_assignable<NoThrowAssignable, NoThrowAssignable>::value == true), "is_nothrow_assignable failure"); - static_assert((is_nothrow_assignable<ThrowAssignableTest, NoThrowAssignable>::value == true), "is_nothrow_assignable failure"); - static_assert((is_nothrow_assignable<ThrowAssignableTest, ThrowAssignableTest>::value == false), "is_nothrow_assignable failure"); - #endif - - - // is_array_of_known_bounds - // is_array_of_unknown_bounds - static_assert(is_array_of_known_bounds<void>::value == false, "is_array_of_known_bounds failure"); - static_assert(is_array_of_known_bounds<int>::value == false, "is_array_of_known_bounds failure"); - static_assert(is_array_of_known_bounds<PodA>::value == false, "is_array_of_known_bounds failure"); - static_assert(is_array_of_known_bounds<int[3]>::value == true, "is_array_of_known_bounds failure"); - static_assert(is_array_of_known_bounds<int[]>::value == false, "is_array_of_known_bounds failure"); - - static_assert(is_array_of_unknown_bounds<void>::value == false, "is_array_of_known_bounds failure"); - static_assert(is_array_of_unknown_bounds<int>::value == false, "is_array_of_known_bounds failure"); - static_assert(is_array_of_unknown_bounds<PodA>::value == false, "is_array_of_known_bounds failure"); - static_assert(is_array_of_unknown_bounds<int[3]>::value == false, "is_array_of_known_bounds failure"); - static_assert(is_array_of_unknown_bounds<int[]>::value == true, "is_array_of_known_bounds failure"); - - - // is_trivially_copyable - static_assert(is_trivially_copyable<void>::value == false, "is_trivially_copyable failure"); - EATEST_VERIFY(GetType(is_trivially_copyable<void>()) == false); - static_assert(is_trivially_copyable<int>::value == true, "is_trivially_copyable failure"); - static_assert(is_trivially_copyable<int*>::value == true, "is_trivially_copyable failure"); - static_assert(is_trivially_copyable<int[]>::value == true, "is_trivially_copyable failure"); - static_assert(is_trivially_copyable<int[4]>::value == true, "is_trivially_copyable failure"); - #if EASTL_TYPE_TRAIT_is_trivially_copyable_CONFORMANCE - static_assert(is_trivially_copyable<NonPod1>::value == false, "is_trivially_copyable failure"); - static_assert(is_trivially_copyable<NoTrivialCopy1>::value == false, "is_trivially_copyable failure"); - static_assert(is_trivially_copyable<PodA>::value == true, "is_trivially_copyable failure"); - #endif - - { // user reported regression - struct Foo - { - int a; - Foo(int i) : a(i) {} - Foo(Foo&& other) : a(other.a) { other.a = 0; } - - Foo(const Foo&) = delete; - Foo& operator=(const Foo&) = delete; - }; - - static_assert(!eastl::is_trivially_copyable<Foo>::value, "is_trivially_copyable failure"); - } - - - // is_trivially_copy_assignable - { - static_assert(is_trivially_copy_assignable<int>::value == true, "is_trivially_copy_assignable failure"); - static_assert(is_trivially_copy_assignable<char*>::value == true, "is_trivially_copy_assignable failure"); - static_assert(is_trivially_copy_assignable<const char*>::value == true, "is_trivially_copy_assignable failure"); - static_assert(is_trivially_copy_assignable<NoTrivialCopy1>::value == false, "is_trivially_copy_assignable failure"); - - #ifdef INTENTIONALLY_DISABLED - // These tests currently fail on clang, but they would pass using the std::is_trivially_copy_assignable trait. We should - // determine if our implementation is correct, or if clang is actually incorrect. - static_assert(is_trivially_copy_assignable<const int>::value == true, "is_trivially_copy_assignable failure"); - static_assert(is_trivially_copy_assignable<const PodA>::value == true, "is_trivially_copy_assignable failure"); - static_assert(is_trivially_copy_assignable<PodA>::value == true, "is_trivially_copy_assignable failure"); - #endif - } - // is_trivially_default_constructible - // To do. - - - // is_trivial - // To do. - - - // is_constructible - static_assert(is_constructible<void>::value == false, "is_constructible failure"); - static_assert(is_constructible<const void>::value == false, "is_constructible failure"); - static_assert(is_constructible<int>::value == true, "is_constructible failure"); - static_assert(is_constructible<int&>::value == false, "is_constructible failure"); - static_assert(is_constructible<int&&>::value == false, "is_constructible failure"); - static_assert(is_constructible<int*>::value == true, "is_constructible failure"); - static_assert(is_constructible<int[]>::value == false, "is_constructible failure"); - static_assert(is_constructible<int[4]>::value == true, "is_constructible failure"); - static_assert(is_constructible<NonPod1>::value == true, " is_constructible failure"); - static_assert(is_constructible<NoTrivialCopy1>::value == true, "is_constructible failure"); - static_assert(is_constructible<PodA>::value == true, "is_constructible failure"); - static_assert(is_constructible<Abstract>::value == false, "is_constructible failure"); - static_assert(is_constructible<NonCopyable>::value == true, "is_constructible failure"); - #if EASTL_TYPE_TRAIT_is_trivially_constructible_CONFORMANCE - static_assert((is_constructible<int, const int>::value == true), "is_constructible failure"); - static_assert((is_constructible<char*, const char*>::value == false), "is_constructible failure"); - static_assert((is_constructible<char*, char* const>::value == true), "is_constructible failure"); - static_assert((is_constructible<ThrowConstructibleTest, int>::value == true), "is_constructible failure"); - static_assert((is_constructible<ThrowConstructibleTest, float>::value == true), "is_constructible failure"); - #endif - - - // is_trivially_constructible - // Need double parentheses because some older compilers need static_assert implemented as a macro. - static_assert((is_trivially_constructible<void>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<void, void>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<void, int>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<int>::value == true), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<int, int>::value == true), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<int, Abstract>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<int*>::value == true), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<int[]>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<int[], int[]>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<int[4]>::value == true), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<int[4], int[]>::value == false), "is_trivially_constructible failure"); - #if EASTL_TYPE_TRAIT_is_trivially_constructible_CONFORMANCE - static_assert((is_trivially_constructible<NoTrivialCopy1>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<PodA>::value == true), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<PodA, PodA>::value == true), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<Abstract>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<NonPod1>::value == false), "is_trivially_constructible failure"); - static_assert((is_trivially_constructible<NoTrivialConstructor>::value == false), "is_trivially_constructible failure"); - #endif - - - // is_nothrow_constructible - static_assert((is_nothrow_constructible<void>::value == false), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<int>::value == true), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<int*>::value == true), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<int[4]>::value == true), "is_nothrow_constructible failure"); - #if EASTL_TYPE_TRAIT_is_nothrow_constructible_CONFORMANCE - static_assert((is_nothrow_constructible<int[]>::value == false), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<Abstract>::value == false), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<int, const int>::value == true), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<char*, const char*>::value == false), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<char*, char* const>::value == true), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<NonPod1>::value == false), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<PodA>::value == true), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<ThrowConstructibleTest, int>::value == true), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<ThrowConstructibleTest, float>::value == false), "is_nothrow_constructible failure"); - static_assert((is_nothrow_constructible<NoTrivialCopy1>::value == true), "is_nothrow_constructible failure"); //True because it's a compiler-generated constructor. - #endif - - - // is_nothrow_move_constructible -#if !defined(EA_PLATFORM_MICROSOFT) - static_assert((is_nothrow_move_constructible<void>::value == false), "is_nothrow_move_constructible failure"); - static_assert((is_nothrow_move_constructible<int>::value == true), "is_nothrow_move_constructible failure"); - static_assert((is_nothrow_move_constructible<int*>::value == true), "is_nothrow_move_constructible failure"); - static_assert((is_nothrow_move_constructible<const int*>::value == true), "is_nothrow_move_constructible failure"); - static_assert((is_nothrow_move_constructible<int&>::value == true), "is_nothrow_move_constructible failure"); - static_assert((is_nothrow_move_constructible<double>::value == true), "is_nothrow_move_constructible failure"); - static_assert((is_nothrow_move_constructible<ClassEmpty>::value == true), "is_nothrow_move_constructible failure"); -#endif - - - // is_copy_constructible - static_assert((is_copy_constructible<void>::value == false), "is_copy_constructible failure"); - #if EASTL_TYPE_TRAIT_is_copy_constructible_CONFORMANCE - static_assert((is_copy_constructible<int>::value == true), "is_copy_constructible failure"); - static_assert((is_copy_constructible<char*>::value == true), "is_copy_constructible failure"); - static_assert((is_copy_constructible<int&>::value == true), "is_copy_constructible failure"); // As of this writing, GCC's libstdc++ reports true for this. I'm trying to find what's correct. - static_assert((is_copy_constructible<const int>::value == true), "is_copy_constructible failure"); - static_assert((is_copy_constructible<HasTrivialCopy>::value == true), "is_copy_constructible failure"); - - #if !defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_MSVC) // EDG (and only EDG) is generating warnings about the decltype expression referencing a deleted constructor. This seems like a bug, though we need to verify. - // EA_COMPILER_MSVC is disabled because VS2013 fails this test and it may be that EASTL_TYPE_TRAIT_is_copy_constructible_CONFORMANCE should really be 0 for VS2013. - static_assert((is_copy_constructible<ConstructibleOnlyWithNonConstReference>::value == false), "is_copy_constructible failure"); - #endif - #endif - - - // is_destructible - static_assert(is_destructible<int>::value == true, "is_destructible failure"); - static_assert(is_destructible<int&>::value == true, "is_destructible failure"); - static_assert(is_destructible<int&&>::value == true, "is_destructible failure"); - static_assert(is_destructible<char>::value == true, "is_destructible failure"); - static_assert(is_destructible<char*>::value == true, "is_destructible failure"); - static_assert(is_destructible<PodA>::value == true, "is_destructible failure"); - static_assert(is_destructible<void>::value == false, "is_destructible failure"); - static_assert(is_destructible<int[3]>::value == true, "is_destructible failure"); - static_assert(is_destructible<int[]>::value == false, "is_destructible failure"); // You can't call operator delete on this class. - static_assert(is_destructible<Abstract>::value == true, "is_destructible failure"); - static_assert(is_destructible<AbstractWithDtor>::value == true, "is_destructible failure"); - #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) - static_assert(is_destructible<DeletedDtor>::value == false, "is_destructible failure"); // You can't call operator delete on this class. - #endif - static_assert(is_destructible<NonPod2>::value == true, "is_destructible failure"); - - - // is_trivially_destructible - static_assert(is_trivially_destructible<int>::value == true, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<int&>::value == true, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<int&&>::value == true, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<char>::value == true, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<char*>::value == true, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<void>::value == false, "is_trivially_destructible failure"); - #if EASTL_TYPE_TRAIT_is_trivially_destructible_CONFORMANCE - static_assert(is_trivially_destructible<PodA>::value == true, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<int[3]>::value == true, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<int[]>::value == false, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<Abstract>::value == true, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<AbstractWithDtor>::value == false, "is_trivially_destructible failure"); // Having a user-defined destructor make it non-trivial. - #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) - static_assert(is_trivially_destructible<DeletedDtor>::value == false, "is_trivially_destructible failure"); - #endif - static_assert(is_trivially_destructible<NonPod2>::value == false, "is_trivially_destructible failure"); // This case differs from is_destructible, because we have a declared destructor. - #endif - - - // is_nothrow_destructible - static_assert(is_nothrow_destructible<int>::value == true, "is_nothrow_destructible failure"); - static_assert(is_nothrow_destructible<int&>::value == true, "is_nothrow_destructible failure"); - static_assert(is_nothrow_destructible<int&&>::value == true, "is_nothrow_destructible failure"); - static_assert(is_nothrow_destructible<void>::value == false, "is_nothrow_destructible failure"); - static_assert(is_nothrow_destructible<Abstract>::value == true, "is_nothrow_destructible failure"); - static_assert(is_nothrow_destructible<AbstractWithDtor>::value == true, "is_nothrow_destructible failure"); - #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) - static_assert(is_nothrow_destructible<DeletedDtor>::value == false, "is_nothrow_destructible failure"); // You can't call operator delete on this class. - #endif - #if EASTL_TYPE_TRAIT_is_nothrow_destructible_CONFORMANCE - static_assert(is_nothrow_destructible<NonPod2>::value == true, "is_nothrow_destructible failure"); // NonPod2 is nothrow destructible because it has an empty destructor (makes no calls) which has no exception specification. Thus its exception specification defaults to noexcept(true) [C++11 Standard, 15.4 paragraph 14] - static_assert(is_nothrow_destructible<NoThrowDestructible>::value == true, "is_nothrow_destructible failure"); - #endif - #if EASTL_TYPE_TRAIT_is_nothrow_destructible_CONFORMANCE && !defined(EA_COMPILER_NO_EXCEPTIONS) - static_assert(is_nothrow_destructible<ThrowDestructible>::value == false, "is_nothrow_destructible failure"); - static_assert(is_nothrow_destructible<ThrowDestructibleNoexceptFalse>::value == false, "is_nothrow_destructible failure"); - #endif - - - // alignment_of - #if !defined(EA_ABI_ARM_APPLE) // Apple on ARM (i.e. iPhone/iPad) doesn't align 8 byte types on 8 byte boundaries, and the hardware allows it. - static_assert(alignment_of<uint64_t>::value == 8, "alignment_of failure"); - EATEST_VERIFY(GetType(alignment_of<uint64_t>()) == 8); - #endif - - static_assert(alignment_of<ClassAlign32>::value == 32, "alignment_of failure"); - EATEST_VERIFY(GetType(alignment_of<ClassAlign32>()) == 32); - - - // common_type - static_assert((is_same<common_type<NonPod2*>::type, NonPod2*>::value), "common_type failure"); - static_assert((is_same<common_type<int>::type, int>::value), "common_type failure"); - static_assert((is_same<common_type<void, void>::type, void>::value), "common_type failure"); - static_assert((is_same<common_type<int, int>::type, int>::value), "common_type failure"); - - - // rank - static_assert(rank<int[1][2][3][4][5][6]>::value == 6, "rank failure"); - static_assert(rank<int[][1][2]>::value == 3, "rank failure"); - static_assert(rank<int>::value == 0, "rank failure"); - static_assert(rank<void>::value == 0, "rank failure"); - - static_assert(rank_v<int[1][2][3][4][5][6]> == 6, "rank failure"); - static_assert(rank_v<int[][1][2]> == 3, "rank failure"); - static_assert(rank_v<int> == 0, "rank failure"); - static_assert(rank_v<void> == 0, "rank failure"); - - - - // extent - static_assert((extent<int> ::value == 0), "extent failure"); - static_assert((extent<int[2]> ::value == 2), "extent failure"); - static_assert((extent<int[2][4]> ::value == 2), "extent failure"); - static_assert((extent<int[]> ::value == 0), "extent failure"); - static_assert((extent<int[][4]> ::value == 0), "extent failure"); - static_assert((extent<int, 1> ::value == 0), "extent failure"); - static_assert((extent<int[2], 1> ::value == 0), "extent failure"); - static_assert((extent<int[2][4], 1>::value == 4), "extent failure"); - static_assert((extent<int[][4], 1> ::value == 4), "extent failure"); - - static_assert((extent_v<int> == 0), "extent failure"); - static_assert((extent_v<int[2]> == 2), "extent failure"); - static_assert((extent_v<int[2][4]> == 2), "extent failure"); - static_assert((extent_v<int[]> == 0), "extent failure"); - static_assert((extent_v<int[][4]> == 0), "extent failure"); - static_assert((extent_v<int, 1> == 0), "extent failure"); - static_assert((extent_v<int[2], 1> == 0), "extent failure"); - static_assert((extent_v<int[2][4], 1> == 4), "extent failure"); - static_assert((extent_v<int[][4], 1> == 4), "extent failure"); - - - - // is_aligned - static_assert(is_aligned<uint8_t>::value == false, "is_aligned failure"); - EATEST_VERIFY(GetType(is_aligned<uint8_t>()) == false); - - static_assert(is_aligned<uint16_t>::value == false, "is_aligned failure"); - EATEST_VERIFY(GetType(is_aligned<uint16_t>()) == false); - - static_assert(is_aligned<uint32_t>::value == false, "is_aligned failure"); - EATEST_VERIFY(GetType(is_aligned<uint32_t>()) == false); - - static_assert(is_aligned<uint64_t>::value == false, "is_aligned failure"); - EATEST_VERIFY(GetType(is_aligned<uint64_t>()) == false); - - static_assert(is_aligned<uint64_t>::value == false, "is_aligned failure"); - EATEST_VERIFY(GetType(is_aligned<uint64_t>()) == false); - - { - #if (kEASTLTestAlign16 == 16) // To do: Rename kEASTLTestAlign16, as what it really means is "is 16 byte alignment+ supported". - static_assert(is_aligned<Align16>::value, "is_aligned failure"); - EATEST_VERIFY(GetType(is_aligned<Align16>())); - - - static_assert(is_aligned<Align32>::value, "is_aligned failure"); - EATEST_VERIFY(GetType(is_aligned<Align32>())); - - static_assert(is_aligned<Align64>::value, "is_aligned failure"); - EATEST_VERIFY(GetType(is_aligned<Align64>())); - #endif - } - - - // is_same - static_assert((is_same<uint32_t, uint32_t>::value == true), "is_same failure"); - static_assert((is_same<void, void>::value == true), "is_same failure"); - static_assert((is_same<void*, void*>::value == true), "is_same failure"); - static_assert((is_same<uint64_t, uint64_t>::value == true), "is_same failure"); - static_assert((is_same<Class, Class>::value == true), "is_same failure"); - static_assert((is_same<uint64_t, uint32_t>::value == false), "is_same failure"); - static_assert((is_same<Class, ClassAlign32>::value == false), "is_same failure"); - - static_assert((is_same_v<uint32_t, uint32_t> == true), "is_same_v failure"); - static_assert((is_same_v<void, void> == true), "is_same_v failure"); - static_assert((is_same_v<void*, void*> == true), "is_same_v failure"); - static_assert((is_same_v<uint64_t, uint64_t> == true), "is_same_v failure"); - static_assert((is_same_v<Class, Class> == true), "is_same_v failure"); - static_assert((is_same_v<uint64_t, uint32_t> == false), "is_same_v failure"); - static_assert((is_same_v<Class, ClassAlign32> == false), "is_same_v failure"); - - - - // is_convertible - static_assert((is_convertible<uint16_t, uint32_t>::value == true), "is_convertible failure"); - static_assert((is_convertible<int32_t, int16_t>::value == true), "is_convertible failure"); // This is a conversion from 32 bits down to 16 bits. All compilers natively report that this is true. However, VC++ generates warnings for actual such conversions. - static_assert((is_convertible<Subclass, Class>::value == true), "is_convertible failure"); - static_assert((is_convertible<Subclass*, Class*>::value == true), "is_convertible failure"); - static_assert((is_convertible<Subclass&, const Class&>::value == true), "is_convertible failure"); - static_assert((is_convertible<int, Class>::value == false), "is_convertible failure"); - static_assert((is_convertible<NonPod1, NonPod1>::value == true), "is_convertible failure"); - static_assert((is_convertible<NonPod1, NonPod2>::value == false), "is_convertible failure"); - #if EASTL_TYPE_TRAIT_is_convertible_CONFORMANCE // This causes compile failures. - static_assert((is_convertible<IsConvertibleTest1, IsConvertibleTest1>::value == false), "is_convertible failure"); - #endif - - // Test EASTL_DECLARE_TRIVIAL_ASSIGN(HiddenAssign); - eastl::vector<HiddenAssign> v; - EATEST_VERIFY(v.empty()); - - - // make_signed - // make_unsigned - { - // Test declarations - eastl::make_signed<int8_t>::type i8 = -1; - EATEST_VERIFY(i8 == -1); - eastl::make_unsigned<uint8_t>::type u8 = 0xff; - EATEST_VERIFY(u8 == 0xff); - - eastl::make_signed<int16_t>::type i16 = -1; - EATEST_VERIFY(i16 == -1); - eastl::make_unsigned<uint16_t>::type u16 = 0xffff; - EATEST_VERIFY(u16 == 0xffff); - - eastl::make_signed<int32_t>::type i32 = -1; - EATEST_VERIFY(i32 == -1); - eastl::make_unsigned<uint32_t>::type u32 = 0xffffffff; - EATEST_VERIFY(u32 == 0xffffffff); - - eastl::make_signed<int64_t>::type i64 = -1; - EATEST_VERIFY(i64 == -1); - eastl::make_unsigned<uint64_t>::type u64 = UINT64_C(0xffffffffffffffff); - EATEST_VERIFY(u64 == UINT64_C(0xffffffffffffffff)); - - // Test conversions via static_cast: - u8 = static_cast<eastl::make_unsigned<uint8_t>::type>(i8); - EATEST_VERIFY(u8 == 0xff); - i8 = static_cast<eastl::make_signed<int8_t>::type>(u8); - EATEST_VERIFY(i8 == -1); - - u16 = static_cast<eastl::make_unsigned<uint16_t>::type>(i16); - EATEST_VERIFY(u16 == 0xffff); - i16 = static_cast<eastl::make_signed<int16_t>::type>(u16); - EATEST_VERIFY(i16 == -1); - - u32 = static_cast<eastl::make_unsigned<uint32_t>::type>(i32); - EATEST_VERIFY(u32 == 0xffffffff); - i32 = static_cast<eastl::make_signed<int32_t>::type>(u32); - EATEST_VERIFY(i32 == -1); - - u64 = static_cast<eastl::make_unsigned<uint64_t>::type>(i64); - EATEST_VERIFY(u64 == UINT64_C(0xffffffffffffffff)); - i64 = static_cast<eastl::make_signed<int64_t>::type>(u64); - EATEST_VERIFY(i64 == -1); - - - static_assert(eastl::is_same_v<signed char, eastl::make_signed<unsigned char>::type>); - static_assert(eastl::is_same_v<short, eastl::make_signed<unsigned short>::type>); - static_assert(eastl::is_same_v<int, eastl::make_signed<unsigned int>::type>); - static_assert(eastl::is_same_v<long, eastl::make_signed<unsigned long>::type>); - static_assert(eastl::is_same_v<long long, eastl::make_signed<unsigned long long>::type>); - - static_assert(eastl::is_same_v<const signed char, eastl::make_signed<const unsigned char>::type>); - static_assert(eastl::is_same_v<const short, eastl::make_signed<const unsigned short>::type>); - static_assert(eastl::is_same_v<const int, eastl::make_signed<const unsigned int>::type>); - static_assert(eastl::is_same_v<const long, eastl::make_signed<const unsigned long>::type>); - static_assert(eastl::is_same_v<const long long, eastl::make_signed<const unsigned long long>::type>); - - static_assert(eastl::is_same_v<volatile signed char, eastl::make_signed<volatile unsigned char>::type>); - static_assert(eastl::is_same_v<volatile short, eastl::make_signed<volatile unsigned short>::type>); - static_assert(eastl::is_same_v<volatile int, eastl::make_signed<volatile unsigned int>::type>); - static_assert(eastl::is_same_v<volatile long, eastl::make_signed<volatile unsigned long>::type>); - static_assert(eastl::is_same_v<volatile long long, eastl::make_signed<volatile unsigned long long>::type>); - - static_assert(eastl::is_same_v<const volatile signed char, eastl::make_signed<const volatile unsigned char>::type>); - static_assert(eastl::is_same_v<const volatile short, eastl::make_signed<const volatile unsigned short>::type>); - static_assert(eastl::is_same_v<const volatile int, eastl::make_signed<const volatile unsigned int>::type>); - static_assert(eastl::is_same_v<const volatile long, eastl::make_signed<const volatile unsigned long>::type>); - static_assert(eastl::is_same_v<const volatile long long, eastl::make_signed<const volatile unsigned long long>::type>); - - static_assert(eastl::is_same_v<unsigned char, eastl::make_unsigned<signed char>::type>); - static_assert(eastl::is_same_v<unsigned short, eastl::make_unsigned<short>::type>); - static_assert(eastl::is_same_v<unsigned int, eastl::make_unsigned<int>::type>); - static_assert(eastl::is_same_v<unsigned long, eastl::make_unsigned<long>::type>); - static_assert(eastl::is_same_v<unsigned long long, eastl::make_unsigned<long long>::type>); - - static_assert(eastl::is_same_v<const unsigned char, eastl::make_unsigned<const signed char>::type>); - static_assert(eastl::is_same_v<const unsigned short, eastl::make_unsigned<const short>::type>); - static_assert(eastl::is_same_v<const unsigned int, eastl::make_unsigned<const int>::type>); - static_assert(eastl::is_same_v<const unsigned long, eastl::make_unsigned<const long>::type>); - static_assert(eastl::is_same_v<const unsigned long long, eastl::make_unsigned<const long long>::type>); - - static_assert(eastl::is_same_v<volatile unsigned char, eastl::make_unsigned<volatile signed char>::type>); - static_assert(eastl::is_same_v<volatile unsigned short, eastl::make_unsigned<volatile short>::type>); - static_assert(eastl::is_same_v<volatile unsigned int, eastl::make_unsigned<volatile int>::type>); - static_assert(eastl::is_same_v<volatile unsigned long, eastl::make_unsigned<volatile long>::type>); - static_assert(eastl::is_same_v<volatile unsigned long long, eastl::make_unsigned<volatile long long>::type>); - - static_assert(eastl::is_same_v<const volatile unsigned char, eastl::make_unsigned<const volatile signed char>::type>); - static_assert(eastl::is_same_v<const volatile unsigned short, eastl::make_unsigned<const volatile short>::type>); - static_assert(eastl::is_same_v<const volatile unsigned int, eastl::make_unsigned<const volatile int>::type>); - static_assert(eastl::is_same_v<const volatile unsigned long, eastl::make_unsigned<const volatile long>::type>); - static_assert(eastl::is_same_v<const volatile unsigned long long, eastl::make_unsigned<const volatile long long>::type>); - - static_assert(eastl::is_same_v<signed char, eastl::make_signed<signed char>::type>); - static_assert(eastl::is_same_v<short, eastl::make_signed<signed short>::type>); - static_assert(eastl::is_same_v<int, eastl::make_signed<signed int>::type>); - static_assert(eastl::is_same_v<long, eastl::make_signed<signed long>::type>); - static_assert(eastl::is_same_v<long long, eastl::make_signed<signed long long>::type>); - - static_assert(eastl::is_same_v<unsigned char, eastl::make_unsigned<unsigned char>::type>); - static_assert(eastl::is_same_v<unsigned short, eastl::make_unsigned<unsigned short>::type>); - static_assert(eastl::is_same_v<unsigned int, eastl::make_unsigned<unsigned int>::type>); - static_assert(eastl::is_same_v<unsigned long, eastl::make_unsigned<unsigned long>::type>); - static_assert(eastl::is_same_v<unsigned long long, eastl::make_unsigned<unsigned long long>::type>); - - #if EASTL_GCC_STYLE_INT128_SUPPORTED - static_assert(eastl::is_same_v<__uint128_t, eastl::make_unsigned<__int128_t>::type>); - static_assert(eastl::is_same_v<__uint128_t, eastl::make_unsigned<__uint128_t>::type>); - - static_assert(eastl::is_same_v<__int128_t, eastl::make_signed<__int128_t>::type>); - static_assert(eastl::is_same_v<__int128_t, eastl::make_signed<__uint128_t>::type>); - #endif - - // Char tests - static_assert(sizeof(char) == sizeof(eastl::make_signed<char>::type)); - static_assert(sizeof(wchar_t) == sizeof(eastl::make_signed<wchar_t>::type)); - static_assert(sizeof(char8_t) == sizeof(eastl::make_signed<char8_t>::type)); - static_assert(sizeof(char16_t) == sizeof(eastl::make_signed<char16_t>::type)); - static_assert(sizeof(char32_t) == sizeof(eastl::make_signed<char32_t>::type)); - static_assert(sizeof(char) == sizeof(eastl::make_unsigned<char>::type)); - static_assert(sizeof(wchar_t) == sizeof(eastl::make_unsigned<wchar_t>::type)); - static_assert(sizeof(char8_t) == sizeof(eastl::make_unsigned<char8_t>::type)); - static_assert(sizeof(char16_t) == sizeof(eastl::make_unsigned<char16_t>::type)); - static_assert(sizeof(char32_t) == sizeof(eastl::make_unsigned<char32_t>::type)); - - static_assert(eastl::is_same_v<signed char, eastl::make_signed<char8_t>::type>); - static_assert(eastl::is_same_v<unsigned char, eastl::make_unsigned<char8_t>::type>); - - // Enum tests - enum EnumUCharSize : unsigned char {}; - enum EnumUShortSize : unsigned short {}; - enum EnumUIntSize : unsigned int {}; - enum EnumULongSize : unsigned long {}; - enum EnumULongLongSize : unsigned long long {}; - - static_assert(eastl::is_signed_v<eastl::make_signed<EnumUCharSize>::type>); - static_assert(eastl::is_signed_v<eastl::make_signed<EnumUShortSize>::type>); - static_assert(eastl::is_signed_v<eastl::make_signed<EnumUIntSize>::type>); - static_assert(eastl::is_signed_v<eastl::make_signed<EnumULongSize>::type>); - static_assert(eastl::is_signed_v<eastl::make_signed<EnumULongLongSize>::type>); - static_assert(sizeof(EnumUCharSize) == sizeof(eastl::make_signed<EnumUCharSize>::type)); - static_assert(sizeof(EnumUShortSize) == sizeof(eastl::make_signed<EnumUShortSize>::type)); - static_assert(sizeof(EnumUIntSize) == sizeof(eastl::make_signed<EnumUIntSize>::type)); - static_assert(sizeof(EnumULongSize) == sizeof(eastl::make_signed<EnumULongSize>::type)); - static_assert(sizeof(EnumULongLongSize) == sizeof(eastl::make_signed<EnumULongLongSize>::type)); - - enum EnumCharSize : signed char {}; - enum EnumShortSize : short {}; - enum EnumIntSize : int {}; - enum EnumLongSize : long {}; - enum EnumLongLongSize : long long {}; - - static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumCharSize>::type>); - static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumShortSize>::type>); - static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumIntSize>::type>); - static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumLongSize>::type>); - static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumLongLongSize>::type>); - static_assert(sizeof(EnumCharSize) == sizeof(eastl::make_unsigned<EnumCharSize>::type)); - static_assert(sizeof(EnumShortSize) == sizeof(eastl::make_unsigned<EnumShortSize>::type)); - static_assert(sizeof(EnumIntSize) == sizeof(eastl::make_unsigned<EnumIntSize>::type)); - static_assert(sizeof(EnumLongSize) == sizeof(eastl::make_unsigned<EnumLongSize>::type)); - static_assert(sizeof(EnumLongLongSize) == sizeof(eastl::make_unsigned<EnumLongLongSize>::type)); - } - - // remove_const - // remove_volatile - // remove_cv - { - // To do: Make more thorough tests verifying this. Such tests will probably involve template metaprogramming. - remove_const<const int32_t>::type i32 = 47; - EATEST_VERIFY(++i32 == 48); - - remove_volatile<volatile int16_t>::type i16 = 47; - EATEST_VERIFY(++i16 == 48); - - remove_cv<const volatile int32_t>::type i64 = 47; - EATEST_VERIFY(++i64 == 48); - - //static_assert(is_same<std::remove_cv<int (int, ...)>::type , std::remove_cv<int (int, ...) const>::type>::value, "remove_cv failure"); - } - - // remove_cvref - { - static_assert(is_same_v<remove_cvref_t<int>, int>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<int&>, int>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<int&&>, int>, "remove_cvref failure"); - - static_assert(is_same_v<remove_cvref_t<const int>, int>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<const int&>, int>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<const int&&>, int>, "remove_cvref failure"); - - static_assert(is_same_v<remove_cvref_t<volatile int>, int>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<volatile int&>, int>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<volatile int&&>, int>, "remove_cvref failure"); - - static_assert(is_same_v<remove_cvref_t<const volatile int>, int>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<const volatile int&>, int>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<const volatile int&&>, int>, "remove_cvref failure"); - - // test pointer types - static_assert(is_same_v<remove_cvref_t<int*>, int*>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<int*&>, int*>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<int*&&>, int*>, "remove_cvref failure"); - - static_assert(is_same_v<remove_cvref_t<const int*>, const int*>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<const int*&>, const int*>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<const int*&&>, const int*>, "remove_cvref failure"); - - static_assert(is_same_v<remove_cvref_t<int* const>, int*>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<int* const&>, int*>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<int* const&&>, int*>, "remove_cvref failure"); - - static_assert(is_same_v<remove_cvref_t<int* const volatile>, int*>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<int* const volatile&>, int*>, "remove_cvref failure"); - static_assert(is_same_v<remove_cvref_t<int* const volatile&&>, int*>, "remove_cvref failure"); - } - - - // add_const - // add_volatile - // add_cv - { - // To do: Make more thorough tests verifying this. Such tests will probably involve template metaprogramming. - eastl::add_const<int32_t>::type i32 = 47; - EATEST_VERIFY(i32 == 47); - - eastl::add_volatile<volatile int16_t>::type i16 = 47; - EATEST_VERIFY(++i16 == 48); - - eastl::add_cv<const volatile int32_t>::type i64 = 47; - EATEST_VERIFY(i64 == 47); - } - - - // as_const - { - { - int i = 42; - static_assert(eastl::is_same<decltype(eastl::as_const(i)), const int&>::value, "expecting a 'const T&' return type"); - EATEST_VERIFY(eastl::as_const(i) == 42); - } - - { - eastl::string str = "Electronic Arts"; - static_assert(eastl::is_same<decltype(eastl::as_const(str)), const eastl::string&>::value, "expecting a 'const T&' return type"); - EATEST_VERIFY(eastl::as_const(str) == "Electronic Arts"); - } - } - - - // remove_reference - // add_reference - // remove_pointer - // add_pointer - // remove_extent - // remove_all_extents - { - int x = 17; - eastl::add_reference<int>::type xRef = x; - x++; - EATEST_VERIFY(xRef == 18); - - eastl::remove_reference<int&>::type xValue; - xValue = 3; - EATEST_VERIFY(xValue == 3); - - eastl::add_pointer<int>::type xPtr = &x; - *xPtr = 19; - EATEST_VERIFY(x == 19); - - eastl::remove_pointer<int*>::type yValue; - yValue = 3; - EATEST_VERIFY(yValue == 3); - - // ref to T - // -> T* - static_assert(is_same_v<add_pointer_t<int&>, int*>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<int(&)()>, int(*)()>, "add_pointer failure"); - - // object type (a (possibly cv-qualified) type other than function type, reference type or void), or - // a function type that is not cv- or ref-qualified, or a (possibly cv-qualified) void type - // -> T* - static_assert(is_same_v<add_pointer_t<int>, int*>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<int*>, int**>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<int()>, int(*)()>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<void>, void*>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<const void>, const void*>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<volatile void>, volatile void*>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<const volatile void>, const volatile void*>, "add_pointer failure"); - - // otherwise (cv- or ref-qualified function type) - // -> T - static_assert(is_same_v<add_pointer_t<int() const>, int() const>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<int() volatile>, int() volatile>, "add_pointer failure"); - static_assert(is_same_v<add_pointer_t<int() const volatile>, int() const volatile>, "add_pointer failure"); - - // remove_extent - // If T is an array of some type X, provides the member typedef type equal to X, otherwise - // type is T. Note that if T is a multidimensional array, only the first dimension is removed. - typedef int IntArray1[37]; - typedef eastl::remove_extent<IntArray1>::type Int; - static_assert((eastl::is_same<Int, int>::value == true), "remove_extent/is_same failure"); - - // remove_all_extents - typedef int IntArray2[37][54]; - typedef eastl::remove_all_extents<IntArray2>::type Int2; - static_assert((eastl::is_same<Int2, int>::value == true), "remove_all_extents/is_same failure"); - } - - // add_lvalue_reference - { - // function type with no cv- or ref-qualifier - // -> T& - static_assert(is_same_v<add_lvalue_reference_t<void()>, void(&)()>, "add_lvalue_reference failure"); - - // object type (a (possibly cv-qualified) type other than function type, reference type or void) - // -> T& - static_assert(is_same_v<add_lvalue_reference_t<int>, int&>, "add_lvalue_reference failure"); - static_assert(is_same_v<add_lvalue_reference_t<const int>, const int&>, "add_lvalue_reference failure"); - - // if T is an rvalue reference (to some type U) - // -> U& - static_assert(is_same_v<add_lvalue_reference_t<int&&>, int&>, "add_lvalue_reference failure"); - - // otherwise (cv- or ref-qualified function type, or reference type, or (possibly cv-qualified) void) - // -> T - static_assert(is_same_v<add_lvalue_reference_t<void() const>, void() const>, "add_lvalue_reference failure"); - static_assert(is_same_v<add_lvalue_reference_t<void()&>, void()&>, "add_lvalue_reference failure"); - static_assert(is_same_v<add_lvalue_reference_t<void()&&>, void()&&>, "add_lvalue_reference failure"); - static_assert(is_same_v<add_lvalue_reference_t<int&>, int&>, "add_lvalue_reference failure"); - static_assert(is_same_v<add_lvalue_reference_t<const int&>, const int&>, "add_lvalue_reference failure"); - static_assert(is_same_v<add_lvalue_reference_t<void>, void>, "add_lvalue_reference failure"); - static_assert(is_same_v<add_lvalue_reference_t<const void>, const void>, "add_lvalue_reference failure"); - } - - // add_rvalue_reference - { - // function type with no cv- or ref-qualifier - // -> T&& - static_assert(is_same_v<add_rvalue_reference_t<void()>, void(&&)()>, "add_rvalue_reference failure"); - - // object type (a (possibly cv-qualified) type other than function type, reference type or void) - // -> T&& - static_assert(is_same_v<add_rvalue_reference_t<int>, int&&>, "add_rvalue_reference failure"); - static_assert(is_same_v<add_rvalue_reference_t<const int>, const int&&>, "add_rvalue_reference failure"); - - // otherwise (cv- or ref-qualified function type, or reference type, or (possibly cv-qualified) void) - // -> T - static_assert(is_same_v<add_rvalue_reference_t<void() const>, void() const>, "add_rvalue_reference failure"); - static_assert(is_same_v<add_rvalue_reference_t<void()&>, void()&>, "add_rvalue_reference failure"); - static_assert(is_same_v<add_rvalue_reference_t<void()&&>, void()&&>, "add_rvalue_reference failure"); - static_assert(is_same_v<add_rvalue_reference_t<int&>, int&>, "add_rvalue_reference failure"); - static_assert(is_same_v<add_rvalue_reference_t<int&&>, int&&>, "add_rvalue_reference failure"); - static_assert(is_same_v<add_rvalue_reference_t<const int&>, const int&>, "add_rvalue_reference failure"); - static_assert(is_same_v<add_rvalue_reference_t<void>, void>, "add_rvalue_reference failure"); - static_assert(is_same_v<add_rvalue_reference_t<const void>, const void>, "add_rvalue_reference failure"); - } - - - // decay - { - static_assert((eastl::is_same<uint32_t, eastl::decay<uint32_t>::type>::value == true), "is_same failure"); - static_assert((eastl::is_same<uint32_t, eastl::decay<const uint32_t>::type>::value == true), "is_same failure"); - static_assert((eastl::is_same<uint32_t, eastl::decay<volatile uint32_t>::type>::value == true), "is_same failure"); - static_assert((eastl::is_same<uint32_t, eastl::decay<uint32_t&>::type>::value == true), "is_same failure"); - static_assert((eastl::is_same<uint32_t, eastl::decay<const uint32_t&>::type>::value == true), "is_same failure"); - static_assert((eastl::is_same<uint32_t, eastl::decay<const volatile uint32_t&>::type>::value == true), "is_same failure"); - #if !EASTL_NO_RVALUE_REFERENCES - static_assert((eastl::is_same<uint32_t, eastl::decay<uint32_t&&>::type>::value == true), "is_same failure"); - #endif - static_assert((eastl::is_same<uint32_t*, eastl::decay<uint32_t[3]>::type>::value == true), "is_same failure"); - static_assert((eastl::is_same<uint32_t(*)(char), eastl::decay<uint32_t(char)>::type>::value == true), "is_same failure"); - } - - - // aligned_storage - // Some compilers don't support or ignore alignment specifications for stack variables, - // so we limit our testing to compilers that are known to support it. - #if (EA_ALIGN_MAX_AUTOMATIC >= 64) && defined(EA_PLATFORM_DESKTOP) // Actually there are additional compilers that support alignment of stack-based variables, most significantly clang, GCC 4.4+, and probably others. - { - // Test the creation of a single aligned value. - const size_t kArraySize = 100; - const size_t kExpectedAlignment = 64; - typedef uint16_t Type; - - eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type data; - Type* value = new(&data) Type; - *value = 37; - EATEST_VERIFY_F((EA::StdC::GetAlignment(value) >= kExpectedAlignment) && (*value == 37), - "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(value)); - - // Create an array of 100 values aligned. - eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type dataArray[kArraySize]; - Type* valueArray = new(dataArray) Type[kArraySize]; - valueArray[0] = 37; - EATEST_VERIFY_F((EA::StdC::GetAlignment(valueArray) >= kExpectedAlignment) && (valueArray[0] == 37), - "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(valueArray)); - } - { - // Test the creation of a single aligned value. - const size_t kArraySize = 17; - const size_t kExpectedAlignment = 128; - typedef uint8_t Type; - - eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type data; - Type* value = new(&data) Type; - *value = 37; - EATEST_VERIFY_F((EA::StdC::GetAlignment(value) >= kExpectedAlignment) && (*value == 37), - "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(value)); - - // Create an array of 100 values aligned. - eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type dataArray[kArraySize]; - Type* valueArray = new(dataArray) Type[kArraySize]; - valueArray[0] = 37; - EATEST_VERIFY_F((EA::StdC::GetAlignment(valueArray) >= kExpectedAlignment) && (valueArray[0] == 37), - "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(valueArray)); - } - { - // Test the creation of a single aligned value. - const size_t kArraySize = 27; - const size_t kExpectedAlignment = 256; - typedef uint32_t Type; - - eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type data; - Type* value = new(&data) Type; - *value = 37; - EATEST_VERIFY_F((EA::StdC::GetAlignment(value) >= kExpectedAlignment) && (*value == 37), - "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(value)); - - // Create an array of 100 values aligned. - eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type dataArray[kArraySize]; - Type* valueArray = new(dataArray) Type[kArraySize]; - valueArray[0] = 37; - EATEST_VERIFY_F((EA::StdC::GetAlignment(valueArray) >= kExpectedAlignment) && (valueArray[0] == 37), - "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(valueArray)); - } - #endif - - - // aligned_union - // Some compilers don't support or ignore alignment specifications for stack variables, - // so we limit our testing to compilers that are known to support it. - { - union AlignedUnion - { - char c; - int i; - float f; - char a[32]; - - AlignedUnion(float fValue) : f(fValue) {} - }; - - typedef aligned_union<sizeof(AlignedUnion), char, int, float>::type AlignedUnionStorage; - - static_assert((EA_ALIGN_OF(AlignedUnionStorage) >= EA_ALIGN_OF(float)) && (EA_ALIGN_OF(AlignedUnionStorage) <= EA_ALIGN_OF(double)), "aligned_union failure"); - static_assert(sizeof(AlignedUnionStorage) >= sizeof(AlignedUnion), "aligned_union failure"); - - AlignedUnionStorage alignedUnionStorage; // Since we know that our alignment is a simple value <= default alignment, we can just declare an object here and it will work with all compilers, including those that are limited in the stack alignments they support. - AlignedUnion* pAlignedUnion = new (&alignedUnionStorage) AlignedUnion(21.4f); - EATEST_VERIFY(pAlignedUnion->f == 21.4f); - pAlignedUnion->i = 37; - EATEST_VERIFY(pAlignedUnion->i == 37); - } - - - // union_cast - { - float f32 = -1234.f; - uint32_t n32 = union_cast<uint32_t>(f32); - float f32New = union_cast<float>(n32); - EATEST_VERIFY(f32 == f32New); - - double f64 = -1234.0; - uint64_t n64 = union_cast<uint64_t>(f64); - double f64New = union_cast<double>(n64); - EATEST_VERIFY(f64 == f64New); - - PodA a = { -1234 }; - PodB b = union_cast<PodB>(a); - PodA aNew = union_cast<PodA>(b); - EATEST_VERIFY(a == aNew); - - PodA* pA = new PodA; - PodB* pB = union_cast<PodB*>(pA); - PodA* pANew = union_cast<PodA*>(pB); - EATEST_VERIFY(pA == pANew); - delete pA; - } - - // void_t - { - { - static_assert(is_same<void_t<void>, void>::value, "void_t failure"); - static_assert(is_same<void_t<int>, void>::value, "void_t failure"); - static_assert(is_same<void_t<short>, void>::value, "void_t failure"); - static_assert(is_same<void_t<long>, void>::value, "void_t failure"); - static_assert(is_same<void_t<long long>, void>::value, "void_t failure"); - static_assert(is_same<void_t<ClassEmpty>, void>::value, "void_t failure"); - static_assert(is_same<void_t<ClassNonEmpty>, void>::value, "void_t failure"); - static_assert(is_same<void_t<vector<int>>, void>::value, "void_t failure"); - } - - // new sfinae mechansim test - { - static_assert(has_increment_operator_using_void_t<HasIncrementOperator>::value, "void_t sfinae failure"); - static_assert(!has_increment_operator_using_void_t<ClassEmpty>::value, "void_t sfinae failure"); - } - } - - // detected idiom - { - static_assert(is_detected<has_increment_operator_detection, HasIncrementOperator>::value, "is_detected failure."); - static_assert(!is_detected<has_increment_operator_detection, ClassEmpty>::value, "is_detected failure."); - - static_assert(is_same<detected_t<has_increment_operator_detection, HasIncrementOperator>, HasIncrementOperator&>::value, "is_detected_t failure."); - static_assert(is_same<detected_t<has_increment_operator_detection, ClassEmpty>, nonesuch>::value, "is_detected_t failure."); - - using detected_or_positive_result = detected_or<float, has_increment_operator_detection, HasIncrementOperator>; - using detected_or_negative_result = detected_or<float, has_increment_operator_detection, ClassEmpty>; - static_assert(detected_or_positive_result::value_t::value, "detected_or failure."); - static_assert(!detected_or_negative_result::value_t::value, "detected_or failure."); - static_assert(is_same<detected_or_positive_result::type, HasIncrementOperator&>::value, "detected_or failure."); - static_assert(is_same<detected_or_negative_result::type, float>::value, "detected_or failure."); - - static_assert(is_same<detected_or_t<float, has_increment_operator_detection, HasIncrementOperator>, HasIncrementOperator&>::value, "detected_or_t failure."); - static_assert(is_same<detected_or_t<float, has_increment_operator_detection, ClassEmpty>, float>::value, "detected_or_t failure."); - - static_assert(is_detected_exact<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_exact failure."); - static_assert(!is_detected_exact<float, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_exact failure."); - static_assert(is_detected_exact<nonesuch, has_increment_operator_detection, ClassEmpty>::value, "is_detected_exact failure."); - static_assert(!is_detected_exact<float, has_increment_operator_detection, ClassEmpty>::value, "is_detected_exact failure."); - - static_assert(is_detected_convertible<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure."); - static_assert(is_detected_convertible<HasIncrementOperator, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure."); - static_assert(!is_detected_convertible<float, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure."); - static_assert(!is_detected_convertible<nonesuch, has_increment_operator_detection, ClassEmpty>::value, "is_detected_convertible failure."); - static_assert(!is_detected_convertible<float, has_increment_operator_detection, ClassEmpty>::value, "is_detected_convertible failure."); - - - #if EASTL_VARIABLE_TEMPLATES_ENABLED - static_assert(is_detected_v<has_increment_operator_detection, HasIncrementOperator>, "is_detected_v failure."); - static_assert(!is_detected_v<has_increment_operator_detection, ClassEmpty>, "is_detected_v failure."); - - static_assert(is_detected_exact_v<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>, "is_detected_exact_v failure."); - static_assert(!is_detected_exact_v<float, has_increment_operator_detection, HasIncrementOperator>, "is_detected_exact_v failure."); - static_assert(is_detected_exact_v<nonesuch, has_increment_operator_detection, ClassEmpty>, "is_detected_exact_v failure."); - static_assert(!is_detected_exact_v<float, has_increment_operator_detection, ClassEmpty>, "is_detected_exact_v failure."); - - static_assert(is_detected_convertible_v<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure."); - static_assert(is_detected_convertible_v<HasIncrementOperator, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure."); - static_assert(!is_detected_convertible_v<float, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure."); - static_assert(!is_detected_convertible_v<nonesuch, has_increment_operator_detection, ClassEmpty>, "is_detected_convertible_v failure."); - static_assert(!is_detected_convertible_v<float, has_increment_operator_detection, ClassEmpty>, "is_detected_convertible_v failure."); - #endif - } - - // conjunction - { - static_assert( conjunction<>::value, "conjunction failure"); - static_assert(!conjunction<false_type>::value, "conjunction failure"); - static_assert(!conjunction<false_type, false_type>::value, "conjunction failure"); - static_assert(!conjunction<false_type, false_type, false_type>::value, "conjunction failure"); - static_assert(!conjunction<false_type, false_type, false_type, true_type>::value, "conjunction failure"); - static_assert(!conjunction<false_type, false_type, true_type, true_type>::value, "conjunction failure"); - static_assert(!conjunction<false_type, true_type, true_type, true_type>::value, "conjunction failure"); - static_assert(!conjunction<true_type, true_type, true_type, true_type, false_type>::value, "conjunction failure"); - static_assert(!conjunction<true_type, false_type, true_type, true_type, true_type>::value, "conjunction failure"); - static_assert( conjunction<true_type, true_type, true_type, true_type, true_type>::value, "conjunction failure"); - static_assert( conjunction<true_type, true_type, true_type, true_type>::value, "conjunction failure"); - static_assert( conjunction<true_type, true_type, true_type>::value, "conjunction failure"); - static_assert( conjunction<true_type>::value, "conjunction failure"); - - #if EASTL_VARIABLE_TEMPLATES_ENABLED - static_assert( conjunction_v<>, "conjunction failure"); - static_assert(!conjunction_v<false_type>, "conjunction failure"); - static_assert(!conjunction_v<false_type, false_type>, "conjunction failure"); - static_assert(!conjunction_v<false_type, false_type, false_type>, "conjunction failure"); - static_assert(!conjunction_v<false_type, false_type, false_type, true_type>, "conjunction failure"); - static_assert(!conjunction_v<false_type, false_type, true_type, true_type>, "conjunction failure"); - static_assert(!conjunction_v<false_type, true_type, true_type, true_type>, "conjunction failure"); - static_assert(!conjunction_v<true_type, true_type, true_type, true_type, false_type>, "conjunction failure"); - static_assert(!conjunction_v<true_type, false_type, true_type, true_type, true_type>, "conjunction failure"); - static_assert( conjunction_v<true_type, true_type, true_type, true_type, true_type>, "conjunction failure"); - static_assert( conjunction_v<true_type, true_type, true_type, true_type>, "conjunction failure"); - static_assert( conjunction_v<true_type, true_type, true_type>, "conjunction failure"); - static_assert( conjunction_v<true_type>, "conjunction failure"); - #endif - } - - // disjunction - { - static_assert(!disjunction<>::value, "disjunction failure"); - static_assert(!disjunction<false_type>::value, "disjunction failure"); - static_assert(!disjunction<false_type, false_type>::value, "disjunction failure"); - static_assert(!disjunction<false_type, false_type, false_type>::value, "disjunction failure"); - static_assert( disjunction<false_type, false_type, false_type, true_type>::value, "disjunction failure"); - static_assert( disjunction<false_type, false_type, true_type, true_type>::value, "disjunction failure"); - static_assert( disjunction<false_type, true_type, true_type, true_type>::value, "disjunction failure"); - static_assert( disjunction<true_type, true_type, true_type, true_type, false_type>::value, "disjunction failure"); - static_assert( disjunction<true_type, false_type, true_type, true_type, true_type>::value, "disjunction failure"); - static_assert( disjunction<true_type, true_type, true_type, true_type, true_type>::value, "disjunction failure"); - static_assert( disjunction<true_type, true_type, true_type, true_type>::value, "disjunction failure"); - static_assert( disjunction<true_type, true_type, true_type>::value, "disjunction failure"); - static_assert( disjunction<true_type>::value, "disjunction failure"); - - #if EASTL_VARIABLE_TEMPLATES_ENABLED - static_assert(!disjunction_v<>, "disjunction failure"); - static_assert(!disjunction_v<false_type>, "disjunction failure"); - static_assert(!disjunction_v<false_type, false_type>, "disjunction failure"); - static_assert(!disjunction_v<false_type, false_type, false_type>, "disjunction failure"); - static_assert( disjunction_v<false_type, false_type, false_type, true_type>, "disjunction failure"); - static_assert( disjunction_v<false_type, false_type, true_type, true_type>, "disjunction failure"); - static_assert( disjunction_v<false_type, true_type, true_type, true_type>, "disjunction failure"); - static_assert( disjunction_v<true_type, true_type, true_type, true_type, false_type>, "disjunction failure"); - static_assert( disjunction_v<true_type, false_type, true_type, true_type, true_type>, "disjunction failure"); - static_assert( disjunction_v<true_type, true_type, true_type, true_type, true_type>, "disjunction failure"); - static_assert( disjunction_v<true_type, true_type, true_type, true_type>, "disjunction failure"); - static_assert( disjunction_v<true_type, true_type, true_type>, "disjunction failure"); - static_assert( disjunction_v<true_type>, "disjunction failure"); - #endif - } - - // negation - { - static_assert( negation<false_type>::value, "negation failure"); - static_assert(!negation<true_type>::value, "negation failure"); - - #if EASTL_VARIABLE_TEMPLATES_ENABLED - static_assert( negation_v<false_type>, "negation failure"); - static_assert(!negation_v<true_type>, "negation failure"); - #endif - } - - // has_unique_object_representations - { - static_assert( has_unique_object_representations<bool>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<char16_t>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<char32_t>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<char>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<int>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<long long>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<long>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<short>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<signed char>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<unsigned char>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<unsigned int>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<unsigned long long>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<unsigned long>::value, "has_unique_object_representations failure"); - static_assert( has_unique_object_representations<unsigned short>::value, "has_unique_object_representations failure"); - static_assert(!has_unique_object_representations<void>::value, "has_unique_object_representations failure"); -#ifndef EA_WCHAR_T_NON_NATIVE // If wchar_t is a native type instead of simply a define to an existing type which is already handled... - static_assert( has_unique_object_representations<wchar_t>::value, "has_unique_object_representations failure"); -#endif - - #if EASTL_TYPE_TRAIT_has_unique_object_representations_CONFORMANCE - { - struct packed_type { int a; }; - static_assert( has_unique_object_representations<packed_type>::value, "has_unique_object_representations failure"); - - struct padded_type { int a; char b; int c; }; - static_assert(!has_unique_object_representations<padded_type>::value, "has_unique_object_representations failure"); - } - #endif - } - - // is_final - { - #if (EA_COMPILER_HAS_FEATURE(is_final)) - static_assert(std::is_final<FinalStruct>::value == eastl::is_final<FinalStruct>::value, "final struct not correctly detected"); - static_assert(std::is_final<FinalClass>::value == eastl::is_final<FinalClass>::value, "final class not correctly detected"); - static_assert(std::is_final<Enum>::value == eastl::is_final<Enum>::value, "enum not correctly detected"); - static_assert(std::is_final<int>::value == eastl::is_final<int>::value, "int not correctly detected"); - static_assert(std::is_final<Struct>::value == eastl::is_final<Struct>::value, "non-final struct not correctly detected"); - static_assert(std::is_final<Class>::value == eastl::is_final<Class>::value, "non-final class not correctly detected"); - #endif - - // endian (big-endian and little; no mixed-endian/middle-endian) - static_assert(eastl::endian::big != eastl::endian::little, "little-endian and big-endian are not the same"); - static_assert(eastl::endian::native == eastl::endian::big || eastl::endian::native == eastl::endian::little, "native may be little endian or big endian"); - static_assert(!(eastl::endian::native == eastl::endian::big && eastl::endian::native == eastl::endian::little), "native cannot be both big and little endian"); - - #ifdef EA_SYSTEM_LITTLE_ENDIAN - static_assert(eastl::endian::native == eastl::endian::little, "must be little endian"); - static_assert(eastl::endian::native != eastl::endian::big, "must not be big endian"); - #else - static_assert(eastl::endian::native != eastl::endian::little, "must not be little endian"); - static_assert(eastl::endian::native == eastl::endian::big, "must be big endian"); - #endif - } - - // has_equality - { - static_assert( has_equality_v<int>, "has_equality failure"); - static_assert( has_equality_v<short>, "has_equality failure"); - static_assert( has_equality_v<long>, "has_equality failure"); - static_assert( has_equality_v<long long>, "has_equality failure"); - static_assert( has_equality_v<TestObject>, "has_equality failure"); - static_assert(!has_equality_v<MissingEquality>, "has_equality failure"); - } - - // is_aggregate - #if EASTL_TYPE_TRAIT_is_aggregate_CONFORMANCE - { - static_assert(!is_aggregate_v<int>, "is_aggregate failure"); - static_assert( is_aggregate_v<int[]>, "is_aggregate failure"); - - { - struct Aggregrate {}; - static_assert(is_aggregate_v<Aggregrate>, "is_aggregate failure"); - } - - { - struct NotAggregrate { NotAggregrate() {} }; // user provided ctor - static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure"); - } - - #if defined(EA_COMPILER_CPP11_ENABLED) && !defined(EA_COMPILER_CPP14_ENABLED) - // See https://en.cppreference.com/w/cpp/language/aggregate_initialization - // In C++11 the requirement was added to aggregate types that no default member initializers exist, - // however this requirement was removed in C++14. - { - struct NotAggregrate { int data = 42; }; // default member initializer - static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure"); - } - #endif - - { - struct NotAggregrate { virtual void foo() {} }; // virtual member function - static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure"); - } - } - #endif - - // is_complete_type - { - struct Foo - { - int x; - }; - - struct FooEmpty - { - }; - - struct Bar; - - void FooFunc(); - - static_assert(eastl::internal::is_complete_type_v<Foo>, "is_complete_type failure"); - static_assert(eastl::internal::is_complete_type_v<FooEmpty>, "is_complete_type failure"); - static_assert(!eastl::internal::is_complete_type_v<Bar>, "is_complete_type failure"); - static_assert(!eastl::internal::is_complete_type_v<void>, "is_complete_type failure"); - static_assert(!eastl::internal::is_complete_type_v<volatile void>, "is_complete_type failure"); - static_assert(!eastl::internal::is_complete_type_v<const void>, "is_complete_type failure"); - static_assert(!eastl::internal::is_complete_type_v<const volatile void>, "is_complete_type failure"); - static_assert(eastl::internal::is_complete_type_v<decltype(FooFunc)>, "is_complete_type failure"); - } - - - return nErrorCount; -} diff --git a/test/source/TestUtility.cpp b/test/source/TestUtility.cpp deleted file mode 100644 index e9027e5..0000000 --- a/test/source/TestUtility.cpp +++ /dev/null @@ -1,915 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EASTL/utility.h> -#include <EAStdC/EAString.h> - -struct BasicObject -{ - int mX; - BasicObject(int x) : mX(x) {} -}; - -inline bool operator==(const BasicObject& t1, const BasicObject& t2) { return t1.mX == t2.mX; } - -inline bool operator<(const BasicObject& t1, const BasicObject& t2) { return t1.mX < t2.mX; } - -/////////////////////////////////////////////////////////////////////////////// -// TestUtilityPair -// -static int TestUtilityPair() -{ - using namespace eastl; - - int nErrorCount = 0; - - { - int _0 = 0, _2 = 2, _3 = 3; - float _1f = 1.f; - - // pair(); - pair<int, float> ifPair1; - EATEST_VERIFY((ifPair1.first == 0) && (ifPair1.second == 0.f)); - - // pair(const T1& x, const T2& y); - pair<int, float> ifPair2(_0, _1f); - EATEST_VERIFY((ifPair2.first == 0) && (ifPair2.second == 1.f)); - - // template <typename U, typename V> - // pair(U&& u, V&& v); - pair<int, float> ifPair3(int(0), float(1.f)); - EATEST_VERIFY((ifPair3.first == 0) && (ifPair3.second == 1.f)); - - // template <typename U> - // pair(U&& x, const T2& y); - const float fConst1 = 1.f; - pair<int, float> ifPair4(int(0), fConst1); - EATEST_VERIFY((ifPair4.first == 0) && (ifPair4.second == 1.f)); - - // template <typename V> - // pair(const T1& x, V&& y); - const int intConst0 = 0; - pair<int, float> ifPair5(intConst0, float(1.f)); - EATEST_VERIFY((ifPair5.first == 0) && (ifPair5.second == 1.f)); - - pair<const int, const int> constIntPair(_2, _3); - EATEST_VERIFY((constIntPair.first == 2) && (constIntPair.second == 3)); - - // pair(const pair&) = default; - pair<int, float> ifPair2Copy(ifPair2); - EATEST_VERIFY((ifPair2Copy.first == 0) && (ifPair2Copy.second == 1.f)); - - pair<const int, const int> constIntPairCopy(constIntPair); - EATEST_VERIFY((constIntPairCopy.first == 2) && (constIntPairCopy.second == 3)); - - // template<typename U, typename V> - // pair(const pair<U, V>& p); - pair<long, double> idPair2(ifPair2); - EATEST_VERIFY((idPair2.first == 0) && (idPair2.second == 1.0)); - - // pair(pair&& p); - - // template<typename U, typename V> - // pair(pair<U, V>&& p); - - // pair& operator=(const pair& p); - - // template<typename U, typename V> - // pair& operator=(const pair<U, V>& p); - - // pair& operator=(pair&& p); - - // template<typename U, typename V> - // pair& operator=(pair<U, V>&& p); - - // void swap(pair& p); - - // use_self, use_first, use_second - use_self<pair<int, float> > usIFPair; - use_first<pair<int, float> > u1IFPair; - use_second<pair<int, float> > u2IFPair; - - ifPair2 = usIFPair(ifPair2); - EATEST_VERIFY((ifPair2.first == 0) && (ifPair2.second == 1)); - - int first = u1IFPair(ifPair2); - EATEST_VERIFY(first == 0); - - float second = u2IFPair(ifPair2); - EATEST_VERIFY(second == 1); - - // make_pair - pair<int, float> p1 = make_pair(int(0), float(1)); - EATEST_VERIFY((p1.first == 0) && (p1.second == 1.f)); - - pair<int, float> p2 = make_pair_ref(int(0), float(1)); - EATEST_VERIFY((p2.first == 0) && (p2.second == 1.f)); - - pair<const char*, int> p3 = eastl::make_pair("a", 1); - EATEST_VERIFY((EA::StdC::Strcmp(p3.first, "a") == 0) && (p3.second == 1)); - - pair<const char*, int> p4 = eastl::make_pair<const char*, int>("a", 1); - EATEST_VERIFY((EA::StdC::Strcmp(p4.first, "a") == 0) && (p4.second == 1)); - - pair<int, const char*> p5 = eastl::make_pair<int, const char*>(1, "b"); - EATEST_VERIFY((p5.first == 1) && (EA::StdC::Strcmp(p5.second, "b") == 0)); - -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - pair<int, int> p6 = eastl::make_pair<int, int>(1, 2); - pair<int, int> p7 = eastl::make_pair<int, int>(2, 1); - pair<int, int> p8 = eastl::make_pair<int, int>(7, 8); - pair<int, int> p9 = eastl::make_pair<int, int>(10, 1); - - EATEST_VERIFY( (p6 <=> p7) != 0); - EATEST_VERIFY( (p6 <=> p6) == 0); - EATEST_VERIFY( (p7 <=> p8) < 0); - EATEST_VERIFY( (p7 <=> p8) <= 0); - EATEST_VERIFY( (p9 <=> p8) > 0); - EATEST_VERIFY( (p9 <=> p8) >= 0); -#endif - -#if !defined(EA_COMPILER_NO_AUTO) - auto p60 = eastl::make_pair("a", "b"); // Different strings of same length of 1. - EATEST_VERIFY((EA::StdC::Strcmp(p60.first, "a") == 0) && (EA::StdC::Strcmp(p60.second, "b") == 0)); - - auto p61 = eastl::make_pair("ab", "cd"); // Different strings of same length > 1. - EATEST_VERIFY((EA::StdC::Strcmp(p61.first, "ab") == 0) && (EA::StdC::Strcmp(p61.second, "cd") == 0)); - - auto p62 = eastl::make_pair("abc", "bcdef"); // Different strings of different length. - EATEST_VERIFY((EA::StdC::Strcmp(p62.first, "abc") == 0) && (EA::StdC::Strcmp(p62.second, "bcdef") == 0)); - - char strA[] = "a"; - auto p70 = eastl::make_pair(strA, strA); - EATEST_VERIFY((EA::StdC::Strcmp(p70.first, "a") == 0) && (EA::StdC::Strcmp(p70.second, "a") == 0)); - - char strBC[] = "bc"; - auto p71 = eastl::make_pair(strA, strBC); - EATEST_VERIFY((EA::StdC::Strcmp(p71.first, "a") == 0) && (EA::StdC::Strcmp(p71.second, "bc") == 0)); - - const char cstrA[] = "a"; - auto p80 = eastl::make_pair(cstrA, cstrA); - EATEST_VERIFY((EA::StdC::Strcmp(p80.first, "a") == 0) && (EA::StdC::Strcmp(p80.second, "a") == 0)); - - const char cstrBC[] = "bc"; - auto p81 = eastl::make_pair(cstrA, cstrBC); - EATEST_VERIFY((EA::StdC::Strcmp(p81.first, "a") == 0) && (EA::StdC::Strcmp(p81.second, "bc") == 0)); -#endif - } - - { -// One-off tests and regressions - -#if EASTL_PAIR_CONFORMANCE // See http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#811 - pair<char*, char*> zeroLiteralPair(0, 0); - EATEST_VERIFY((zeroLiteralPair.first == NULL) && (zeroLiteralPair.second == NULL)); -#endif - - // template<typename U> - // pair(U&& x, const T2& y) - typedef eastl::pair<uint16_t, const char8_t*> LCIDMapping; - LCIDMapping lcidMappingArray[1] = {LCIDMapping(0x0036, EA_CHAR8("af"))}; // Note that 0x0036 is of type int. - EATEST_VERIFY((lcidMappingArray[0].first == 0x0036)); - - // template<typename V> - // pair(const T1& x, V&& y) - typedef eastl::pair<const char8_t*, uint16_t> LCIDMapping2; - LCIDMapping2 lcidMapping2Array[1] = {LCIDMapping2(EA_CHAR8("af"), 0x0036)}; - EATEST_VERIFY((lcidMapping2Array[0].second == 0x0036)); - -// The following code was giving an EDG compiler: -// error 145: a value of type "int" cannot be used to initialize -// an entity of type "void *" second(eastl::forward<V>(v)) {} -// template <typename U, typename V> -// pair(U&& u, V&& v); -#if EASTL_PAIR_CONFORMANCE - typedef eastl::pair<float*, void*> TestPair1; - float fOne = 1.f; - TestPair1 testPair1(&fOne, NULL); - EATEST_VERIFY(*testPair1.first == 1.f); -#endif - } - -#ifndef EA_COMPILER_NO_STRUCTURED_BINDING - // pair structured bindings test - { - eastl::pair<int, int> t = {1,2}; - auto [x,y] = t; - EATEST_VERIFY(x == 1); - EATEST_VERIFY(y == 2); - } - - { - auto t = eastl::make_pair(1, 2); - auto [x,y] = t; - EATEST_VERIFY(x == 1); - EATEST_VERIFY(y == 2); - } - - { // reported user-regression structured binding unpacking for iterators - eastl::vector<int> v = {1,2,3,4,5,6}; - auto t = eastl::make_pair(v.begin(), v.end() - 1); - auto [x,y] = t; - EATEST_VERIFY(*x == 1); - EATEST_VERIFY(*y == 6); - } - - { // reported user-regression structured binding unpacking for iterators - eastl::vector<int> v = {1,2,3,4,5,6}; - auto t = eastl::make_pair(v.begin(), v.end()); - auto [x,y] = t; - EATEST_VERIFY(*x == 1); - EA_UNUSED(y); - } - - { // reported user-regression for const structured binding unpacking for iterators - eastl::vector<int> v = {1,2,3,4,5,6}; - const auto [x,y] = eastl::make_pair(v.begin(), v.end());; - EATEST_VERIFY(*x == 1); - EA_UNUSED(y); - } -#endif - - return nErrorCount; -} - -/////////////////////////////////////////////////////////////////////////////// -// TestUtilityRelops -// -static int TestUtilityRelops() -{ - int nErrorCount = 0; - - { - using namespace eastl::rel_ops; // Defines default versions of operators !=, <, >, <=, >= based on == and <. - - BasicObject bo1(1), bo2(2); - - EATEST_VERIFY(!(bo1 == bo2)); - EATEST_VERIFY((bo1 != bo2)); - EATEST_VERIFY((bo1 < bo2)); - EATEST_VERIFY(!(bo1 > bo2)); - EATEST_VERIFY((bo1 <= bo2)); - EATEST_VERIFY(!(bo1 >= bo2)); - } - - return nErrorCount; -} - -// ThrowSwappable -struct ThrowSwappable -{ -}; - -void swap(ThrowSwappable& x, ThrowSwappable& y) EA_NOEXCEPT_IF(false) -{ - ThrowSwappable temp(x); - x = y; - y = temp; - -#if EASTL_EXCEPTIONS_ENABLED - throw int(); -#endif -} - -#if EASTL_TYPE_TRAIT_is_nothrow_swappable_CONFORMANCE -// NoThrowSwappable -struct NoThrowSwappable -{ -}; - -void swap(NoThrowSwappable& x, NoThrowSwappable& y) EA_NOEXCEPT_IF(true) -{ - NoThrowSwappable temp(x); - x = y; - y = temp; -} -#endif - -struct Swappable1 {}; -struct Swappable2 {}; -struct Swappable3 {}; -void swap(Swappable1&, Swappable2&) {} -void swap(Swappable2&, Swappable1&) {} -void swap(Swappable1&, Swappable3&) {} // intentionally missing 'swap(Swappable3, Swappable1)' - - -static int TestUtilitySwap() -{ - int nErrorCount = 0; - -// is_swappable -// is_nothrow_swappable -#if EASTL_TYPE_TRAIT_is_swappable_CONFORMANCE - static_assert((eastl::is_swappable<int>::value == true), "is_swappable failure"); - static_assert((eastl::is_swappable<eastl::vector<int> >::value == true), "is_swappable failure"); - static_assert((eastl::is_swappable<ThrowSwappable>::value == true), "is_swappable failure"); - #if EASTL_VARIABLE_TEMPLATES_ENABLED - static_assert((eastl::is_swappable_v<int> == true), "is_swappable failure"); - static_assert((eastl::is_swappable_v<eastl::vector<int> > == true), "is_swappable failure"); - static_assert((eastl::is_swappable_v<ThrowSwappable> == true), "is_swappable failure"); - #endif -// Need to come up with a class that's not swappable. How do we do that, given the universal swap template? -// static_assert((eastl::is_swappable<?>::value == false), "is_swappable failure"); -#endif - -#if EASTL_TYPE_TRAIT_is_nothrow_swappable_CONFORMANCE - static_assert((eastl::is_nothrow_swappable<int>::value == true), "is_nothrow_swappable failure"); // There currently isn't any specialization for swap of scalar types that's nothrow. - static_assert((eastl::is_nothrow_swappable<eastl::vector<int> >::value == false), "is_nothrow_swappable failure"); - static_assert((eastl::is_nothrow_swappable<ThrowSwappable>::value == false), "is_nothrow_swappable failure"); - static_assert((eastl::is_nothrow_swappable<NoThrowSwappable>::value == true), "is_nothrow_swappable failure"); - #if EASTL_VARIABLE_TEMPLATES_ENABLED - static_assert((eastl::is_nothrow_swappable_v<int> == true), "is_nothrow_swappable failure"); // There currently isn't any specialization for swap of scalar types that's nothrow. - static_assert((eastl::is_nothrow_swappable_v<eastl::vector<int>> == false), "is_nothrow_swappable failure"); - static_assert((eastl::is_nothrow_swappable_v<ThrowSwappable> == false), "is_nothrow_swappable failure"); - static_assert((eastl::is_nothrow_swappable_v<NoThrowSwappable> == true), "is_nothrow_swappable failure"); - #endif -#endif - -#if EASTL_VARIADIC_TEMPLATES_ENABLED -// is_swappable_with -// is_nothrow_swappable_with - static_assert(eastl::is_swappable_with<int&, int&>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<int, int>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<int&, int>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<int, int&>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<int, short>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<int, long>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<int, eastl::vector<int>>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<void, void>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<int, void>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<void, int>::value, "is_swappable_with failure"); - static_assert(!eastl::is_swappable_with<ThrowSwappable, ThrowSwappable>::value, "is_swappable_with failure"); - static_assert(eastl::is_swappable_with<ThrowSwappable&, ThrowSwappable&>::value, "is_swappable_with failure"); - static_assert(eastl::is_swappable_with<Swappable1&, Swappable1&>::value, "is_swappable_with failure"); - static_assert(eastl::is_swappable_with<Swappable1&, Swappable2&>::value, "is_swappable_with failure"); - static_assert(eastl::is_swappable_with<Swappable2&, Swappable1&>::value, "is_swappable_with failure"); - - #if EASTL_VARIABLE_TEMPLATES_ENABLED - static_assert(eastl::is_swappable_with_v<int&, int&>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<int, int>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<int&, int>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<int, int&>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<int, short>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<int, long>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<int, eastl::vector<int>>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<void, void>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<int, void>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<void, int>, "is_swappable_with_v failure"); - static_assert(!eastl::is_swappable_with_v<ThrowSwappable, ThrowSwappable>, "is_swappable_with_v failure"); - static_assert(eastl::is_swappable_with_v<ThrowSwappable&, ThrowSwappable&>, "is_swappable_with_v failure"); - static_assert(eastl::is_swappable_with_v<Swappable1&, Swappable1&>, "is_swappable_with_v failure"); - static_assert(eastl::is_swappable_with_v<Swappable1&, Swappable2&>, "is_swappable_with_v failure"); - static_assert(eastl::is_swappable_with_v<Swappable2&, Swappable1&>, "is_swappable_with_v failure"); - #endif // EASTL_VARIABLE_TEMPLATES_ENABLED - -#if EASTL_TYPE_TRAIT_is_nothrow_swappable_with_CONFORMANCE - static_assert(eastl::is_nothrow_swappable_with<int&, int&>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<int, int>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<int&, int>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<int, int&>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<int, short>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<int, long>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<int, eastl::vector<int>>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<void, void>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<int, void>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<void, int>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<ThrowSwappable, ThrowSwappable>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<ThrowSwappable&, ThrowSwappable&>::value, "is_nothrow_swappable_with failure"); - static_assert(!eastl::is_nothrow_swappable_with<NoThrowSwappable, NoThrowSwappable>::value, "is_nothrow_swappable_with failure"); - static_assert(eastl::is_nothrow_swappable_with<NoThrowSwappable&, NoThrowSwappable&>::value, "is_nothrow_swappable_with failure"); - - #if EASTL_VARIABLE_TEMPLATES_ENABLED - static_assert(eastl::is_nothrow_swappable_with_v<int&, int&>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<int, int>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<int&, int>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<int, int&>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<int, short>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<int, long>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<int, eastl::vector<int>>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<void, void>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<int, void>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<void, int>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<ThrowSwappable, ThrowSwappable>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<ThrowSwappable&, ThrowSwappable&>, "is_nothrow_swappable_with_v failure"); - static_assert(!eastl::is_nothrow_swappable_with_v<NoThrowSwappable, NoThrowSwappable>, "is_nothrow_swappable_with_v failure"); - static_assert(eastl::is_nothrow_swappable_with_v<NoThrowSwappable&, NoThrowSwappable&>, "is_nothrow_swappable_with_v failure"); - #endif // EASTL_VARIABLE_TEMPLATES_ENABLED -#endif -#endif // EASTL_VARIADIC_TEMPLATES_ENABLED - - return nErrorCount; -} - -#if !defined(EA_COMPILER_NO_NOEXCEPT) - -/////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Warning C4626 warns against an implicitly deleted move assignment operator. -// This warning was disabled by default in VS2013. It was enabled by default in -// VS2015. Since the the tests below are explicitly testing move construction -// of the various classes explicitly deleting the move assignment to remove the -// warning is safe. -// -// https://msdn.microsoft.com/en-us/library/23k5d385.aspx - -struct noexcept_move_copy -{ - bool mStatus; - - noexcept_move_copy() : mStatus(true) {} - - noexcept_move_copy(const noexcept_move_copy&) = default; - - noexcept_move_copy(noexcept_move_copy&& r) noexcept { r.mStatus = false; } - - noexcept_move_copy& operator=(const noexcept_move_copy&) = delete; // required as VS2015 enabled C4626 by default. -}; - -struct noexcept_move_no_copy -{ - bool mStatus; - - noexcept_move_no_copy() : mStatus(true) {} - - noexcept_move_no_copy(const noexcept_move_no_copy&) = delete; - - noexcept_move_no_copy(noexcept_move_no_copy&& r) noexcept { r.mStatus = false; }; - - noexcept_move_no_copy& operator=(const noexcept_move_no_copy&) = delete; // required as VS2015 enabled C4626 by default. -}; - -struct except_move_copy -{ - bool mStatus; - - except_move_copy() : mStatus(true) {} - - except_move_copy(const except_move_copy&) = default; - - except_move_copy(except_move_copy&& r) noexcept(false) { r.mStatus = false; }; - - except_move_copy& operator=(const except_move_copy&) = delete; // required as VS2015 enabled C4626 by default. -}; - -struct except_move_no_copy -{ - bool mStatus; - - except_move_no_copy() : mStatus(true) {} - - except_move_no_copy(const except_move_no_copy&) = delete; - - except_move_no_copy(except_move_no_copy&& r) noexcept(false) { r.mStatus = false; }; - - except_move_no_copy& operator=(const except_move_no_copy&) = delete; // required as VS2015 enabled C4626 by default. -}; -#endif - -static int TestUtilityMove() -{ - int nErrorCount = 0; - -// move_if_noexcept -#if !defined(EA_COMPILER_NO_NOEXCEPT) - noexcept_move_copy nemcA; - noexcept_move_copy nemcB = - eastl::move_if_noexcept(nemcA); // nemcB should be constructed via noexcept_move_copy(noexcept_move_copy&&) - EATEST_VERIFY(nemcA.mStatus == false); - EA_UNUSED(nemcB); - - noexcept_move_no_copy nemncA; - noexcept_move_no_copy nemncB = eastl::move_if_noexcept( - nemncA); // nemncB should be constructed via noexcept_move_no_copy(noexcept_move_no_copy&&) - EATEST_VERIFY(nemncA.mStatus == false); - EA_UNUSED(nemncB); - - except_move_copy emcA; - except_move_copy emcB = eastl::move_if_noexcept( - emcA); // emcB should be constructed via except_move_copy(const except_move_copy&) if exceptions are enabled. -#if EASTL_EXCEPTIONS_ENABLED - EATEST_VERIFY(emcA.mStatus == true); -#else - EATEST_VERIFY(emcA.mStatus == false); -#endif - EA_UNUSED(emcB); - - except_move_no_copy emncA; - except_move_no_copy emncB = - eastl::move_if_noexcept(emncA); // emncB should be constructed via except_move_no_copy(except_move_no_copy&&) - EATEST_VERIFY(emncA.mStatus == false); - EA_UNUSED(emncB); -#endif - - return nErrorCount; -} - -static int TestUtilityIntegerSequence() -{ - using namespace eastl; - int nErrorCount = 0; -#if EASTL_VARIADIC_TEMPLATES_ENABLED - - EATEST_VERIFY((integer_sequence<int, 0, 1, 2, 3, 4>::size() == 5)); - EATEST_VERIFY((make_integer_sequence<int, 5>::size() == 5)); - static_assert(is_same<make_integer_sequence<int, 5>, integer_sequence<int, 0, 1, 2, 3, 4>>::value); - - EATEST_VERIFY((index_sequence<0, 1, 2, 3, 4>::size() == 5)); - EATEST_VERIFY((make_index_sequence<5>::size() == 5)); - static_assert(is_same<make_index_sequence<5>, index_sequence<0, 1, 2, 3, 4>>::value); - static_assert(is_same<make_index_sequence<5>, integer_sequence<size_t, 0, 1, 2, 3, 4>>::value); -#endif // EASTL_VARIADIC_TEMPLATES_ENABLED - - return nErrorCount; -} - -static int TestUtilityExchange() -{ - int nErrorCount = 0; - - { - int a = 0; - auto r = eastl::exchange(a, 1); - - EATEST_VERIFY(r == 0); - EATEST_VERIFY(a == 1); - } - - { - int a = 0; - auto r = eastl::exchange(a, 1.78); - - EATEST_VERIFY(r == 0); - EATEST_VERIFY(a == 1); - } - - { - int a = 0; - auto r = eastl::exchange(a, 1.78f); - - EATEST_VERIFY(r == 0); - EATEST_VERIFY(a == 1); - } - - { - int a = 0, b = 1; - auto r = eastl::exchange(a, b); - - EATEST_VERIFY(r == 0); - EATEST_VERIFY(a == 1); - EATEST_VERIFY(b == 1); - } - - { - bool b = true; - - auto r = eastl::exchange(b, true); - EATEST_VERIFY(r); - - r = eastl::exchange(b, false); - EATEST_VERIFY(r); - EATEST_VERIFY(!b); - - r = eastl::exchange(b, true); - EATEST_VERIFY(!r); - EATEST_VERIFY(b); - } - - { - TestObject::Reset(); - - TestObject a(42); - auto r = eastl::exchange(a, TestObject(24)); - - EATEST_VERIFY(r.mX == 42); - EATEST_VERIFY(a.mX == 24); - } - - { - const char* const pElectronicArts = "Electronic Arts"; - const char* const pEAVancouver = "EA Vancouver"; - - eastl::string a(pElectronicArts); - auto r = eastl::exchange(a, pEAVancouver); - - EATEST_VERIFY(r == pElectronicArts); - EATEST_VERIFY(a == pEAVancouver); - - r = eastl::exchange(a, "EA Standard Template Library"); - EATEST_VERIFY(a == "EA Standard Template Library"); - } - - // Construct pair using single move constructor - { - struct TestPairSingleMoveConstructor - { - void test(int&& val) - { - eastl::pair<int,int> p(eastl::pair_first_construct, eastl::move(val)); - } - }; - - int i1 = 1; - TestPairSingleMoveConstructor test; - test.test(eastl::move(i1)); - } - - // User reported regression where via reference collapsing, we see the same single element ctor defined twice. - // - // T = const U& - // pair(const T&) -> pair(const const U& &) -> pair(const U&) - // pair(T&&) -> pair(const U& &&) -> pair(const U&) - { - struct FooType {}; - - using VectorOfPairWithReference = eastl::vector<eastl::pair<const FooType&, float>>; - - VectorOfPairWithReference v; - } - - return nErrorCount; -} - -#if defined(EA_COMPILER_CPP20_ENABLED) -template <typename T> -static int TestCmpCommon() -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::cmp_equal(T(0), T(0))); - EATEST_VERIFY(eastl::cmp_equal(T(1), T(1))); - EATEST_VERIFY(eastl::cmp_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min())); - EATEST_VERIFY(eastl::cmp_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max())); - EATEST_VERIFY(!eastl::cmp_equal(T(0), T(1))); - EATEST_VERIFY(!eastl::cmp_equal(T(1), T(0))); - if (eastl::is_signed_v<T>) - { - EATEST_VERIFY(eastl::cmp_equal(T(-1), T(-1))); - EATEST_VERIFY(!eastl::cmp_equal(T(-1), T(-2))); - EATEST_VERIFY(!eastl::cmp_equal(T(-2), T(-1))); - } - - EATEST_VERIFY(eastl::cmp_not_equal(T(1), T(0))); - EATEST_VERIFY(eastl::cmp_not_equal(T(0), T(1))); - EATEST_VERIFY(eastl::cmp_not_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max())); - EATEST_VERIFY(eastl::cmp_not_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min())); - if (eastl::is_signed_v<T>) - { - EATEST_VERIFY(!eastl::cmp_not_equal(T(-1), T(-1))); - EATEST_VERIFY(eastl::cmp_not_equal(T(-1), T(-2))); - EATEST_VERIFY(eastl::cmp_not_equal(T(-2), T(-1))); - } - - EATEST_VERIFY(eastl::cmp_less(T(0), T(1))); - EATEST_VERIFY(eastl::cmp_less(T(5), T(10))); - EATEST_VERIFY(!eastl::cmp_less(T(0), T(0))); - EATEST_VERIFY(!eastl::cmp_less(T(1), T(0))); - EATEST_VERIFY(eastl::cmp_less(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max())); - EATEST_VERIFY(!eastl::cmp_less(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min())); - EATEST_VERIFY(!eastl::cmp_less(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max())); - EATEST_VERIFY(!eastl::cmp_less(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min())); - if (eastl::is_signed_v<T>) - { - EATEST_VERIFY(!eastl::cmp_less(T(-1), T(-1))); - EATEST_VERIFY(!eastl::cmp_less(T(-1), T(-2))); - EATEST_VERIFY(eastl::cmp_less(T(-2), T(-1))); - } - - EATEST_VERIFY(eastl::cmp_less_equal(T(0), T(1))); - EATEST_VERIFY(eastl::cmp_less_equal(T(5), T(10))); - EATEST_VERIFY(eastl::cmp_less_equal(T(0), T(0))); - EATEST_VERIFY(eastl::cmp_less_equal(T(1), T(1))); - EATEST_VERIFY(!eastl::cmp_less_equal(T(1), T(0))); - EATEST_VERIFY(eastl::cmp_less_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max())); - EATEST_VERIFY(eastl::cmp_less_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min())); - EATEST_VERIFY(eastl::cmp_less_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max())); - EATEST_VERIFY(!eastl::cmp_less_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min())); - if (eastl::is_signed_v<T>) - { - EATEST_VERIFY(eastl::cmp_less_equal(T(-1), T(-1))); - EATEST_VERIFY(!eastl::cmp_less_equal(T(-1), T(-2))); - EATEST_VERIFY(eastl::cmp_less_equal(T(-2), T(-1))); - } - - EATEST_VERIFY(eastl::cmp_greater(T(1), T(0))); - EATEST_VERIFY(eastl::cmp_greater(T(10), T(5))); - EATEST_VERIFY(!eastl::cmp_greater(T(0), T(0))); - EATEST_VERIFY(!eastl::cmp_greater(T(0), T(1))); - EATEST_VERIFY(eastl::cmp_greater(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min())); - EATEST_VERIFY(!eastl::cmp_greater(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min())); - EATEST_VERIFY(!eastl::cmp_greater(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max())); - EATEST_VERIFY(!eastl::cmp_greater(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max())); - if (eastl::is_signed_v<T>) - { - EATEST_VERIFY(!eastl::cmp_greater(T(-1), T(-1))); - EATEST_VERIFY(eastl::cmp_greater(T(-1), T(-2))); - EATEST_VERIFY(!eastl::cmp_greater(T(-2), T(-1))); - } - - EATEST_VERIFY(eastl::cmp_greater_equal(T(1), T(0))); - EATEST_VERIFY(eastl::cmp_greater_equal(T(10), T(5))); - EATEST_VERIFY(eastl::cmp_greater_equal(T(0), T(0))); - EATEST_VERIFY(!eastl::cmp_greater_equal(T(0), T(1))); - EATEST_VERIFY(eastl::cmp_greater_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::min())); - EATEST_VERIFY(eastl::cmp_greater_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::min())); - EATEST_VERIFY(eastl::cmp_greater_equal(eastl::numeric_limits<T>::max(), eastl::numeric_limits<T>::max())); - EATEST_VERIFY(!eastl::cmp_greater_equal(eastl::numeric_limits<T>::min(), eastl::numeric_limits<T>::max())); - if (eastl::is_signed_v<T>) - { - EATEST_VERIFY(eastl::cmp_greater_equal(T(-1), T(-1))); - EATEST_VERIFY(eastl::cmp_greater_equal(T(-1), T(-2))); - EATEST_VERIFY(!eastl::cmp_greater_equal(T(-2), T(-1))); - } - - return nErrorCount; -} - -template <typename T, typename U> -static int TestUtilityCmpEql(const T x, const U y) -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::cmp_equal(T(x), U(y))); - EATEST_VERIFY(eastl::cmp_equal(U(y), T(x))); - EATEST_VERIFY(!eastl::cmp_not_equal(T(x), U(y))); - EATEST_VERIFY(!eastl::cmp_not_equal(U(y), T(x))); - - return nErrorCount; -} - -template <typename T, typename U> -static int TestUtilityCmpLess(const T x, const U y) -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::cmp_less(T(x), U(y))); - EATEST_VERIFY(!eastl::cmp_less(U(y), T(x))); - - EATEST_VERIFY(!eastl::cmp_greater_equal(T(x), U(y))); - EATEST_VERIFY(eastl::cmp_greater_equal(U(y), T(x))); - - return nErrorCount; -} - -template <typename T, typename U> -static int TestUtilityCmpGreater(const T x, const U y) -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::cmp_greater(T(x), U(y))); - EATEST_VERIFY(!eastl::cmp_greater(U(y), T(x))); - - EATEST_VERIFY(!eastl::cmp_less_equal(T(x), U(y))); - EATEST_VERIFY(eastl::cmp_less_equal(U(y), T(x))); - - return nErrorCount; -} - -template <typename T, typename U> -static int TestUtilityCmpLessEq(const T x, const U y) -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::cmp_less_equal(T(x), U(y))); - EATEST_VERIFY(eastl::cmp_less(T(x), U(y)) || eastl::cmp_equal(T(x), U(y))); - - EATEST_VERIFY(eastl::cmp_greater_equal(U(y), T(x))); - - return nErrorCount; -} - -template <typename T, typename U> -static int TestUtilityCmpGreaterEq(const T x, const U y) -{ - int nErrorCount = 0; - - EATEST_VERIFY(eastl::cmp_greater_equal(T(x), U(y))); - EATEST_VERIFY(eastl::cmp_greater(T(x), U(y)) || eastl::cmp_equal(T(x), U(y))); - - EATEST_VERIFY(eastl::cmp_less_equal(U(y), T(x))); - - return nErrorCount; -} - -static int TestUtilityIntegralComp() -{ - int nErrorCount = 0; - - // Test integral comparisons among same types - nErrorCount += TestCmpCommon<int>(); - nErrorCount += TestCmpCommon<short>(); - nErrorCount += TestCmpCommon<long>(); - nErrorCount += TestCmpCommon<long long>(); - - nErrorCount += TestCmpCommon<unsigned int>(); - nErrorCount += TestCmpCommon<unsigned short>(); - nErrorCount += TestCmpCommon<unsigned long>(); - nErrorCount += TestCmpCommon<unsigned long long>(); - - // Test integral comparison among different types - nErrorCount += TestUtilityCmpEql(int(0), short(0)); - nErrorCount += TestUtilityCmpEql(short(2), long(2)); - nErrorCount += TestUtilityCmpEql(short(3), unsigned long(3)); - nErrorCount += TestUtilityCmpEql(int(-5), long long(-5)); - nErrorCount += TestUtilityCmpEql(short(-100), long long(-100)); - nErrorCount += TestUtilityCmpEql(unsigned int(100), long(100)); - nErrorCount += TestUtilityCmpEql(unsigned long long(100), int(100)); - - nErrorCount += TestUtilityCmpLess(int(0), long long(1)); - nErrorCount += TestUtilityCmpLess(int(-1), unsigned long(1)); - nErrorCount += TestUtilityCmpLess(short(-100), long long(100)); - nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<long>::min(), short(0)); - nErrorCount += TestUtilityCmpLess(short(0), eastl::numeric_limits<int>::max()); - nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<unsigned short>::min(), eastl::numeric_limits<int>::max()); - nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<short>::max(), eastl::numeric_limits<long>::max()); - nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<int>::max(), eastl::numeric_limits<long long>::max()); - nErrorCount += TestUtilityCmpLess(int(-100), unsigned int(0)); - nErrorCount += TestUtilityCmpLess(eastl::numeric_limits<int>::min(), eastl::numeric_limits<unsigned int>::min()); - - nErrorCount += TestUtilityCmpGreater(int(1), short(0)); - nErrorCount += TestUtilityCmpGreater(unsigned long(1), int(-1)); - nErrorCount += TestUtilityCmpGreater(unsigned long long(100), short(-100)); - nErrorCount += TestUtilityCmpGreater(short(0), eastl::numeric_limits<short>::min()); - nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<long>::max(), unsigned short(5)); - nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<long>::max(), eastl::numeric_limits<int>::min()); - nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<int>::max(), eastl::numeric_limits<short>::max()); - nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<long long>::max(), eastl::numeric_limits<int>::max()); - nErrorCount += TestUtilityCmpGreater(unsigned int(0), int(-100)); - nErrorCount += TestUtilityCmpGreater(eastl::numeric_limits<unsigned int>::min(), eastl::numeric_limits<int>::min()); - - nErrorCount += TestUtilityCmpLessEq(int(0), short(1)); - nErrorCount += TestUtilityCmpLessEq(int(-1), long long(-1)); - nErrorCount += TestUtilityCmpLessEq(short(-100), unsigned long long(100)); - nErrorCount += TestUtilityCmpLessEq(short(-100), long long(-100)); - nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<int>::min(), short(0)); - nErrorCount += TestUtilityCmpLessEq(short(0), eastl::numeric_limits<int>::max()); - nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<short>::min(), eastl::numeric_limits<short>::min()); - nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<int>::max(), eastl::numeric_limits<int>::max()); - nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<int>::max(), eastl::numeric_limits<long long>::max()); - nErrorCount += TestUtilityCmpLessEq(int(50), unsigned int(50)); - nErrorCount += TestUtilityCmpLessEq(eastl::numeric_limits<int>::min(), eastl::numeric_limits<unsigned int>::min()); - - nErrorCount += TestUtilityCmpGreaterEq(int(1), short(1)); - nErrorCount += TestUtilityCmpGreaterEq(long long(-1), int(-1)); - nErrorCount += TestUtilityCmpGreaterEq(long long(-100), short(-100)); - nErrorCount += TestUtilityCmpGreaterEq(short(0), long(0)); - nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<long>::max(), eastl::numeric_limits<long>::max()); - nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<int>::max(), eastl::numeric_limits<short>::min()); - nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<int>::max(), eastl::numeric_limits<short>::max()); - nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<long long>::max(), eastl::numeric_limits<int>::max()); - nErrorCount += TestUtilityCmpGreaterEq(unsigned int(0), int(0)); - nErrorCount += TestUtilityCmpGreaterEq(eastl::numeric_limits<unsigned int>::min(), eastl::numeric_limits<int>::min()); - - // Test in_range - EATEST_VERIFY(eastl::in_range<int>(0)); - EATEST_VERIFY(eastl::in_range<int>(eastl::numeric_limits<int>::min())); - EATEST_VERIFY(eastl::in_range<int>(eastl::numeric_limits<int>::max())); - EATEST_VERIFY(eastl::in_range<unsigned int>(0)); - EATEST_VERIFY(eastl::in_range<unsigned int>(eastl::numeric_limits<unsigned int>::min())); - EATEST_VERIFY(eastl::in_range<unsigned int>(eastl::numeric_limits<unsigned int>::max())); - EATEST_VERIFY(!eastl::in_range<unsigned int>(-1)); - EATEST_VERIFY(!eastl::in_range<int>(eastl::numeric_limits<unsigned int>::max())); - EATEST_VERIFY(!eastl::in_range<unsigned int>(eastl::numeric_limits<int>::min())); - - EATEST_VERIFY(eastl::in_range<short>(100)); - EATEST_VERIFY(eastl::in_range<short>(eastl::numeric_limits<short>::min())); - EATEST_VERIFY(eastl::in_range<short>(eastl::numeric_limits<short>::max())); - EATEST_VERIFY(eastl::in_range<unsigned short>(100)); - EATEST_VERIFY(eastl::in_range<unsigned short>(eastl::numeric_limits<unsigned short>::min())); - EATEST_VERIFY(eastl::in_range<unsigned short>(eastl::numeric_limits<unsigned short>::max())); - EATEST_VERIFY(!eastl::in_range<unsigned short>(-1)); - EATEST_VERIFY(!eastl::in_range<short>(eastl::numeric_limits<unsigned int>::max())); - EATEST_VERIFY(!eastl::in_range<unsigned short>(eastl::numeric_limits<int>::min())); - - EATEST_VERIFY(eastl::in_range<long>(50)); - EATEST_VERIFY(eastl::in_range<long>(eastl::numeric_limits<long>::min())); - EATEST_VERIFY(eastl::in_range<long>(eastl::numeric_limits<long>::max())); - EATEST_VERIFY(eastl::in_range<unsigned long>(50)); - EATEST_VERIFY(eastl::in_range<unsigned long>(eastl::numeric_limits<unsigned long>::min())); - EATEST_VERIFY(eastl::in_range<unsigned long>(eastl::numeric_limits<unsigned long>::max())); - EATEST_VERIFY(!eastl::in_range<unsigned long>(-1)); - EATEST_VERIFY(!eastl::in_range<long>(eastl::numeric_limits<unsigned int>::max())); - EATEST_VERIFY(!eastl::in_range<unsigned long>(eastl::numeric_limits<int>::min())); - - return nErrorCount; -} -#endif - -/////////////////////////////////////////////////////////////////////////////// -// TestUtility -// -int TestUtility() -{ - int nErrorCount = 0; - - nErrorCount += TestUtilityPair(); - nErrorCount += TestUtilityRelops(); - nErrorCount += TestUtilitySwap(); - nErrorCount += TestUtilityMove(); - nErrorCount += TestUtilityIntegerSequence(); - nErrorCount += TestUtilityExchange(); -#if defined(EA_COMPILER_CPP20_ENABLED) - nErrorCount += TestUtilityIntegralComp(); -#endif - return nErrorCount; -} diff --git a/test/source/TestVariant.cpp b/test/source/TestVariant.cpp deleted file mode 100644 index 2a78a89..0000000 --- a/test/source/TestVariant.cpp +++ /dev/null @@ -1,1823 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EASTL/string.h> -#include <EASTL/algorithm.h> -#include <EASTL/sort.h> -#include <EASTL/bonus/overloaded.h> - -#ifdef EA_COMPILER_CPP14_ENABLED -#include "ConceptImpls.h" -#include <EASTL/variant.h> - - -#if EASTL_EXCEPTIONS_ENABLED - -// Intentionally Non-Trivial. -// There are optimizations we can make in variant if the types are trivial that we don't currently do but can do. -template <typename T> -struct valueless_struct -{ - valueless_struct() {} - - valueless_struct(const valueless_struct&) {} - - ~valueless_struct() {} - - struct exception_tag {}; - - operator T() const { throw exception_tag{}; } -}; - -#endif - - -int TestVariantAlternative() -{ - using namespace eastl; - int nErrorCount = 0; - { - using v_t = variant<int>; - static_assert(is_same_v<variant_alternative_t<0, v_t>, int>, "error variant_alternative"); - } - { - using v_t = variant<int, long, short, char>; - - static_assert(is_same_v<variant_alternative_t<0, v_t>, int>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<1, v_t>, long>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<2, v_t>, short>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<3, v_t>, char>, "error variant_alternative"); - } - { - struct custom_type1 {}; - struct custom_type2 {}; - struct custom_type3 {}; - - using v_t = variant<int, long, short, char, size_t, unsigned, signed, custom_type1, custom_type2, custom_type3>; - - static_assert(is_same_v<variant_alternative_t<5, v_t>, unsigned>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<6, v_t>, signed>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<7, v_t>, custom_type1>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<8, v_t>, custom_type2>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<9, v_t>, custom_type3>, "error variant_alternative"); - } - // cv-qualifier tests - { - using v_t = variant<int, const int, volatile int, const volatile int>; - - static_assert(is_same_v<variant_alternative_t<0, v_t>, int>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<1, v_t>, const int>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<2, v_t>, volatile int>, "error variant_alternative"); - static_assert(is_same_v<variant_alternative_t<3, v_t>, const volatile int>, "error variant_alternative"); - } - return nErrorCount; -} - -int TestVariantSize() -{ - using namespace eastl; - int nErrorCount = 0; - - static_assert(variant_size<variant<int>>() == 1, "error variant_size"); - static_assert(variant_size<variant<int, int>>() == 2, "error variant_size"); - static_assert(variant_size<variant<int, int, int, int>>() == 4, "error variant_size"); - static_assert(variant_size<variant<const int>>() == 1, "error variant_size"); - static_assert(variant_size<variant<volatile int>>() == 1, "error variant_size"); - static_assert(variant_size<variant<const volatile int>>() == 1, "error variant_size"); - - static_assert(variant_size_v<variant<int>> == 1, "error variant_size"); - static_assert(variant_size_v<variant<int, int>> == 2, "error variant_size"); - static_assert(variant_size_v<variant<int, int, int, int>> == 4, "error variant_size"); - static_assert(variant_size_v<variant<const int>> == 1, "error variant_size"); - static_assert(variant_size_v<variant<volatile int>> == 1, "error variant_size"); - static_assert(variant_size_v<variant<const volatile int>> == 1, "error variant_size"); - - static_assert(variant_size_v<variant<int, int>> == 2, "error variant_size_v"); - static_assert(variant_size_v<variant<volatile int, const int>> == 2, "error variant_size_v"); - static_assert(variant_size_v<variant<volatile int, const int, const volatile int>> == 3, "error variant_size_v"); - - return nErrorCount; -} - -int TestVariantHash() -{ - using namespace eastl; - int nErrorCount = 0; - - { hash<monostate> h; EA_UNUSED(h); } - - return nErrorCount; -} - -int TestVariantBasic() -{ - using namespace eastl; - int nErrorCount = 0; - - { VERIFY(variant_npos == size_t(-1)); } - - { variant<int> v; EA_UNUSED(v); } - { variant<int, short> v; EA_UNUSED(v); } - { variant<int, short, float> v; EA_UNUSED(v); } - { variant<int, short, float, char> v; EA_UNUSED(v); } - { variant<int, short, float, char, long> v; EA_UNUSED(v); } - { variant<int, short, float, char, long, long long> v; EA_UNUSED(v); } - { variant<int, short, float, char, long, long long, double> v; EA_UNUSED(v); } - - { variant<monostate> v; EA_UNUSED(v); } - { variant<monostate, NotDefaultConstructible> v; EA_UNUSED(v); } - { variant<int, NotDefaultConstructible> v; EA_UNUSED(v); } - - { - struct MyObj - { - MyObj() : i(1337) {} - ~MyObj() {} - - int i; - }; - - struct MyObj2 - { - MyObj2(int& ii) : i(ii) {} - ~MyObj2() {} - - MyObj2& operator=(const MyObj2&) = delete; - - int& i; - }; - - static_assert(!eastl::is_trivially_destructible_v<MyObj>, "MyObj can't be trivially destructible"); - static_assert(!eastl::is_trivially_destructible_v<MyObj2>, "MyObj2 can't be trivially destructible"); - - { - eastl::variant<MyObj, MyObj2> myVar; - VERIFY(get<MyObj>(myVar).i == 1337); - } - - { - eastl::variant<MyObj, MyObj2> myVar = MyObj(); - VERIFY(get<MyObj>(myVar).i == 1337); - } - - { - int i = 42; - eastl::variant<MyObj, MyObj2> myVar = MyObj2(i); - VERIFY(get<MyObj2>(myVar).i == 42); - } - - { - auto m = MyObj(); - m.i = 2000; - - eastl::variant<MyObj, MyObj2> myVar = m; - VERIFY(get<MyObj>(myVar).i == 2000); - } - } - - { variant<int, int> v; EA_UNUSED(v); } - { variant<const short, volatile short, const volatile short> v; EA_UNUSED(v); } - { variant<int, int, const short, volatile short, const volatile short> v; EA_UNUSED(v); } - - { - // verify constructors and destructors are called - { - variant<TestObject> v = TestObject(1337); - VERIFY((get<TestObject>(v)).mX == 1337); - - variant<TestObject> vCopy = v; - VERIFY((get<TestObject>(vCopy)).mX == 1337); - } - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - { - variant<string> v; - VERIFY(*(get_if<string>(&v)) == ""); - VERIFY(get_if<string>(&v)->empty()); - VERIFY(get_if<string>(&v)->length() == 0); - VERIFY(get_if<string>(&v)->size() == 0); - - *(get_if<string>(&v)) += 'a'; - VERIFY(*(get_if<string>(&v)) == "a"); - } - - return nErrorCount; -} - -int TestVariantGet() -{ - using namespace eastl; - int nErrorCount = 0; - - { - const char* strValue = "canada"; - using v_t = variant<int, string>; - { - v_t v; - v = 42; - VERIFY(v.index() == 0); - VERIFY(*get_if<int>(&v) == 42); - VERIFY(get<int>(v) == 42); - VERIFY( holds_alternative<int>(v)); - VERIFY(!holds_alternative<string>(v)); - } - { - v_t v; - v = strValue; - VERIFY(v.index() == 1); - VERIFY(*get_if<string>(&v) == strValue); - VERIFY(get<string>(v) == strValue); - VERIFY(!holds_alternative<int>(v)); - VERIFY(holds_alternative<string>(v)); - VERIFY(get<string>(move(v)) == strValue); - } - { - v_t v; - v = 42; - VERIFY(v.index() == 0); - VERIFY(*get_if<0>(&v) == 42); - VERIFY(get<0>(v) == 42); - VERIFY( holds_alternative<int>(v)); - VERIFY(!holds_alternative<string>(v)); - } - { - v_t v; - v = strValue; - VERIFY(v.index() == 1); - VERIFY(*get_if<1>(&v) == strValue); - VERIFY(get<1>(v) == strValue); - VERIFY(!holds_alternative<int>(v)); - VERIFY( holds_alternative<string>(v)); - } - { - v_t v; - v = strValue; - VERIFY(v.index() == 1); - VERIFY(*get_if<1>(&v) == strValue); - VERIFY(get_if<0>(&v) == nullptr); - } - { - VERIFY(get_if<0>((v_t*)nullptr) == nullptr); - VERIFY(get_if<1>((v_t*)nullptr) == nullptr); - } - } - - return nErrorCount; -} - -int TestVariantHoldsAlternative() -{ - using namespace eastl; - int nErrorCount = 0; - - { - { - using v_t = variant<int, short>; // default construct first type - v_t v; - - VERIFY(!holds_alternative<long>(v)); // Verify that a query for a T not in the variant typelist returns false. - VERIFY(!holds_alternative<string>(v)); // Verify that a query for a T not in the variant typelist returns false. - VERIFY( holds_alternative<int>(v)); // variant does hold an int, because its a default constructible first parameter - VERIFY(!holds_alternative<short>(v)); // variant does not hold a short - } - - { - using v_t = variant<monostate, int, short>; // default construct monostate - v_t v; - - VERIFY(!holds_alternative<long>(v)); // Verify that a query for a T not in the variant typelist returns false. - VERIFY(!holds_alternative<string>(v)); // Verify that a query for a T not in the variant typelist returns false. - VERIFY(!holds_alternative<int>(v)); // variant does not hold an int - VERIFY(!holds_alternative<short>(v)); // variant does not hold a short - } - - { - using v_t = variant<monostate, int>; - - { - v_t v; - VERIFY(!holds_alternative<int>(v)); // variant does not hold an int - - v = 42; - VERIFY(holds_alternative<int>(v)); // variant does hold an int - } - - { - v_t v1, v2; - VERIFY(!holds_alternative<int>(v1)); - VERIFY(!holds_alternative<int>(v2)); - - v1 = 42; - VERIFY(holds_alternative<int>(v1)); - VERIFY(!holds_alternative<int>(v2)); - - eastl::swap(v1, v2); - VERIFY(!holds_alternative<int>(v1)); - VERIFY(holds_alternative<int>(v2)); - } - } - } - - return nErrorCount; -} - -int TestVariantValuelessByException() -{ - using namespace eastl; - int nErrorCount = 0; - - { - { - using v_t = variant<int, short>; - static_assert(eastl::is_default_constructible_v<v_t>, "valueless_by_exception error"); - - v_t v; - VERIFY(!v.valueless_by_exception()); - - v = 42; - VERIFY(!v.valueless_by_exception()); - } - - { - using v_t = variant<monostate, int>; - static_assert(eastl::is_default_constructible_v<v_t>, "valueless_by_exception error"); - - v_t v1, v2; - VERIFY(!v1.valueless_by_exception()); - VERIFY(!v2.valueless_by_exception()); - - v1 = 42; - VERIFY(!v1.valueless_by_exception()); - VERIFY(!v2.valueless_by_exception()); - - eastl::swap(v1, v2); - VERIFY(!v1.valueless_by_exception()); - VERIFY(!v2.valueless_by_exception()); - - v1 = v2; - VERIFY(!v1.valueless_by_exception()); - VERIFY(!v2.valueless_by_exception()); - } - - { - struct NotDefaultConstructibleButHasConversionCtor - { - NotDefaultConstructibleButHasConversionCtor() = delete; - NotDefaultConstructibleButHasConversionCtor(int) {} - }; - static_assert(!eastl::is_default_constructible<NotDefaultConstructibleButHasConversionCtor>::value, "valueless_by_exception error"); - - using v_t = variant<NotDefaultConstructibleButHasConversionCtor>; - v_t v(42); - static_assert(!eastl::is_default_constructible_v<v_t>, "valueless_by_exception error"); - VERIFY(!v.valueless_by_exception()); - } - - // TODO(rparolin): review exception safety for variant types - // - // { - // #if EASTL_EXCEPTIONS_ENABLED - // struct DefaultConstructibleButThrows - // { - // DefaultConstructibleButThrows() {} - // ~DefaultConstructibleButThrows() {} - // - // DefaultConstructibleButThrows(DefaultConstructibleButThrows&&) { throw 42; } - // DefaultConstructibleButThrows(const DefaultConstructibleButThrows&) { throw 42; } - // DefaultConstructibleButThrows& operator=(const DefaultConstructibleButThrows&) { throw 42; } - // DefaultConstructibleButThrows& operator=(DefaultConstructibleButThrows&&) { throw 42; } - // }; - // - // using v_t = variant<DefaultConstructibleButThrows>; - // - // v_t v1; - // VERIFY(!v1.valueless_by_exception()); - // - // try - // { - // v1 = DefaultConstructibleButThrows(); - // } - // catch (...) - // { - // VERIFY(v1.valueless_by_exception()); - // } - // #endif - // } - } - - return nErrorCount; -} - -int TestVariantCopyAndMove() -{ - using namespace eastl; - int nErrorCount = 0; - - { - { - using v_t = variant<int, short, char>; - - v_t v1 = 42; - v_t v2 = v1; - - VERIFY(get<int>(v2) == get<int>(v1)); - } - - } - - return nErrorCount; -} - -int TestVariantEmplace() -{ - using namespace eastl; - int nErrorCount = 0; - - { - variant<int> v; - v.emplace<int>(42); - VERIFY(get<int>(v) == 42); - } - { - variant<int> v; - v.emplace<0>(42); - VERIFY(get<0>(v) == 42); - } - - { - variant<int, short, long> v; - - v.emplace<0>(42); - VERIFY(get<0>(v) == 42); - - v.emplace<1>(short(43)); - VERIFY(get<1>(v) == short(43)); - - v.emplace<2>(44L); - VERIFY(get<2>(v) == 44L); - } - { - variant<int, short, long> v; - - v.emplace<int>(42); - VERIFY(get<int>(v) == 42); - - v.emplace<short>(short(43)); - VERIFY(get<short>(v) == short(43)); - - v.emplace<long>(44L); - VERIFY(get<long>(v) == 44L); - } - - { - { - variant<TestObject> v; - v.emplace<0>(1337); - VERIFY(get<0>(v).mX == 1337); - } - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - { - { - variant<int, TestObject> v; - - v.emplace<int>(42); - VERIFY(get<int>(v) == 42); - - v.emplace<TestObject>(1337); - VERIFY(get<TestObject>(v).mX == 1337); - - v.emplace<TestObject>(1338, 42, 3); - VERIFY(get<TestObject>(v).mX == 1338 + 42 + 3); - } - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - { - { - struct r { - r() = default; - r(int x) : mX(x) {} - int mX; - }; - - variant<int, r> v; - - v.emplace<0>(42); - VERIFY(get<0>(v) == 42); - - v.emplace<1>(1337); - VERIFY(get<1>(v).mX == 1337); - } - } - - { - struct r { - r() = default; - r(int a, int b, int c, int d) : a(a), b(b), c(c), d(d) {} - r(std::initializer_list<int> l) - { - auto it = l.begin(); - - a = *it++; - b = *it++; - c = *it++; - d = *it++; - } - int a, b, c, d; - }; - - r aa{1,2,3,4}; - VERIFY(aa.a == 1); - VERIFY(aa.b == 2); - VERIFY(aa.c == 3); - VERIFY(aa.d == 4); - - variant<r> v; - v.emplace<0>(std::initializer_list<int>{1,2,3,4}); - - VERIFY(get<r>(v).a == 1); - VERIFY(get<r>(v).b == 2); - VERIFY(get<r>(v).c == 3); - VERIFY(get<r>(v).d == 4); - } - - return nErrorCount; -} - -int TestVariantSwap() -{ - using namespace eastl; - int nErrorCount = 0; - - { - variant<int, float> v1 = 42; - variant<int, float> v2 = 24; - - v1.swap(v2); - - VERIFY(get<int>(v1) == 24); - VERIFY(get<int>(v2) == 42); - - v1.swap(v2); - - VERIFY(get<int>(v1) == 42); - VERIFY(get<int>(v2) == 24); - } - - { - variant<string> v1 = "Hello"; - variant<string> v2 = "World"; - - VERIFY(get<string>(v1) == "Hello"); - VERIFY(get<string>(v2) == "World"); - - v1.swap(v2); - - VERIFY(get<string>(v1) == "World"); - VERIFY(get<string>(v2) == "Hello"); - } - - return nErrorCount; -} - -int TestVariantRelOps() -{ - using namespace eastl; - int nErrorCount = 0; - - { - variant<int, float> v1 = 42; - variant<int, float> v2 = 24; - variant<int, float> v1e = v1; - - VERIFY(v1 == v1e); - VERIFY(v1 != v2); - VERIFY(v1 > v2); - VERIFY(v2 < v1); - } - - { - vector<variant<int, string>> v = {{1}, {3}, {7}, {4}, {0}, {5}, {2}, {6}, {8}}; - eastl::sort(v.begin(), v.end()); - VERIFY(eastl::is_sorted(v.begin(), v.end())); - } - - return nErrorCount; -} - - -int TestVariantInplaceCtors() -{ - using namespace eastl; - int nErrorCount = 0; - - { - variant<int, int> v(in_place<0>, 42); - VERIFY(get<0>(v) == 42); - VERIFY(v.index() == 0); - } - - { - variant<int, int> v(in_place<1>, 42); - VERIFY(get<1>(v) == 42); - VERIFY(v.index() == 1); - } - - { - variant<int, string> v(in_place<int>, 42); - VERIFY(get<0>(v) == 42); - VERIFY(v.index() == 0); - } - - { - variant<int, string> v(in_place<string>, "hello"); - VERIFY(get<1>(v) == "hello"); - VERIFY(v.index() == 1); - } - - return nErrorCount; -} - -// Many Compilers are smart and will fully inline the visitor in our unittests, -// Thereby not actually testing the recursive call. -EA_NO_INLINE int TestVariantVisitNoInline(const eastl::variant<int, bool, unsigned>& v) -{ - int nErrorCount = 0; - - bool bVisited = false; - - struct MyVisitor - { - MyVisitor() = delete; - MyVisitor(bool& visited) : mVisited(visited) {}; - - void operator()(int) { mVisited = true; } - void operator()(bool) { mVisited = true; } - void operator()(unsigned) { mVisited = true; } - - bool& mVisited; - }; - - eastl::visit(MyVisitor(bVisited), v); - - EATEST_VERIFY(bVisited); - - return nErrorCount; -} - -EA_NO_INLINE int TestVariantVisit2NoInline(const eastl::variant<int, bool>& v0, const eastl::variant<int, bool>& v1) -{ - int nErrorCount = 0; - - bool bVisited = false; - - struct MyVisitor - { - MyVisitor() = delete; - MyVisitor(bool& visited) : mVisited(visited) {}; - - void operator()(int, int) { mVisited = true; } - void operator()(bool, int) { mVisited = true; } - void operator()(int, bool) { mVisited = true; } - void operator()(bool, bool) { mVisited = true; } - - bool& mVisited; - }; - - eastl::visit(MyVisitor(bVisited), v0, v1); - - EATEST_VERIFY(bVisited); - - return nErrorCount; -} - -EA_NO_INLINE int TestVariantVisit3tNoInline(const eastl::variant<int, bool>& v0, const eastl::variant<int, bool>& v1, const eastl::variant<int, bool>& v2) -{ - int nErrorCount = 0; - - bool bVisited = false; - - struct MyVisitor - { - MyVisitor() = delete; - MyVisitor(bool& visited) : mVisited(visited) {}; - - void operator()(int, int, int) { mVisited = true; } - void operator()(bool, int, int) { mVisited = true; } - void operator()(int, bool, int) { mVisited = true; } - void operator()(bool, bool, int) { mVisited = true; } - - void operator()(int, int, bool) { mVisited = true; } - void operator()(bool, int, bool) { mVisited = true; } - void operator()(int, bool, bool) { mVisited = true; } - void operator()(bool, bool, bool) { mVisited = true; } - - bool& mVisited; - }; - - eastl::visit(MyVisitor(bVisited), v0, v1, v2); - - EATEST_VERIFY(bVisited); - - return nErrorCount; -} - -int TestVariantVisitorOverloaded() -{ - using namespace eastl; - int nErrorCount = 0; - - using v_t = variant<int, string, double, long>; - v_t arr[] = {42, "jean", 42.0, 42L}; - v_t v{42.0}; - - - #ifdef __cpp_deduction_guides - { - int count = 0; - - for (auto& e : arr) - { - eastl::visit( - overloaded{ - [&](int) { count++; }, - [&](string) { count++; }, - [&](double) { count++; }, - [&](long) { count++; }}, - e - ); - } - - VERIFY(count == EAArrayCount(arr)); - } - - { - double visitedValue = 0.0f; - - eastl::visit( - overloaded{ - [](int) { }, - [](string) { }, - [&](double d) { visitedValue = d; }, - [](long) { }}, - v - ); - - VERIFY(visitedValue == 42.0f); - } - - #endif - - { - int count = 0; - - for (auto& e : arr) - { - eastl::visit( - eastl::make_overloaded( - [&](int) { count++; }, - [&](string) { count++; }, - [&](double) { count++; }, - [&](long) { count++; }), - e - ); - } - - VERIFY(count == EAArrayCount(arr)); - } - - { - double visitedValue = 0.0f; - - eastl::visit( - eastl::make_overloaded( - [](int) { }, - [](string) { }, - [&](double d) { visitedValue = d; }, - [](long) { }), - v - ); - - VERIFY(visitedValue == 42.0f); - } - - return nErrorCount; -} - -int TestVariantVisitor() -{ - using namespace eastl; - int nErrorCount = 0; - - using v_t = variant<int, string, double, long>; - - { - v_t arr[] = {42, "hello", 42.0, 42L}; - - int count = 0; - for (auto& e : arr) - { - eastl::visit([&](auto){ count++; }, e); - } - - VERIFY(count == EAArrayCount(arr)); - - count = 0; - for (auto& e : arr) - { - eastl::visit<void>([&](auto){ count++; }, e); - } - - VERIFY(count == EAArrayCount(arr)); - } - - { - static bool bVisited = false; - - variant<int, long, string> v = 42; - - struct MyVisitor - { - void operator()(int) { bVisited = true; }; - void operator()(long) { }; - void operator()(string) { }; - void operator()(unsigned) { }; // not in variant - }; - - visit(MyVisitor{}, v); - VERIFY(bVisited); - - bVisited = false; - - visit<void>(MyVisitor{}, v); - VERIFY(bVisited); - } - - { - static bool bVisited = false; - - variant<int, bool, unsigned> v = (int)1; - - struct MyVisitor - { - bool& operator()(int) { return bVisited; } - bool& operator()(bool) { return bVisited; } - bool& operator()(unsigned) { return bVisited; } - }; - - bool& ret = visit(MyVisitor{}, v); - ret = true; - VERIFY(bVisited); - - bVisited = false; - bool& ret2 = visit<bool&>(MyVisitor{}, v); - ret2 = true; - VERIFY(bVisited); - } - - { - variant<int, bool, unsigned> v = (int)1; - - struct MyVisitor - { - void operator()(int& i) { i = 2; } - void operator()(bool&) {} - void operator()(unsigned&) {} - }; - - visit(MyVisitor{}, v); - EATEST_VERIFY(get<0>(v) == (int)2); - - v = (int)1; - visit<void>(MyVisitor{}, v); - EATEST_VERIFY(get<0>(v) == (int)2); - } - - { - static bool bVisited = false; - - variant<int, bool, unsigned> v =(int)1; - - struct MyVisitor - { - void operator()(const int&) { bVisited = true; } - void operator()(const bool&) {} - void operator()(const unsigned&) {} - }; - - visit(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - - bVisited = false; - visit<void>(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - } - - { - static bool bVisited = false; - - const variant<int, bool, unsigned> v =(int)1; - - struct MyVisitor - { - void operator()(const int&) { bVisited = true; } - void operator()(const bool&) {} - void operator()(const unsigned&) {} - }; - - visit(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - - bVisited = false; - visit<void>(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - } - - { - static bool bVisited = false; - - struct MyVisitor - { - void operator()(int&&) { bVisited = true; } - void operator()(bool&&) {} - void operator()(unsigned&&) {} - }; - - visit(MyVisitor{}, variant<int, bool, unsigned>{(int)1}); - EATEST_VERIFY(bVisited); - - visit<void>(MyVisitor{}, variant<int, bool, unsigned>{(int)1}); - EATEST_VERIFY(bVisited); - } - - { - static bool bVisited = false; - - variant<int, bool, unsigned> v = (int)1; - - struct MyVisitor - { - bool&& operator()(int) { return eastl::move(bVisited); } - bool&& operator()(bool) { return eastl::move(bVisited); } - bool&& operator()(unsigned) { return eastl::move(bVisited); } - }; - - bool&& ret = visit(MyVisitor{}, v); - ret = true; - VERIFY(bVisited); - - bVisited = false; - bool&& ret2 = visit<bool&&>(MyVisitor{}, v); - ret2 = true; - VERIFY(bVisited); - } - - { - variant<int, bool, unsigned> v = (int)1; - - TestVariantVisitNoInline(v); - v = (bool)true; - TestVariantVisitNoInline(v); - v = (int)3; - TestVariantVisitNoInline(v); - } - - { - variant<int, bool> v0 = (int)1; - variant<int, bool> v1 = (bool)true; - - TestVariantVisit2NoInline(v0, v1); - v0 = (bool)false; - TestVariantVisit2NoInline(v0, v1); - v1 = (int)2; - TestVariantVisit2NoInline(v0, v1); - } - - { - variant<int, bool> v0 = (int)1; - variant<int, bool> v1 = (int)2; - variant<int, bool> v2 = (int)3; - - TestVariantVisit3tNoInline(v0, v1, v2); - v2 = (bool)false; - TestVariantVisit3tNoInline(v0, v1, v2); - v0 = (bool)true; - TestVariantVisit3tNoInline(v0, v1, v2); - } - - { - static bool bVisited = false; - - variant<int, string> i = 42; - variant<int, string> s = "hello"; - - struct MultipleVisitor - { - MultipleVisitor& operator()(int, int) { return *this; } - MultipleVisitor& operator()(int, string) { bVisited = true; return *this; } - MultipleVisitor& operator()(string, int) { return *this; } - MultipleVisitor& operator()(string, string) { return *this; } - }; - - MultipleVisitor& ret = visit(MultipleVisitor{}, i, s); - EA_UNUSED(ret); - VERIFY(bVisited); - - MultipleVisitor& ret2 = visit<MultipleVisitor&>(MultipleVisitor{}, i, s); - EA_UNUSED(ret2); - VERIFY(bVisited); - } - - { - bool bVisited = false; - - variant<int, bool> v0 = 0; - variant<int, bool> v1 = 1; - - struct MultipleVisitor - { - MultipleVisitor() = delete; - MultipleVisitor(bool& visited) : mVisited(visited) {}; - - void operator()(int, int) { mVisited = true; } - void operator()(int, bool) {} - void operator()(bool, int) {} - void operator()(bool, bool) {} - - bool& mVisited; - }; - - visit(MultipleVisitor(bVisited), v0, v1); - EATEST_VERIFY(bVisited); - - bVisited = false; - visit<void>(MultipleVisitor(bVisited), v0, v1); - EATEST_VERIFY(bVisited); - } - - { - variant<int, string> v = 42; - - struct ModifyingVisitor - { - void operator()(int &i) { i += 1; } - void operator()(string &s) { s += "hello"; } - }; - - visit(ModifyingVisitor{}, v); - VERIFY(get<0>(v) == 43); - } - - { - variant<int, string> v = 42; - - struct ReturningVisitor - { - int operator()(int i) {return i;} - int operator()(string s) {return 0;} - }; - - VERIFY(visit(ReturningVisitor{}, v) == 42); - } - - return nErrorCount; -} - -int TestVariantVisitorReturn() -{ - int nErrorCount = 0; - - { - static bool bVisited = false; - - eastl::variant<int, bool> v = (int)1; - - struct MyVisitor - { - bool operator()(int) { bVisited = true; return true; } - bool operator()(bool) { return false; } - }; - - eastl::visit<void>(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - } - - { - static bool bVisited = false; - - eastl::variant<int, bool> v = (int)1; - - struct MyVisitor - { - bool operator()(int) { bVisited = true; return true; } - bool operator()(bool) { return false; } - }; - - eastl::visit<const void>(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - } - - { - static bool bVisited = false; - - eastl::variant<int, bool> v = (int)1; - - struct MyVisitor - { - bool operator()(int) { bVisited = true; return true; } - bool operator()(bool) { return false; } - }; - - eastl::visit<volatile void>(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - } - - { - static bool bVisited = false; - - eastl::variant<int, bool> v = (int)1; - - struct MyVisitor - { - bool operator()(int) { bVisited = true; return true; } - bool operator()(bool) { return false; } - }; - - eastl::visit<const volatile void>(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - } - - { - static bool bVisited = false; - - eastl::variant<int, bool> v = (int)1; - - struct MyVisitor - { - bool operator()(int) { bVisited = true; return true; } - bool operator()(bool) { return false; } - }; - - int ret = eastl::visit<int>(MyVisitor{}, v); - EATEST_VERIFY(bVisited); - EATEST_VERIFY(ret); - } - - { - static bool bVisited = false; - - struct A {}; - struct B : public A {}; - struct C : public A {}; - - eastl::variant<int, bool> v = (int)1; - - struct MyVisitor - { - B operator()(int) { bVisited = true; return B{}; } - C operator()(bool) { return C{}; } - }; - - A ret = eastl::visit<A>(MyVisitor{}, v); - EA_UNUSED(ret); - EATEST_VERIFY(bVisited); - } - - { - static bool bVisited = false; - - eastl::variant<int, bool> v = (int)1; - - struct MyVisitor - { - MyVisitor operator()(int) { bVisited = true; return MyVisitor{}; } - MyVisitor operator()(bool) { return MyVisitor{}; } - }; - - MyVisitor ret = eastl::visit<MyVisitor>(MyVisitor{}, v); - EA_UNUSED(ret); - EATEST_VERIFY(bVisited); - } - - return nErrorCount; -} - -int TestVariantAssignment() -{ - using namespace eastl; - int nErrorCount = 0; - - { - variant<int, TestObject> v = TestObject(1337); - VERIFY(get<TestObject>(v).mX == 1337); - TestObject::Reset(); - - v.operator=(42); // ensure assignment-operator is called - VERIFY(TestObject::sTODtorCount == 1); // verify TestObject dtor is called. - VERIFY(get<int>(v) == 42); - TestObject::Reset(); - } - - return nErrorCount; -} - - -int TestVariantMoveOnly() -{ - using namespace eastl; - int nErrorCount = 0; - - { - variant<int, MoveOnlyType> v = MoveOnlyType(1337); - VERIFY(get<MoveOnlyType>(v).mVal == 1337); - } - - return nErrorCount; -} - - -//compilation test related to PR #315: converting constructor and assignment operator compilation error -void TestCompilation(const double e) { eastl::variant<double> v{e}; } - - - -int TestVariantUserRegressionCopyMoveAssignmentOperatorLeak() -{ - using namespace eastl; - int nErrorCount = 0; - - { - { - eastl::variant<TestObject> v = TestObject(1337); - VERIFY(eastl::get<TestObject>(v).mX == 1337); - eastl::variant<TestObject> v2 = TestObject(1338); - VERIFY(eastl::get<TestObject>(v2).mX == 1338); - v.operator=(v2); - VERIFY(eastl::get<TestObject>(v).mX == 1338); - VERIFY(eastl::get<TestObject>(v2).mX == 1338); - } - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - { - { - eastl::variant<TestObject> v = TestObject(1337); - VERIFY(eastl::get<TestObject>(v).mX == 1337); - eastl::variant<TestObject> v2 = TestObject(1338); - VERIFY(eastl::get<TestObject>(v2).mX == 1338); - v.operator=(eastl::move(v2)); - VERIFY(eastl::get<TestObject>(v).mX == 1338); - } - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - { - { - eastl::variant<TestObject> v = TestObject(1337); - VERIFY(eastl::get<TestObject>(v).mX == 1337); - v = {}; - VERIFY(eastl::get<TestObject>(v).mX == 0); - } - VERIFY(TestObject::IsClear()); - TestObject::Reset(); - } - - return nErrorCount; -} - -int TestVariantRelationalOperators() -{ - int nErrorCount = 0; - - using VariantNoThrow = eastl::variant<int, bool, float>; - - // Equality - { - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ true }; - - EATEST_VERIFY((v1 == v2) == false); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 == v2) == true); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)0 }; - - EATEST_VERIFY((v1 == v2) == false); - } - } - - // Inequality - { - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ true }; - - EATEST_VERIFY((v1 != v2) == true); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 != v2) == false); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)0 }; - - EATEST_VERIFY((v1 != v2) == true); - } - } - - // Less Than - { - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ true }; - - EATEST_VERIFY((v1 < v2) == true); - } - - { - VariantNoThrow v1{ true }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 < v2) == false); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 < v2) == false); - } - - { - VariantNoThrow v1{ (int)0 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 < v2) == true); - } - } - - // Greater Than - { - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ true }; - - EATEST_VERIFY((v1 > v2) == false); - } - - { - VariantNoThrow v1{ true }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 > v2) == true); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 > v2) == false); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)0 }; - - EATEST_VERIFY((v1 > v2) == true); - } - } - - // Less Equal - { - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ true }; - - EATEST_VERIFY((v1 <= v2) == true); - } - - { - VariantNoThrow v1{ true }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 <= v2) == false); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 <= v2) == true); - } - - { - VariantNoThrow v1{ (int)0 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 <= v2) == true); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)0 }; - - EATEST_VERIFY((v1 <= v2) == false); - } - } - - // Greater Equal - { - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ true }; - - EATEST_VERIFY((v1 >= v2) == false); - } - - { - VariantNoThrow v1{ true }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 >= v2) == true); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 >= v2) == true); - } - - { - VariantNoThrow v1{ (int)0 }; - VariantNoThrow v2{ (int)1 }; - - EATEST_VERIFY((v1 >= v2) == false); - } - - { - VariantNoThrow v1{ (int)1 }; - VariantNoThrow v2{ (int)0 }; - - EATEST_VERIFY((v1 >= v2) == true); - } - } - -#if EASTL_EXCEPTIONS_ENABLED - - using VariantThrow = eastl::variant<int, bool, float>; - - auto make_variant_valueless = [](VariantThrow& v) - { - try - { - v.emplace<0>(valueless_struct<int>{}); - } - catch(const typename valueless_struct<int>::exception_tag &) - { - } - }; - - // Equality - { - { - VariantThrow v0{ (int)0 }; - VariantThrow v1{ (int)1 }; - - make_variant_valueless(v0); - make_variant_valueless(v1); - - EATEST_VERIFY((v0 == v1) == true); - } - } - - // Inequality - { - { - VariantThrow v0{ (int)0 }; - VariantThrow v1{ (int)1 }; - - make_variant_valueless(v0); - make_variant_valueless(v1); - - EATEST_VERIFY((v0 != v1) == false); - } - } - - // Less Than - { - { - VariantThrow v0{ (int)0 }; - VariantThrow v1{ (int)1 }; - - make_variant_valueless(v0); - - EATEST_VERIFY((v0 < v1) == true); - } - - { - VariantThrow v0{ (int)0 }; - VariantThrow v1{ (int)1 }; - - make_variant_valueless(v1); - - EATEST_VERIFY((v0 < v1) == false); - } - } - - // Greater Than - { - { - VariantThrow v0{ (int)1 }; - VariantThrow v1{ (int)0 }; - - make_variant_valueless(v0); - - EATEST_VERIFY((v0 > v1) == false); - } - - { - VariantThrow v0{ (int)1 }; - VariantThrow v1{ (int)0 }; - - make_variant_valueless(v1); - - EATEST_VERIFY((v0 > v1) == true); - } - } - - // Less Equal - { - { - VariantThrow v0{ (int)1 }; - VariantThrow v1{ (int)1 }; - - make_variant_valueless(v0); - - EATEST_VERIFY((v0 <= v1) == true); - } - - { - VariantThrow v0{ (int)1 }; - VariantThrow v1{ (int)0 }; - - make_variant_valueless(v1); - - EATEST_VERIFY((v0 <= v1) == false); - } - } - - // Greater Equal - { - { - VariantThrow v0{ (int)1 }; - VariantThrow v1{ (int)1 }; - - make_variant_valueless(v0); - - EATEST_VERIFY((v0 >= v1) == false); - } - - { - VariantThrow v0{ (int)1 }; - VariantThrow v1{ (int)0 }; - - make_variant_valueless(v1); - - EATEST_VERIFY((v0 >= v1) == true); - } - } - -#endif - - return nErrorCount; -} - - -int TestVariantUserRegressionIncompleteType() -{ - using namespace eastl; - int nErrorCount = 0; - - { - struct B; - - struct A - { - vector<variant<B>> v; - }; - - struct B - { - vector<variant<A>> v; - }; - } - - return nErrorCount; -} - -#define EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(Type, VarName) \ - bool operator==(const Type & rhs) const { return VarName == rhs.VarName; } \ - bool operator!=(const Type & rhs) const { return VarName != rhs.VarName; } \ - bool operator<(const Type & rhs) const { return VarName < rhs.VarName; } \ - bool operator>(const Type & rhs) const { return VarName > rhs.VarName; } \ - bool operator<=(const Type & rhs) const { return VarName <= rhs.VarName; } \ - bool operator>=(const Type & rhs) const { return VarName >= rhs.VarName; } - -int TestBigVariantComparison() -{ - int nErrorCount = 0; - - struct A; - struct B; - struct C; - struct D; - struct E; - struct F; - struct G; - struct H; - struct I; - struct J; - struct K; - struct L; - struct M; - struct N; - struct O; - struct P; - struct Q; - struct R; - struct S; - struct T; - struct U; - struct V; - struct W; - struct X; - struct Y; - struct Z; - - using BigVariant = eastl::variant<A, B, C, D, E, F, G, H, I, J, K, L, M, N, - O, P, Q, R, S, T, U, V, W, X, Y, Z>; - - struct A { int a; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(A, a) }; - struct B { int b; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(B, b) }; - struct C { int c; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(C, c) }; - struct D { int d; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(D, d) }; - struct E { int e; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(E, e) }; - struct F { int f; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(F, f) }; - struct G { int g; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(G, g) }; - struct H { int h; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(H, h) }; - struct I { int i; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(I, i) }; - struct J { int j; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(J, j) }; - struct K { int k; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(K, k) }; - struct L { int l; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(L, l) }; - struct M { int m; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(M, m) }; - struct N { int n; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(N, n) }; - struct O { int o; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(O, o) }; - struct P { int p; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(P, p) }; - struct Q { int q; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(Q, q) }; - struct R { int r; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(R, r) }; - struct S { int s; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(S, s) }; - struct T { int t; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(T, t) }; - struct U { int u; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(U, u) }; - struct V { int v; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(V, v) }; - struct W { int w; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(W, w) }; - struct X { int x; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(X, x) }; - struct Y { int y; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(Y, y) }; - struct Z { int z; EASTL_TEST_BIG_VARIANT_RELATIONAL_OPS(Z, z) }; - - { - BigVariant v0{ A{0} }; - BigVariant v1{ A{1} }; - - VERIFY(v0 != v1); - } - - { - BigVariant v0{ A{0} }; - BigVariant v1{ A{1} }; - - VERIFY(v0 < v1); - } - - { - BigVariant v0{ A{0} }; - BigVariant v1{ A{0} }; - - VERIFY(v0 == v1); - } - - { - BigVariant v0{ A{1} }; - BigVariant v1{ A{0} }; - - VERIFY(v0 > v1); - } - - { - BigVariant v0{ A{0} }; - BigVariant v1{ A{1} }; - - VERIFY(v0 <= v1); - } - - { - BigVariant v0{ A{0} }; - BigVariant v1{ A{0} }; - - VERIFY(v0 <= v1); - } - - { - BigVariant v0{ A{0} }; - BigVariant v1{ A{0} }; - - VERIFY(v0 >= v1); - } - - { - BigVariant v0{ A{1} }; - BigVariant v1{ A{0} }; - - VERIFY(v0 >= v1); - } - - { - BigVariant v0{ A{0} }; - BigVariant v1{ B{0} }; - - VERIFY(v0 != v1); - } - - { - BigVariant v0{ A{0} }; - BigVariant v1{ B{0} }; - - VERIFY(v0 < v1); - } - - { - BigVariant v0{ A{0} }; - BigVariant v1{ B{0} }; - - VERIFY(v1 > v0); - } - - return nErrorCount; -} - -int TestVariantGeneratingComparisonOverloads(); - -int TestVariant() -{ - int nErrorCount = 0; - - nErrorCount += TestVariantBasic(); - nErrorCount += TestVariantSize(); - nErrorCount += TestVariantAlternative(); - nErrorCount += TestVariantValuelessByException(); - nErrorCount += TestVariantGet(); - nErrorCount += TestVariantHoldsAlternative(); - nErrorCount += TestVariantHash(); - nErrorCount += TestVariantCopyAndMove(); - nErrorCount += TestVariantSwap(); - nErrorCount += TestVariantEmplace(); - nErrorCount += TestVariantRelOps(); - nErrorCount += TestVariantInplaceCtors(); - nErrorCount += TestVariantVisitorOverloaded(); - nErrorCount += TestVariantVisitor(); - nErrorCount += TestVariantAssignment(); - nErrorCount += TestVariantMoveOnly(); - nErrorCount += TestVariantUserRegressionCopyMoveAssignmentOperatorLeak(); - nErrorCount += TestVariantUserRegressionIncompleteType(); - nErrorCount += TestVariantGeneratingComparisonOverloads(); - nErrorCount += TestBigVariantComparison(); - nErrorCount += TestVariantRelationalOperators(); - - return nErrorCount; -} -#else - int TestVariant() { return 0; } -#endif diff --git a/test/source/TestVariant2.cpp b/test/source/TestVariant2.cpp deleted file mode 100644 index e2bd90f..0000000 --- a/test/source/TestVariant2.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * NOTE: - * - * DO NOT INCLUDE EATest/EATest.h or ANY OTHER HEADER - * There is a bug in MSVC whereby pushing/poping all warnings from a header does not reenable all warnings - * in the TU that included the header. - * For example C4805 will not reenabled. - */ - -#include <EASTL/variant.h> - -int TestVariantGeneratingComparisonOverloads() -{ - int nErrorCount = 0; - - { - eastl::variant<int, float, bool> a; - eastl::variant<int, float, bool> b; - - auto r = a == b; - - nErrorCount += !r; - } - - { - eastl::variant<int, float, bool> a; - eastl::variant<int, float, bool> b; - - bool r = (a == b); - - nErrorCount += !r; - } - - // A variant is permitted to hold the same type more than once, and to hold differently cv-qualified versions of the same type. - - { - eastl::variant<int, int, int> a; - eastl::variant<int, int, int> b; - - bool r = (a == b); - - nErrorCount += !r; - } - - { - eastl::variant<signed int, unsigned int> a; - eastl::variant<signed int, unsigned int> b; - - bool r = (a == b); - - nErrorCount += !r; - } - - { - eastl::variant<int, bool> a; - eastl::variant<int, bool> b; - - bool r = (a == b); - - nErrorCount += !r; - } - - { - eastl::variant<volatile int, int, const int, const volatile int> a; - eastl::variant<volatile int, int, const int, const volatile int> b; - - bool r = (a == b); - - nErrorCount += !r; - } - - { - eastl::variant<volatile int, int, const int, const volatile int, bool> a; - eastl::variant<volatile int, int, const int, const volatile int, bool> b; - - bool r = (a == b); - - nErrorCount += !r; - } - - return nErrorCount; -} diff --git a/test/source/TestVector.cpp b/test/source/TestVector.cpp deleted file mode 100644 index 69cdb52..0000000 --- a/test/source/TestVector.cpp +++ /dev/null @@ -1,1821 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -#include "EASTLTest.h" -#include <EASTL/vector.h> -#include <EASTL/string.h> -#include <EASTL/deque.h> -#include <EASTL/list.h> -#include <EASTL/slist.h> -#include <EASTL/algorithm.h> -#include <EASTL/utility.h> -#include <EASTL/allocator_malloc.h> -#include <EASTL/unique_ptr.h> - -#include "ConceptImpls.h" - - -EA_DISABLE_ALL_VC_WARNINGS() -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <vector> - #include <string> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::vector<bool>; -template class eastl::vector<int>; -template class eastl::vector<Align64>; -template class eastl::vector<TestObject>; - - -// This tests "uninitialized_fill" usage in vector when T has a user provided -// address-of operator overload. In these situations, EASTL containers must use -// the standard utility "eastl::addressof(T)" which is designed to by-pass user -// provided address-of operator overloads. -// -// Previously written as: -// for(; first != last; ++first, ++currentDest) -// ::new((void*)&*currentDest) value_type(*first); // & not guaranteed to be a pointer -// -// Bypasses user 'addressof' operators: -// for(; n > 0; --n, ++currentDest) -// ::new(eastl::addressof(*currentDest)) value_type(value); // guaranteed to be a pointer -// -struct AddressOfOperatorResult {}; -struct HasAddressOfOperator -{ - // problematic 'addressof' operator that doesn't return a pointer type - AddressOfOperatorResult operator&() const { return {}; } - bool operator==(const HasAddressOfOperator&) const { return false; } -}; -template class eastl::vector<HasAddressOfOperator>; // force compile all functions of vector - - - -// Test compiler issue that appeared in VS2012 relating to kAlignment -struct StructWithContainerOfStructs -{ - eastl::vector<StructWithContainerOfStructs> children; -}; - - // This relatively complex test is to prevent a regression on VS2013. The data types have what may appear to be - // strange names (for test code) because the code is based on a test case extracted from the Frostbite codebase. - // This test is actually invalid and should be removed as const data memebers are problematic for STL container - // implementations. (ie. they prevent constructors from being generated). -namespace -{ - EA_DISABLE_VC_WARNING(4512) // disable warning : "assignment operator could not be generated" -#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) // VS2015-preview and later. - EA_DISABLE_VC_WARNING(5025) // disable warning : "move assignment operator could not be generated" - EA_DISABLE_VC_WARNING(4626) // disable warning : "assignment operator was implicitly defined as deleted" - EA_DISABLE_VC_WARNING(5027) // disable warning : "move assignment operator was implicitly defined as deleted" -#endif -struct ScenarioRefEntry -{ - ScenarioRefEntry(const eastl::string& contextDatabase) : ContextDatabase(contextDatabase) {} - - struct RowEntry - { - RowEntry(int levelId, int sceneId, int actorId, int partId, const eastl::string& controller) - : LevelId(levelId), SceneId(sceneId), ActorId(actorId), PartId(partId), Controller(controller) - { - } - - int LevelId; - int SceneId; - int ActorId; - int PartId; - const eastl::string& Controller; - }; - const eastl::string& ContextDatabase; // note: const class members prohibits move semantics - typedef eastl::vector<RowEntry> RowData; - RowData Rows; -}; -typedef eastl::vector<ScenarioRefEntry> ScenarRefData; -struct AntMetaDataRecord -{ - ScenarRefData ScenarioRefs; -}; -typedef eastl::vector<AntMetaDataRecord> MetadataRecords; - -struct StructWithConstInt -{ - StructWithConstInt(const int& _i) : i(_i) {} - const int i; -}; - -struct StructWithConstRefToInt -{ - StructWithConstRefToInt(const int& _i) : i(_i) {} - const int& i; -}; -#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) // VS2015-preview and later. - EA_RESTORE_VC_WARNING() // disable warning 5025: "move assignment operator could not be generated" - EA_RESTORE_VC_WARNING() // disable warning 4626: "assignment operator was implicitly defined as deleted" - EA_RESTORE_VC_WARNING() // disable warning 5027: "move assignment operator was implicitly defined as deleted" -#endif -EA_RESTORE_VC_WARNING() -} - -struct ItemWithConst -{ - ItemWithConst& operator=(const ItemWithConst&); - -public: - ItemWithConst(int _i) : i(_i) {} - ItemWithConst(const ItemWithConst& x) : i(x.i) {} - const int i; -}; - -struct testmovable -{ - EA_NON_COPYABLE(testmovable) -public: - testmovable() EA_NOEXCEPT {} - - testmovable(testmovable&&) EA_NOEXCEPT {} - - testmovable& operator=(testmovable&&) EA_NOEXCEPT { return *this; } -}; - -struct TestMoveAssignToSelf -{ - TestMoveAssignToSelf() EA_NOEXCEPT : mMovedToSelf(false) {} - TestMoveAssignToSelf(const TestMoveAssignToSelf& other) { mMovedToSelf = other.mMovedToSelf; } - TestMoveAssignToSelf& operator=(TestMoveAssignToSelf&&) { mMovedToSelf = true; return *this; } - TestMoveAssignToSelf& operator=(const TestMoveAssignToSelf&) = delete; - - bool mMovedToSelf; -}; - -#if EASTL_VARIABLE_TEMPLATES_ENABLED - /// custom type-trait which checks if a type is comparable via the <operator. - template <class, class = eastl::void_t<>> - struct is_less_comparable : eastl::false_type { }; - template <class T> - struct is_less_comparable<T, eastl::void_t<decltype(eastl::declval<T>() < eastl::declval<T>())>> : eastl::true_type { }; -#else - // bypass the test since the compiler doesn't support variable templates. - template <class> struct is_less_comparable : eastl::false_type { }; -#endif - - -int TestVector() -{ - int nErrorCount = 0; - eastl_size_t i; - - TestObject::Reset(); - - { - MetadataRecords mMetadataRecords; - AntMetaDataRecord r, s; - mMetadataRecords.push_back(r); - mMetadataRecords.push_back(s); - } - - { - using namespace eastl; - - // explicit vector(); - vector<int> intArray1; - vector<TestObject> toArray1; - vector<list<TestObject> > toListArray1; - - EATEST_VERIFY(intArray1.validate()); - EATEST_VERIFY(intArray1.empty()); - EATEST_VERIFY(toArray1.validate()); - EATEST_VERIFY(toArray1.empty()); - EATEST_VERIFY(toListArray1.validate()); - EATEST_VERIFY(toListArray1.empty()); - - // explicit vector(const allocator_type& allocator); - MallocAllocator::reset_all(); - MallocAllocator ma; - vector<int, MallocAllocator> intArray6(ma); - vector<TestObject, MallocAllocator> toArray6(ma); - vector<list<TestObject>, MallocAllocator> toListArray6(ma); - intArray6.resize(1); - toArray6.resize(1); - toListArray6.resize(1); - EATEST_VERIFY(MallocAllocator::mAllocCountAll == 3); - - // explicit vector(size_type n, const allocator_type& allocator = EASTL_VECTOR_DEFAULT_ALLOCATOR) - vector<int> intArray2(10); - vector<TestObject> toArray2(10); - vector<list<TestObject> > toListArray2(10); - - EATEST_VERIFY(intArray2.validate()); - EATEST_VERIFY(intArray2.size() == 10); - EATEST_VERIFY(toArray2.validate()); - EATEST_VERIFY(toArray2.size() == 10); - EATEST_VERIFY(toListArray2.validate()); - EATEST_VERIFY(toListArray2.size() == 10); - - // vector(size_type n, const value_type& value, const allocator_type& allocator = - // EASTL_VECTOR_DEFAULT_ALLOCATOR) - vector<int> intArray3(10, 7); - vector<TestObject> toArray3(10, TestObject(7)); - vector<list<TestObject> > toListArray3(10, list<TestObject>(7)); - - EATEST_VERIFY(intArray3.validate()); - EATEST_VERIFY(intArray3.size() == 10); - EATEST_VERIFY(intArray3[5] == 7); - EATEST_VERIFY(toArray3.validate()); - EATEST_VERIFY(toArray3[5] == TestObject(7)); - EATEST_VERIFY(toListArray3.validate()); - EATEST_VERIFY(toListArray3[5] == list<TestObject>(7)); - - // vector(const vector& x) - vector<int> intArray4(intArray2); - vector<TestObject> toArray4(toArray2); - vector<list<TestObject> > toListArray4(toListArray2); - - EATEST_VERIFY(intArray4.validate()); - EATEST_VERIFY(intArray4 == intArray2); - EATEST_VERIFY(toArray4.validate()); - EATEST_VERIFY(toArray4 == toArray2); - EATEST_VERIFY(intArray4.validate()); - EATEST_VERIFY(toListArray4 == toListArray2); - - // vector(const this_type& x, const allocator_type& allocator) - MallocAllocator::reset_all(); - vector<int, MallocAllocator> intArray7(intArray6, ma); - vector<TestObject, MallocAllocator> toArray7(toArray6, ma); - vector<list<TestObject>, MallocAllocator> toListArray7(toListArray6, ma); - EATEST_VERIFY(MallocAllocator::mAllocCountAll == 3); - - // vector(InputIterator first, InputIterator last) - deque<int> intDeque(3); - deque<TestObject> toDeque(3); - deque<list<TestObject> > toListDeque(3); - - vector<int> intArray5(intDeque.begin(), intDeque.end()); - vector<TestObject> toArray5(toDeque.begin(), toDeque.end()); - vector<list<TestObject> > toListArray5(toListDeque.begin(), toListDeque.end()); - - // vector(std::initializer_list<T> ilist, const Allocator& allocator = EASTL_VECTOR_DEFAULT_ALLOCATOR); - { -#if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - eastl::vector<float> floatVector{0, 1, 2, 3}; - - EATEST_VERIFY(floatVector.size() == 4); - EATEST_VERIFY((floatVector[0] == 0) && (floatVector[3] == 3)); -#endif - } - - // vector& operator=(const vector& x); - intArray3 = intArray4; - toArray3 = toArray4; - toListArray3 = toListArray4; - - EATEST_VERIFY(intArray3.validate()); - EATEST_VERIFY(intArray3 == intArray4); - EATEST_VERIFY(toArray3.validate()); - EATEST_VERIFY(toArray3 == toArray4); - EATEST_VERIFY(intArray3.validate()); - EATEST_VERIFY(toListArray3 == toListArray4); - -// this_type& operator=(std::initializer_list<T> ilist); -#if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - intArray3 = {0, 1, 2, 3}; - EATEST_VERIFY((intArray3.size() == 4) && (intArray3[0] == 0) && (intArray3[3] == 3)); -#endif - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { - using namespace eastl; - - // vector(this_type&& x) - // vector(this_type&& x, const Allocator& allocator) - // this_type& operator=(this_type&& x) - - vector<TestObject> vector3TO33(3, TestObject(33)); - vector<TestObject> toVectorA(eastl::move(vector3TO33)); - EATEST_VERIFY((toVectorA.size() == 3) && (toVectorA.front().mX == 33) && (vector3TO33.size() == 0)); - - // The following is not as strong a test of this ctor as it could be. A stronger test would be to use - // IntanceAllocator with different instances. - vector<TestObject, MallocAllocator> vector4TO44(4, TestObject(44)); - vector<TestObject, MallocAllocator> toVectorB(eastl::move(vector4TO44), MallocAllocator()); - EATEST_VERIFY((toVectorB.size() == 4) && (toVectorB.front().mX == 44) && (vector4TO44.size() == 0)); - - vector<TestObject, MallocAllocator> vector5TO55(5, TestObject(55)); - toVectorB = eastl::move(vector5TO55); - EATEST_VERIFY((toVectorB.size() == 5) && (toVectorB.front().mX == 55) && (vector5TO55.size() == 0)); - - // Should be able to emplace_back an item with const members (non-copyable) - eastl::vector<ItemWithConst> myVec2; - ItemWithConst& ref = myVec2.emplace_back(42); - EATEST_VERIFY(myVec2.back().i == 42); - EATEST_VERIFY(ref.i == 42); - } - - { - using namespace eastl; - - // pointer data(); - // const_pointer data() const; - // reference front(); - // const_reference front() const; - // reference back(); - // const_reference back() const; - - vector<int> intArray(10, 7); - intArray[0] = 10; - intArray[1] = 11; - intArray[2] = 12; - - EATEST_VERIFY(intArray.data() == &intArray[0]); - EATEST_VERIFY(*intArray.data() == 10); - EATEST_VERIFY(intArray.front() == 10); - EATEST_VERIFY(intArray.back() == 7); - - const vector<TestObject> toArrayC(10, TestObject(7)); - - EATEST_VERIFY(toArrayC.data() == &toArrayC[0]); - EATEST_VERIFY(*toArrayC.data() == TestObject(7)); - EATEST_VERIFY(toArrayC.front() == TestObject(7)); - EATEST_VERIFY(toArrayC.back() == TestObject(7)); - } - - { - using namespace eastl; - - // iterator begin(); - // const_iterator begin() const; - // iterator end(); - // const_iterator end() const; - // reverse_iterator rbegin(); - // const_reverse_iterator rbegin() const; - // reverse_iterator rend(); - // const_reverse_iterator rend() const; - - vector<int> intArray(20); - for (i = 0; i < 20; i++) - intArray[i] = (int)i; - - i = 0; - for (vector<int>::iterator it = intArray.begin(); it != intArray.end(); ++it, ++i) - EATEST_VERIFY(*it == (int)i); - - i = intArray.size() - 1; - for (vector<int>::reverse_iterator itr = intArray.rbegin(); itr != intArray.rend(); ++itr, --i) - EATEST_VERIFY(*itr == (int)i); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { - using namespace eastl; - - // void swap(vector& x); - // void assign(size_type n, const value_type& value); - // void assign(InputIterator first, InputIterator last); - - const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; - const int B[] = {99, 99, 99, 99, 99}; - const size_t N = sizeof(A) / sizeof(int); - const size_t M = sizeof(B) / sizeof(int); - - // assign from pointer range - vector<int> v3; - v3.assign(A, A + N); - EATEST_VERIFY(equal(v3.begin(), v3.end(), A)); - EATEST_VERIFY(v3.size() == N); - - // assign from iterator range - vector<int> v4; - v4.assign(v3.begin(), v3.end()); - EATEST_VERIFY(equal(v4.begin(), v4.end(), A)); - EATEST_VERIFY(equal(A, A + N, v4.begin())); - - // assign from initializer range with resize - v4.assign(M, 99); - EATEST_VERIFY(equal(v4.begin(), v4.end(), B)); - EATEST_VERIFY(equal(B, B + M, v4.begin())); - EATEST_VERIFY((v4.size() == M) && (M != N)); - -#if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - // void assign(std::initializer_list<T> ilist); - v4.assign({0, 1, 2, 3}); - EATEST_VERIFY(v4.size() == 4); - EATEST_VERIFY((v4[0] == 0) && (v4[3] == 3)); -#endif - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { - using namespace eastl; - - // reference operator[](size_type n); - // const_reference operator[](size_type n) const; - // reference at(size_type n); - // const_reference at(size_type n) const; - - vector<int> intArray(5); - EATEST_VERIFY(intArray[3] == 0); - EATEST_VERIFY(intArray.at(3) == 0); - - vector<TestObject> toArray(5); - EATEST_VERIFY(toArray[3] == TestObject(0)); - EATEST_VERIFY(toArray.at(3) == TestObject(0)); - -#if EASTL_EXCEPTIONS_ENABLED - vector<TestObject> vec01(5); - - try - { - TestObject& r01 = vec01.at(6); - EATEST_VERIFY(!(r01 == TestObject(0))); // Should not get here, as exception thrown. - } - catch (std::out_of_range&) { EATEST_VERIFY(true); } - catch (...) { EATEST_VERIFY(false); } -#endif - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { - using namespace eastl; - - // void push_back(const value_type& value); - // void push_back(); - // void pop_back(); - // void push_back(T&& value); - - vector<int> intArray(6); - for (i = 0; i < 6; i++) - intArray[i] = (int)i; - - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 6); - EATEST_VERIFY(intArray[5] == 5); - - for (i = 0; i < 40; i++) - { - int& ref = intArray.push_back(); - EATEST_VERIFY(&ref == &intArray.back()); - ref = 98; - } - - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 46); - EATEST_VERIFY(intArray[45] == 98); - - for (i = 0; i < 40; i++) - intArray.push_back(99); - - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 86); - EATEST_VERIFY(intArray[85] == 99); - - for (i = 0; i < 30; i++) - intArray.pop_back(); - - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 56); - EATEST_VERIFY(intArray[5] == 5); - } - - { - using namespace eastl; - - // void* push_back_uninitialized(); - - int64_t toCount0 = TestObject::sTOCount; - - vector<TestObject> vTO; - EATEST_VERIFY(TestObject::sTOCount == toCount0); - - for (i = 0; i < 25; i++) - { - void* pTO = vTO.push_back_uninitialized(); - EATEST_VERIFY(TestObject::sTOCount == (toCount0 + static_cast<int64_t>(i))); - - new (pTO) TestObject((int)i); - EATEST_VERIFY(TestObject::sTOCount == (toCount0 + static_cast<int64_t>(i) + 1)); - EATEST_VERIFY(vTO.back().mX == (int)i); - EATEST_VERIFY(vTO.validate()); - } - } - - { - using namespace eastl; - - // template<class... Args> - // iterator emplace(const_iterator position, Args&&... args); - - // template<class... Args> - // void emplace_back(Args&&... args); - - // iterator insert(const_iterator position, value_type&& value); - // void push_back(value_type&& value); - - TestObject::Reset(); - - vector<TestObject> toVectorA; - - TestObject& ref = toVectorA.emplace_back(2, 3, 4); - EATEST_VERIFY((toVectorA.size() == 1) && (toVectorA.back().mX == (2 + 3 + 4)) && - (TestObject::sTOCtorCount == 1)); - EATEST_VERIFY(ref.mX == (2 + 3 + 4)); - - toVectorA.emplace(toVectorA.begin(), 3, 4, 5); - EATEST_VERIFY((toVectorA.size() == 2) && (toVectorA.front().mX == (3 + 4 + 5)) && - (TestObject::sTOCtorCount == 3)); // 3 because the original count of 1, plus the existing vector - // element will be moved, plus the one being emplaced. - - TestObject::Reset(); - - // void push_back(T&& x); - // iterator insert(const_iterator position, T&& x); - - vector<TestObject> toVectorC; - - toVectorC.push_back(TestObject(2, 3, 4)); - EATEST_VERIFY((toVectorC.size() == 1) && (toVectorC.back().mX == (2 + 3 + 4)) && - (TestObject::sTOMoveCtorCount == 1)); - - toVectorC.insert(toVectorC.begin(), TestObject(3, 4, 5)); - EATEST_VERIFY((toVectorC.size() == 2) && (toVectorC.front().mX == (3 + 4 + 5)) && - (TestObject::sTOMoveCtorCount == 3)); // 3 because the original count of 1, plus the existing - // vector element will be moved, plus the one being - // emplaced. - } - - // We don't check for TestObject::IsClear because we messed with state above and don't currently have a matching set - // of ctors and dtors. - TestObject::Reset(); - - { - using namespace eastl; - - // iterator erase(iterator position); - // iterator erase(iterator first, iterator last); - // iterator erase_unsorted(iterator position); - // iterator erase_first(const T& pos); - // iterator erase_first_unsorted(const T& pos); - // iterator erase_last(const T& pos); - // iterator erase_last_unsorted(const T& pos); - // void clear(); - - vector<int> intArray(20); - for (i = 0; i < 20; i++) - intArray[i] = (int)i; - - // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 - - intArray.erase(intArray.begin() + - 10); // Becomes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19 - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 19); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[10] == 11); - EATEST_VERIFY(intArray[18] == 19); - - intArray.erase(intArray.begin() + 10, - intArray.begin() + 15); // Becomes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19 - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 14); - EATEST_VERIFY(intArray[9] == 9); - EATEST_VERIFY(intArray[13] == 19); - - intArray.erase(intArray.begin() + 1, intArray.begin() + 5); // Becomes: 0, 5, 6, 7, 8, 9, 16, 17, 18, 19 - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 10); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 5); - EATEST_VERIFY(intArray[9] == 19); - - intArray.erase(intArray.begin() + 7, intArray.begin() + 10); // Becomes: 0, 5, 6, 7, 8, 9, 16 - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 7); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 5); - EATEST_VERIFY(intArray[6] == 16); - - intArray.clear(); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.empty()); - EATEST_VERIFY(intArray.size() == 0); - - vector<TestObject> toArray(20); - for (i = 0; i < 20; i++) - toArray[i] = TestObject((int)i); - - toArray.erase(toArray.begin() + 10); - EATEST_VERIFY(toArray.validate()); - EATEST_VERIFY(toArray.size() == 19); - EATEST_VERIFY(toArray[10] == TestObject(11)); - - toArray.erase(toArray.begin() + 10, toArray.begin() + 15); - EATEST_VERIFY(toArray.validate()); - EATEST_VERIFY(toArray.size() == 14); - EATEST_VERIFY(toArray[10] == TestObject(16)); - - toArray.clear(); - EATEST_VERIFY(toArray.validate()); - EATEST_VERIFY(toArray.empty()); - EATEST_VERIFY(toArray.size() == 0); - - // iterator erase_unsorted(iterator position); - intArray.resize(20); - for (i = 0; i < 20; i++) - intArray[i] = (int)i; - - intArray.erase_unsorted(intArray.begin() + 0); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 19); - EATEST_VERIFY(intArray[0] == 19); - EATEST_VERIFY(intArray[1] == 1); - EATEST_VERIFY(intArray[18] == 18); - - intArray.erase_unsorted(intArray.begin() + 10); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 18); - EATEST_VERIFY(intArray[0] == 19); - EATEST_VERIFY(intArray[10] == 18); - EATEST_VERIFY(intArray[17] == 17); - - intArray.erase_unsorted(intArray.begin() + 17); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 17); - EATEST_VERIFY(intArray[0] == 19); - EATEST_VERIFY(intArray[10] == 18); - EATEST_VERIFY(intArray[16] == 16); - - // iterator erase_first(iterator position); - intArray.resize(20); - for (i = 0; i < 20; i++) - intArray[i] = (int)i % 3; // (i.e. 0,1,2,0,1,2...) - - intArray.erase_first(1); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 19); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 2); - EATEST_VERIFY(intArray[2] == 0); - EATEST_VERIFY(intArray[3] == 1); - EATEST_VERIFY(intArray[18] == 1); - - intArray.erase_first(1); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 18); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 2); - EATEST_VERIFY(intArray[2] == 0); - EATEST_VERIFY(intArray[3] == 2); - EATEST_VERIFY(intArray[17] == 1); - - intArray.erase_first(0); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 17); - EATEST_VERIFY(intArray[0] == 2); - EATEST_VERIFY(intArray[1] == 0); - EATEST_VERIFY(intArray[2] == 2); - EATEST_VERIFY(intArray[3] == 0); - EATEST_VERIFY(intArray[16] == 1); - - // iterator erase_first_unsorted(const T& val); - intArray.resize(20); - for (i = 0; i < 20; i++) - intArray[i] = (int) i/2; // every two values are the same (i.e. 0,0,1,1,2,2,3,3...) - - intArray.erase_first_unsorted(1); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 19); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 0); - EATEST_VERIFY(intArray[2] == 9); - EATEST_VERIFY(intArray[3] == 1); - EATEST_VERIFY(intArray[18] == 9); - - intArray.erase_first_unsorted(1); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 18); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 0); - EATEST_VERIFY(intArray[2] == 9); - EATEST_VERIFY(intArray[3] == 9); - EATEST_VERIFY(intArray[17] == 8); - - intArray.erase_first_unsorted(0); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 17); - EATEST_VERIFY(intArray[0] == 8); - EATEST_VERIFY(intArray[1] == 0); - EATEST_VERIFY(intArray[2] == 9); - EATEST_VERIFY(intArray[3] == 9); - EATEST_VERIFY(intArray[16] == 8); - - // iterator erase_last(const T& val); - intArray.resize(20); - for (i = 0; i < 20; i++) - intArray[i] = (int)i % 3; // (i.e. 0,1,2,0,1,2...) - - intArray.erase_last(1); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 19); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 1); - EATEST_VERIFY(intArray[2] == 2); - EATEST_VERIFY(intArray[3] == 0); - EATEST_VERIFY(intArray[15] == 0); - EATEST_VERIFY(intArray[16] == 1); - EATEST_VERIFY(intArray[17] == 2); - EATEST_VERIFY(intArray[18] == 0); - - intArray.erase_last(1); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 18); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 1); - EATEST_VERIFY(intArray[2] == 2); - EATEST_VERIFY(intArray[3] == 0); - EATEST_VERIFY(intArray[14] == 2); - EATEST_VERIFY(intArray[15] == 0); - EATEST_VERIFY(intArray[16] == 2); - EATEST_VERIFY(intArray[17] == 0); - - intArray.erase_last(0); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 17); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 1); - EATEST_VERIFY(intArray[2] == 2); - EATEST_VERIFY(intArray[3] == 0); - EATEST_VERIFY(intArray[13] == 1); - EATEST_VERIFY(intArray[14] == 2); - EATEST_VERIFY(intArray[15] == 0); - EATEST_VERIFY(intArray[16] == 2); - - // iterator erase_last_unsorted(const T& val); - intArray.resize(20); - for (i = 0; i < 20; i++) - intArray[i] = (int)i / 2; // every two values are the same (i.e. 0,0,1,1,2,2,3,3...) - - intArray.erase_last_unsorted(1); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 19); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 0); - EATEST_VERIFY(intArray[2] == 1); - EATEST_VERIFY(intArray[3] == 9); - EATEST_VERIFY(intArray[18] == 9); - - intArray.erase_last_unsorted(1); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 18); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 0); - EATEST_VERIFY(intArray[2] == 9); - EATEST_VERIFY(intArray[3] == 9); - EATEST_VERIFY(intArray[17] == 8); - - intArray.erase_last_unsorted(0); - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY(intArray.size() == 17); - EATEST_VERIFY(intArray[0] == 0); - EATEST_VERIFY(intArray[1] == 8); - EATEST_VERIFY(intArray[2] == 9); - EATEST_VERIFY(intArray[3] == 9); - EATEST_VERIFY(intArray[16] == 8); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { - using namespace eastl; - - // iterator erase(reverse_iterator position); - // iterator erase(reverse_iterator first, reverse_iterator last); - // iterator erase_unsorted(reverse_iterator position); - - vector<int> intVector; - - for (i = 0; i < 20; i++) - intVector.push_back((int)i); - EATEST_VERIFY((intVector.size() == 20) && (intVector[0] == 0) && (intVector[19] == 19)); - - vector<int>::reverse_iterator r2A = intVector.rbegin(); - vector<int>::reverse_iterator r2B = r2A + 3; - intVector.erase(r2A, r2B); - EATEST_VERIFY((intVector.size() == 17)); - EATEST_VERIFY((intVector[0] == 0)); - EATEST_VERIFY((intVector[16] == 16)); - - r2B = intVector.rend(); - r2A = r2B - 3; - intVector.erase(r2A, r2B); - EATEST_VERIFY((intVector.size() == 14)); - EATEST_VERIFY((intVector[0] == 3)); - EATEST_VERIFY((intVector[13] == 16)); - - r2B = intVector.rend() - 1; - intVector.erase(r2B); - EATEST_VERIFY((intVector.size() == 13)); - EATEST_VERIFY((intVector[0] == 4)); - EATEST_VERIFY((intVector[12] == 16)); - - r2B = intVector.rbegin(); - intVector.erase(r2B); - EATEST_VERIFY((intVector.size() == 12)); - EATEST_VERIFY((intVector[0] == 4)); - EATEST_VERIFY((intVector[11] == 15)); - - r2A = intVector.rbegin(); - r2B = intVector.rend(); - intVector.erase(r2A, r2B); - EATEST_VERIFY(intVector.size() == 0); - - // iterator erase_unsorted(iterator position); - intVector.resize(20); - for (i = 0; i < 20; i++) - intVector[i] = (int)i; - - intVector.erase_unsorted(intVector.rbegin() + 0); - EATEST_VERIFY(intVector.validate()); - EATEST_VERIFY(intVector.size() == 19); - EATEST_VERIFY(intVector[0] == 0); - EATEST_VERIFY(intVector[10] == 10); - EATEST_VERIFY(intVector[18] == 18); - - intVector.erase_unsorted(intVector.rbegin() + 10); - EATEST_VERIFY(intVector.validate()); - EATEST_VERIFY(intVector.size() == 18); - EATEST_VERIFY(intVector[0] == 0); - EATEST_VERIFY(intVector[8] == 18); - EATEST_VERIFY(intVector[17] == 17); - - intVector.erase_unsorted(intVector.rbegin() + 17); - EATEST_VERIFY(intVector.validate()); - EATEST_VERIFY(intVector.size() == 17); - EATEST_VERIFY(intVector[0] == 17); - EATEST_VERIFY(intVector[8] == 18); - EATEST_VERIFY(intVector[16] == 16); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { - const int valueToRemove = 44; - int testValues[] = {42, 43, 44, 45, 46, 47}; - - eastl::vector<eastl::unique_ptr<int>> v; - - for(auto& te : testValues) - v.push_back(eastl::make_unique<int>(te)); - - // remove 'valueToRemove' from the container - auto iterToRemove = eastl::find_if(v.begin(), v.end(), [&](eastl::unique_ptr<int>& e) - { return *e == valueToRemove; }); - v.erase_unsorted(iterToRemove); - EATEST_VERIFY(v.size() == 5); - - // verify 'valueToRemove' is no longer in the container - EATEST_VERIFY(eastl::find_if(v.begin(), v.end(), [&](eastl::unique_ptr<int>& e) - { return *e == valueToRemove; }) == v.end()); - - // verify all other expected values are in the container - for (auto& te : testValues) - { - if (te == valueToRemove) - continue; - - EATEST_VERIFY(eastl::find_if(v.begin(), v.end(), [&](eastl::unique_ptr<int>& e) - { return *e == te; }) != v.end()); - } - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { - using namespace eastl; - - // iterator insert(iterator position, const value_type& value); - // iterator insert(iterator position, size_type n, const value_type& value); - // iterator insert(iterator position, InputIterator first, InputIterator last); - // iterator insert(const_iterator position, std::initializer_list<T> ilist); - - vector<int> v(7, 13); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector", 13, 13, 13, 13, 13, 13, 13, -1)); - - // insert at end of size and capacity. - v.insert(v.end(), 99); - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 13, 13, 13, 13, 13, 13, 99, -1)); - - // insert at end of size. - v.reserve(30); - v.insert(v.end(), 999); - EATEST_VERIFY(v.validate()); - EATEST_VERIFY( - VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 13, 13, 13, 13, 13, 13, 99, 999, -1)); - - // Insert in middle. - vector<int>::iterator it = v.begin() + 7; - it = v.insert(it, 49); - EATEST_VERIFY(v.validate()); - EATEST_VERIFY( - VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 13, 13, 13, 13, 13, 13, 49, 99, 999, -1)); - - // Insert multiple copies - it = v.insert(v.begin() + 5, 3, 42); - EATEST_VERIFY(it == v.begin() + 5); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 13, 13, 13, 13, 42, 42, 42, 13, 13, - 49, 99, 999, -1)); - - // Insert multiple copies with count == 0 - vector<int>::iterator at = v.end(); - it = v.insert(at, 0, 666); - EATEST_VERIFY(it == at); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 13, 13, 13, 13, 42, 42, 42, 13, 13, - 49, 99, 999, -1)); - // Insert iterator range - const int data[] = {2, 3, 4, 5}; - it = v.insert(v.begin() + 1, data, data + 4); - EATEST_VERIFY(it == v.begin() + 1); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 2, 3, 4, 5, 13, 13, 13, 13, 42, 42, - 42, 13, 13, 49, 99, 999, -1)); - - // Insert empty iterator range - at = v.begin() + 1; - it = v.insert(at, data + 4, data + 4); - EATEST_VERIFY(it == at); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 2, 3, 4, 5, 13, 13, 13, 13, 42, 42, - 42, 13, 13, 49, 99, 999, -1)); - - // Insert with reallocation - it = v.insert(v.end() - 3, 6, 17); - EATEST_VERIFY(it == v.end() - (3 + 6)); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 2, 3, 4, 5, 13, 13, 13, 13, 42, 42, - 42, 13, 13, 17, 17, 17, 17, 17, 17, 49, 99, 999, -1)); - - // Single insert with reallocation - vector<int> v2; - v2.reserve(100); - v2.insert(v2.begin(), 100, 17); - EATEST_VERIFY(v2.size() == 100); - EATEST_VERIFY(v2[0] == 17); - v2.insert(v2.begin() + 50, 42); - EATEST_VERIFY(v2.size() == 101); - EATEST_VERIFY(v2[50] == 42); - - // Test insertion of values that come from within the vector. - v.insert(v.end() - 3, v.end() - 5, v.end()); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 2, 3, 4, 5, 13, 13, 13, 13, 42, 42, - 42, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 49, 99, 999, 49, 99, 999, -1)); - - v.insert(v.end() - 3, v.back()); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 2, 3, 4, 5, 13, 13, 13, 13, 42, 42, - 42, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 49, 99, 999, 999, 49, 99, 999, -1)); - - v.insert(v.end() - 3, 2, v[v.size() - 3]); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.insert", 13, 2, 3, 4, 5, 13, 13, 13, 13, 42, 42, - 42, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 49, 99, 999, 999, 49, 49, 49, 99, 999, - -1)); - -#if !defined(EASTL_STD_ITERATOR_CATEGORY_ENABLED) && !defined(EA_COMPILER_NO_STANDARD_CPP_LIBRARY) - // std::vector / eastl::vector - std::vector<TestObject> stdV(10); - eastl::vector<TestObject> eastlV(10); - - eastlV.insert(eastlV.end(), stdV.begin(), stdV.end()); - stdV.insert(stdV.end(), eastlV.begin(), eastlV.end()); - - EATEST_VERIFY(eastlV.size() == 20); - EATEST_VERIFY(stdV.size() == 30); - - // std::string / eastl::vector - std::string stdString("blah"); - eastl::vector<char8_t> eastlVString; - - eastlVString.assign(stdString.begin(), stdString.end()); -#endif - -// iterator insert(const_iterator position, std::initializer_list<T> ilist); -#if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) - // iterator insert(const_iterator position, std::initializer_list<T> ilist); - eastl::vector<float> floatVector; - - floatVector.insert(floatVector.end(), {0, 1, 2, 3}); - EATEST_VERIFY(floatVector.size() == 4); - EATEST_VERIFY((floatVector[0] == 0) && (floatVector[3] == 3)); -#endif - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { - // Test insert move objects - eastl::vector<TestObject> toVector1; - toVector1.reserve(20); - for(int idx = 0; idx < 2; ++idx) - toVector1.push_back(TestObject(idx)); - - eastl::vector<TestObject> toVector2; - for(int idx = 0; idx < 3; ++idx) - toVector2.push_back(TestObject(10 + idx)); - - // Insert more objects than the existing number using insert with iterator - TestObject::Reset(); - eastl::vector<TestObject>::iterator it; - it = toVector1.insert(toVector1.begin(), toVector2.begin(), toVector2.end()); - EATEST_VERIFY(it == toVector1.begin()); - EATEST_VERIFY(VerifySequence(toVector1.begin(), toVector1.end(), int(), "vector.insert", 10, 11, 12, 0, 1, -1)); - EATEST_VERIFY(TestObject::sTOMoveCtorCount + TestObject::sTOMoveAssignCount == 2 && - TestObject::sTOCopyCtorCount + TestObject::sTOCopyAssignCount == 3); // Move 2 existing elements and copy the 3 inserted - - eastl::vector<TestObject> toVector3; - toVector3.push_back(TestObject(20)); - - // Insert less objects than the existing number using insert with iterator - TestObject::Reset(); - it = toVector1.insert(toVector1.begin(), toVector3.begin(), toVector3.end()); - EATEST_VERIFY(VerifySequence(toVector1.begin(), toVector1.end(), int(), "vector.insert", 20, 10, 11, 12, 0, 1, -1)); - EATEST_VERIFY(it == toVector1.begin()); - EATEST_VERIFY(TestObject::sTOMoveCtorCount + TestObject::sTOMoveAssignCount == 5 && - TestObject::sTOCopyCtorCount + TestObject::sTOCopyAssignCount == 1); // Move 5 existing elements and copy the 1 inserted - - // Insert more objects than the existing number using insert without iterator - TestObject::Reset(); - it = toVector1.insert(toVector1.begin(), 1, TestObject(17)); - EATEST_VERIFY(it == toVector1.begin()); - EATEST_VERIFY(VerifySequence(toVector1.begin(), toVector1.end(), int(), "vector.insert", 17, 20, 10, 11, 12, 0, 1, -1)); - EATEST_VERIFY(TestObject::sTOMoveCtorCount + TestObject::sTOMoveAssignCount == 6 && - TestObject::sTOCopyCtorCount + TestObject::sTOCopyAssignCount == 2); // Move 6 existing element and copy the 1 inserted + - // the temporary one inside the function - - // Insert less objects than the existing number using insert without iterator - TestObject::Reset(); - it = toVector1.insert(toVector1.begin(), 10, TestObject(18)); - EATEST_VERIFY(it == toVector1.begin()); - EATEST_VERIFY(VerifySequence(toVector1.begin(), toVector1.end(), int(), "vector.insert", 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 20, 10, 11, 12, 0, 1, -1)); - EATEST_VERIFY(TestObject::sTOMoveCtorCount + TestObject::sTOMoveAssignCount == 7 && - TestObject::sTOCopyCtorCount + TestObject::sTOCopyAssignCount == 11); // Move 7 existing element and copy the 10 inserted + - // the temporary one inside the function - } - - TestObject::Reset(); - - { - using namespace eastl; - - // reserve / resize / capacity / clear - vector<int> v(10, 17); - v.reserve(20); - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(v.size() == 10); - EATEST_VERIFY(v.capacity() == 20); - - v.resize(7); // Shrink - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(v.capacity() == 20); - - v.resize(17); // Grow without reallocation - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(v.capacity() == 20); - - v.resize(42); // Grow with reallocation - vector<int>::size_type c = v.capacity(); - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(v[41] == 0); - EATEST_VERIFY(c >= 42); - - v.resize(44, 19); // Grow with reallocation - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(v[43] == 19); - - c = v.capacity(); - v.clear(); - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(v.empty()); - EATEST_VERIFY(v.capacity() == c); - - // How to shrink a vector's capacity to be equal to its size. - vector<int>(v).swap(v); - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(v.empty()); - EATEST_VERIFY(v.capacity() == v.size()); - - // How to completely clear a vector (size = 0, capacity = 0, no allocation). - vector<int>().swap(v); - EATEST_VERIFY(v.validate()); - EATEST_VERIFY(v.empty()); - EATEST_VERIFY(v.capacity() == 0); - } - - { // set_capacity / reset - using namespace eastl; - - const int intArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; - const size_t kIntArraySize = sizeof(intArray) / sizeof(int); - - vector<int> v(30); - EATEST_VERIFY(v.capacity() >= 30); - - v.assign(intArray, intArray + kIntArraySize); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.assign", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, -1)); - - // set_capacity - v.set_capacity(); - EATEST_VERIFY(v.capacity() == v.size()); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.set_capacity", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, -1)); - - v.set_capacity(0); - EATEST_VERIFY(v.size() == 0); - EATEST_VERIFY(v.data() == NULL); - EATEST_VERIFY(v.capacity() == v.size()); - - // Test set_capacity doing a realloc of non-scalar class types. - eastl::vector<TestObject> toArray; - toArray.resize(16); - toArray.set_capacity(64); - EATEST_VERIFY(v.validate()); - - // reset_lose_memory - int* const pData = v.data(); - vector<int>::size_type n = v.size(); - vector<int>::allocator_type& allocator = v.get_allocator(); - v.reset_lose_memory(); - allocator.deallocate(pData, n); - EATEST_VERIFY(v.capacity() == 0); - EATEST_VERIFY(VerifySequence(v.begin(), v.end(), int(), "vector.reset", -1)); - - // Test set_capacity make a move when reducing size - vector<TestObject> toArray2(10, TestObject(7)); - TestObject::Reset(); - toArray2.set_capacity(5); - EATEST_VERIFY(TestObject::sTOMoveCtorCount == 5 && - TestObject::sTOCopyCtorCount + TestObject::sTOCopyAssignCount == 0); // Move the 5 existing elements, no copy - EATEST_VERIFY(VerifySequence(toArray2.begin(), toArray2.end(), int(), "vector.set_capacity", 7, 7, 7, 7, 7, -1)); - } - - TestObject::Reset(); - - { - using namespace eastl; - - // Regression for user-reported possible bug. - { - MallocAllocator::reset_all(); - - eastl::vector<int, MallocAllocator> v; - v.reserve(32); // does allocation - - v.push_back(37); // may reallocate if we do enough of these to exceed 32 - v.erase(v.begin()); - - v.set_capacity(0); - - // Verify that all memory is freed by the set_capacity function. - EATEST_VERIFY((MallocAllocator::mAllocCountAll > 0) && - (MallocAllocator::mAllocCountAll == MallocAllocator::mFreeCountAll)); - - MallocAllocator::reset_all(); - } - - { - MallocAllocator::reset_all(); - - eastl::vector<int, MallocAllocator> v; - v.reserve(32); // does allocation - - for (int j = 0; j < 40; j++) - v.push_back(37); // may reallocate if we do enough of these to exceed 32 - for (int k = 0; k < 40; k++) - v.erase(v.begin()); - - v.set_capacity(0); - - // Verify that all memory is freed by the set_capacity function. - EATEST_VERIFY((MallocAllocator::mAllocCountAll > 0) && - (MallocAllocator::mAllocCountAll == MallocAllocator::mFreeCountAll)); - - MallocAllocator::reset_all(); - } - } - - { - using namespace eastl; - - // bool validate() const; - // bool validate_iterator(const_iterator i) const; - - vector<int> intArray(20); - - EATEST_VERIFY(intArray.validate()); - EATEST_VERIFY((intArray.validate_iterator(intArray.begin()) & (isf_valid | isf_can_dereference)) != 0); - EATEST_VERIFY(intArray.validate_iterator(NULL) == isf_none); - } - - { - using namespace eastl; - - // global operators (==, !=, <, etc.) - vector<int> intArray1(10); - vector<int> intArray2(10); - - for (i = 0; i < intArray1.size(); i++) - { - intArray1[i] = (int)i; // Make intArray1 equal to intArray2. - intArray2[i] = (int)i; - } - - EATEST_VERIFY((intArray1 == intArray2)); - EATEST_VERIFY(!(intArray1 != intArray2)); - EATEST_VERIFY((intArray1 <= intArray2)); - EATEST_VERIFY((intArray1 >= intArray2)); - EATEST_VERIFY(!(intArray1 < intArray2)); - EATEST_VERIFY(!(intArray1 > intArray2)); - - intArray1.push_back(100); // Make intArray1 less than intArray2. - intArray2.push_back(101); - - EATEST_VERIFY(!(intArray1 == intArray2)); - EATEST_VERIFY((intArray1 != intArray2)); - EATEST_VERIFY((intArray1 <= intArray2)); - EATEST_VERIFY(!(intArray1 >= intArray2)); - EATEST_VERIFY((intArray1 < intArray2)); - EATEST_VERIFY(!(intArray1 > intArray2)); - } - - // three way comparison operator -#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON) - { - using namespace eastl; - - vector<int> intArray1(10); - vector<int> intArray2(10); - - for (i = 0; i < intArray1.size(); i++) - { - intArray1[i] = (int)i; // Make intArray1 equal to intArray2. - intArray2[i] = (int)i; - } - - // Verify equality between intArray1 and intArray2 - EATEST_VERIFY((intArray1 <=> intArray2) == 0); - EATEST_VERIFY(!((intArray1 <=> intArray2) != 0)); - EATEST_VERIFY((intArray1 <=> intArray2) <= 0); - EATEST_VERIFY((intArray1 <=> intArray2) >= 0); - EATEST_VERIFY(!((intArray1 <=> intArray2) < 0)); - EATEST_VERIFY(!((intArray1 <=> intArray2) > 0)); - - intArray1.push_back(100); // Make intArray1 less than intArray2. - intArray2.push_back(101); - - // Verify intArray1 < intArray2 - EATEST_VERIFY(!((intArray1 <=> intArray2) == 0)); - EATEST_VERIFY((intArray1 <=> intArray2) != 0); - EATEST_VERIFY((intArray1 <=> intArray2) <= 0); - EATEST_VERIFY(!((intArray1 <=> intArray2) >= 0)); - EATEST_VERIFY(((intArray1 <=> intArray2) < 0)); - EATEST_VERIFY(!((intArray1 <=> intArray2) > 0)); - - for (i = 0; i < 3; i++) // Make the length of intArray2 less than intArray1 - intArray2.pop_back(); - - // Verify intArray2.size() < intArray1.size() and intArray2 is a subset of intArray1 - EATEST_VERIFY(!((intArray1 <=> intArray2) == 0)); - EATEST_VERIFY((intArray1 <=> intArray2) != 0); - EATEST_VERIFY((intArray1 <=> intArray2) >= 0); - EATEST_VERIFY(!((intArray1 <=> intArray2) <= 0)); - EATEST_VERIFY(((intArray1 <=> intArray2) > 0)); - EATEST_VERIFY(!((intArray1 <=> intArray2) < 0)); - } - - { - using namespace eastl; - - vector<int> intArray1 = {1, 2, 3, 4, 5, 6, 7}; - vector<int> intArray2 = {7, 6, 5, 4, 3, 2, 1}; - vector<int> intArray3 = {1, 2, 3, 4}; - - struct weak_ordering_vector - { - vector<int> vec; - inline std::weak_ordering operator<=>(const weak_ordering_vector& b) const { return vec <=> b.vec; } - }; - - EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray1}, weak_ordering_vector{intArray2}) == std::weak_ordering::less); - EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray3}, weak_ordering_vector{intArray1}) == std::weak_ordering::less); - EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray2}, weak_ordering_vector{intArray1}) == std::weak_ordering::greater); - EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray2}, weak_ordering_vector{intArray3}) == std::weak_ordering::greater); - EATEST_VERIFY(synth_three_way{}(weak_ordering_vector{intArray1}, weak_ordering_vector{intArray1}) == std::weak_ordering::equivalent); - - struct strong_ordering_vector - { - vector<int> vec; - inline std::strong_ordering operator<=>(const strong_ordering_vector& b) const { return vec <=> b.vec; } - }; - - EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray1}, strong_ordering_vector{intArray2}) == std::strong_ordering::less); - EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray3}, strong_ordering_vector{intArray1}) == std::strong_ordering::less); - EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray2}, strong_ordering_vector{intArray1}) == std::strong_ordering::greater); - EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray2}, strong_ordering_vector{intArray3}) == std::strong_ordering::greater); - EATEST_VERIFY(synth_three_way{}(strong_ordering_vector{intArray1}, strong_ordering_vector{intArray1}) == std::strong_ordering::equal); - } -#endif - - { - using namespace eastl; - - // Test vector<Align64> - - // Aligned objects should be CustomAllocator instead of the default, because the - // EASTL default might be unable to do aligned allocations, but CustomAllocator always can. - vector<Align64, CustomAllocator> vA64(10); - - vA64.resize(2); - EATEST_VERIFY(vA64.size() == 2); - - vA64.push_back(Align64()); - EATEST_VERIFY(vA64.size() == 3); - - vA64.resize(0); - EATEST_VERIFY(vA64.size() == 0); - - vA64.insert(vA64.begin(), Align64()); - EATEST_VERIFY(vA64.size() == 1); - - vA64.resize(20); - EATEST_VERIFY(vA64.size() == 20); - } - - { - // Misc additional tests - - eastl::vector<int> empty1; - EATEST_VERIFY(empty1.data() == NULL); - EATEST_VERIFY(empty1.size() == 0); - EATEST_VERIFY(empty1.capacity() == 0); - - eastl::vector<int> empty2 = empty1; - EATEST_VERIFY(empty2.data() == NULL); - EATEST_VERIFY(empty2.size() == 0); - EATEST_VERIFY(empty2.capacity() == 0); - } - - { // Test whose purpose is to see if calling vector::size() in a const loop results in the compiler optimizing the - // size() call to outside the loop. - eastl::vector<TestObject> toArray; - - toArray.resize(7); - - for (i = 0; i < toArray.size(); i++) - { - TestObject& to = toArray[i]; - - if (to.mX == 99999) - to.mX++; - } - } - - { // Test assign from iterator type. - TestObject to; - eastl::vector<TestObject> toTest; - - // InputIterator - demoted_iterator<TestObject*, EASTL_ITC_NS::forward_iterator_tag> toInput(&to); - toTest.assign(toInput, toInput); - - // ForwardIterator - eastl::slist<TestObject> toSList; - toTest.assign(toSList.begin(), toSList.end()); - - // BidirectionalIterator - eastl::list<TestObject> toList; - toTest.assign(toList.begin(), toList.end()); - - // RandomAccessIterator - eastl::deque<TestObject> toDeque; - toTest.assign(toDeque.begin(), toDeque.end()); - - // ContiguousIterator (note: as of this writing, vector doesn't actually use contiguous_iterator_tag) - eastl::vector<TestObject> toArray; - toTest.assign(toArray.begin(), toArray.end()); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { // Test user report that they think they saw code like this leak memory. - eastl::vector<int> intTest; - - intTest.push_back(1); - intTest = eastl::vector<int>(); - - eastl::vector<TestObject> toTest; - - toTest.push_back(TestObject(1)); - toTest = eastl::vector<TestObject>(); - } - - EATEST_VERIFY(TestObject::IsClear()); - TestObject::Reset(); - - { // Regression of user error report for the case of vector<const type>. - eastl::vector<int> ctorValues; - - for (int v = 0; v < 10; v++) - ctorValues.push_back(v); - - eastl::vector<const ConstType> testStruct(ctorValues.begin(), ctorValues.end()); - eastl::vector<const int> testInt(ctorValues.begin(), ctorValues.end()); - } - - { // Regression to verify that const vector works. - const eastl::vector<int> constIntVector1; - EATEST_VERIFY(constIntVector1.empty()); - - int intArray[3] = {37, 38, 39}; - const eastl::vector<int> constIntVector2(intArray, intArray + 3); - EATEST_VERIFY(constIntVector2.size() == 3); - - const eastl::vector<int> constIntVector3(4, 37); - EATEST_VERIFY(constIntVector3.size() == 4); - - const eastl::vector<int> constIntVector4; - const eastl::vector<int> constIntVector5 = constIntVector4; - } - - { // Regression to verify that a bug fix for a vector optimization works. - eastl::vector<int> intVector1; - intVector1.reserve(128); - intVector1.resize(128, 37); - intVector1.push_back(intVector1.front()); - EATEST_VERIFY(intVector1.back() == 37); - - eastl::vector<int> intVector2; - intVector2.reserve(1024); - intVector2.resize(1024, 37); - intVector2.resize(2048, intVector2.front()); - EATEST_VERIFY(intVector2.back() == 37); - } - - { // C++11 Range -// EABase 2.00.34+ has EA_COMPILER_NO_RANGE_BASED_FOR_LOOP, which we can check instead. -#if (defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1700)) || \ - (defined(__clang__) && (EA_COMPILER_VERSION >= 300) && (__cplusplus >= 201103L)) || \ - (defined(__GNUC__) && (EA_COMPILER_VERSION >= 4006) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ - (__cplusplus >= 201103L) - - eastl::vector<float> floatVector; - - floatVector.push_back(0.0); - floatVector.push_back(1.0); - - for (auto& f : floatVector) - f += 1.0; - - EATEST_VERIFY(floatVector.back() == 2.0); -#endif - } - - { -// C++11 cbegin, cend, crbegin, crend -#if !defined(EA_COMPILER_NO_AUTO) - // float vector - eastl::vector<float> floatVector; - - auto cb = floatVector.cbegin(); - auto ce = floatVector.cend(); - auto crb = floatVector.crbegin(); - auto cre = floatVector.crend(); - - EATEST_VERIFY(eastl::distance(cb, ce) == 0); - EATEST_VERIFY(eastl::distance(crb, cre) == 0); - - // const float vector - const eastl::vector<float> cFloatVector; - - auto ccb = cFloatVector.cbegin(); - auto cce = cFloatVector.cend(); - auto ccrb = cFloatVector.crbegin(); - auto ccre = cFloatVector.crend(); - - EATEST_VERIFY(eastl::distance(ccb, cce) == 0); - EATEST_VERIFY(eastl::distance(ccrb, ccre) == 0); - -#endif - } - - { - // Regression for failure in DoRealloc's use of uninitialize_move. - using namespace eastl; - - const eastl::string str0 = "TestString0"; - vector<eastl::string> v(1, str0); - vector<eastl::string> v_copy; - - // Test operator= - v_copy = v; - EATEST_VERIFY_MSG(v_copy.size() == 1, "vector string8 copy size"); - EATEST_VERIFY_MSG(eastl::find(v_copy.begin(), v_copy.end(), str0) != v_copy.end(), "vector copy string8"); - EATEST_VERIFY_MSG(v.size() == 1, "vector string8 copy size"); - EATEST_VERIFY_MSG(eastl::find(v.begin(), v.end(), str0) != v.end(), "vector copy string8"); - - // Test assign. - v.clear(); - v.push_back(str0); - v_copy.assign(v.begin(), v.end()); - EATEST_VERIFY_MSG(v_copy.size() == 1, "vector string8 copy size"); - EATEST_VERIFY_MSG(eastl::find(v_copy.begin(), v_copy.end(), str0) != v_copy.end(), "vector copy string8"); - EATEST_VERIFY_MSG(v.size() == 1, "vector string8 copy size"); - EATEST_VERIFY_MSG(eastl::find(v.begin(), v.end(), str0) != v.end(), "vector copy string8"); - } - - { - // Regression of vector::operator= for the case of EASTL_ALLOCATOR_COPY_ENABLED=1 - // For this test we need to use InstanceAllocator to create two containers of the same - // type but with different and unequal allocator instances. The bug was that when - // EASTL_ALLOCATOR_COPY_ENABLED was enabled operator=(this_type& x) assigned x.mAllocator - // to this and then proceeded to assign member elements from x to this. That's invalid - // because the existing elements of this were allocated by a different allocator and - // will be freed in the future with the allocator copied from x. - // The test below should work for the case of EASTL_ALLOCATOR_COPY_ENABLED == 0 or 1. - InstanceAllocator::reset_all(); - - InstanceAllocator ia0((uint8_t)0); - InstanceAllocator ia1((uint8_t)1); - - eastl::vector<int, InstanceAllocator> v0((eastl_size_t)1, (int)0, ia0); - eastl::vector<int, InstanceAllocator> v1((eastl_size_t)1, (int)1, ia1); - - EATEST_VERIFY((v0.front() == 0) && (v1.front() == 1)); -#if EASTL_ALLOCATOR_COPY_ENABLED - EATEST_VERIFY(v0.get_allocator() != v1.get_allocator()); -#endif - v0 = v1; - EATEST_VERIFY((v0.front() == 1) && (v1.front() == 1)); - EATEST_VERIFY(InstanceAllocator::mMismatchCount == 0); - EATEST_VERIFY(v0.validate()); - EATEST_VERIFY(v1.validate()); -#if EASTL_ALLOCATOR_COPY_ENABLED - EATEST_VERIFY(v0.get_allocator() == v1.get_allocator()); -#endif - } - - { - // Test shrink_to_fit - eastl::vector<int> v; - EATEST_VERIFY(v.capacity() == 0); - v.resize(100); - EATEST_VERIFY(v.capacity() == 100); - v.clear(); - EATEST_VERIFY(v.capacity() == 100); - v.shrink_to_fit(); - EATEST_VERIFY(v.capacity() == 0); - } - - { - // Regression for compilation errors found and fixed when integrating into Frostbite. - int j = 7; - - eastl::vector<StructWithConstInt> v1; - v1.push_back(StructWithConstInt(j)); - - eastl::vector<StructWithConstRefToInt> v2; - v2.push_back(StructWithConstRefToInt(j)); - } - - { - // Regression for issue with vector containing non-copyable values reported by user - eastl::vector<testmovable> moveablevec; - testmovable moveable; - moveablevec.insert(moveablevec.end(), eastl::move(moveable)); - } - - { - // Calling erase of empty range should not call a move assignment to self - eastl::vector<TestMoveAssignToSelf> v1; - v1.push_back(TestMoveAssignToSelf()); - EATEST_VERIFY(!v1[0].mMovedToSelf); - v1.erase(v1.begin(), v1.begin()); - EATEST_VERIFY(!v1[0].mMovedToSelf); - } - -#if defined(EASTL_TEST_CONCEPT_IMPLS) - { - // vector default constructor should require no more than Destructible - eastl::vector<Destructible> v1; - EATEST_VERIFY(v1.empty()); - - // some basic vector operations (data(), capacity(), size(), empty(), clear(), erase()) should impose no - // requirements beyond Destructible - EATEST_VERIFY(v1.empty()); - EATEST_VERIFY(v1.size() == 0); - EATEST_VERIFY(v1.capacity() == 0); - EATEST_VERIFY(eastl::distance(v1.data(), v1.data() + v1.size()) == 0); - v1.clear(); - } - - { - // vector default constructor should work with DefaultConstructible T - eastl::vector<DefaultConstructible> v1; - EATEST_VERIFY(v1.empty()); - } - - { - // vector constructor that takes an initial size should only require DefaultConstructible T - eastl::vector<DefaultConstructible> v2(2); - EATEST_VERIFY(v2.size() == 2 && v2[0].value == v2[1].value && - v2[0].value == DefaultConstructible::defaultValue); - } - - { - // vector constructor taking an initial size and a value should only require CopyConstructible - eastl::vector<CopyConstructible> v3(2, CopyConstructible::Create()); - EATEST_VERIFY(v3.size() == 2 && v3[0].value == v3[1].value && v3[0].value == CopyConstructible::defaultValue); - - // vector constructor taking a pair of iterators should work for CopyConstructible - eastl::vector<CopyConstructible> v4(cbegin(v3), cend(v3)); - EATEST_VERIFY(v4.size() == 2 && v4[0].value == v4[1].value && v4[0].value == CopyConstructible::defaultValue); - } - - { - // vector::reserve() should only require MoveInsertible - eastl::vector<MoveConstructible> v5; - v5.reserve(2); - v5.push_back(MoveConstructible::Create()); - v5.push_back(MoveConstructible::Create()); - EATEST_VERIFY(v5.size() == 2 && v5[0].value == v5[1].value && v5[0].value == MoveConstructible::defaultValue); - v5.pop_back(); - - // vector::shrink_to_fit() should only require MoveInsertible - v5.shrink_to_fit(); - EATEST_VERIFY(v5.size() == 1 && v5.capacity() == 1 && v5[0].value == MoveConstructible::defaultValue); - } - - { - // vector constructor taking a pair of iterators should only require MoveConstructible - MoveConstructible moveConstructibleArray[] = {MoveConstructible::Create()}; - eastl::vector<MoveConstructible> v7( - eastl::move_iterator<MoveConstructible*>(eastl::begin(moveConstructibleArray)), - eastl::move_iterator<MoveConstructible*>(eastl::end(moveConstructibleArray))); - EATEST_VERIFY(v7.size() == 1 && v7[0].value == MoveConstructible::defaultValue); - } - - { - // vector::swap() should only require Destructible. We also test with DefaultConstructible as it gives us a - // testable result. - - eastl::vector<Destructible> v4, v5; - eastl::swap(v4, v5); - EATEST_VERIFY(v4.empty() && v5.empty()); - - eastl::vector<DefaultConstructible> v6(1), v7(2); - eastl::swap(v6, v7); - EATEST_VERIFY(v6.size() == 2 && v7.size() == 1); - } - - { - // vector::resize() should only require MoveInsertable and DefaultInsertable - eastl::vector<MoveAndDefaultConstructible> v8; - v8.resize(2); - EATEST_VERIFY(v8.size() == 2 && v8[0].value == v8[1].value && v8[0].value == - MoveAndDefaultConstructible::defaultValue); - } - - { - eastl::vector<MoveAssignable> v1; - // vector::insert(pos, rv) should only require MoveAssignable - v1.insert(begin(v1), MoveAssignable::Create()); - EATEST_VERIFY(v1.size() == 1 && v1.front().value == MoveAssignable::defaultValue); - // vector::erase(pos) should only require MoveAssignable - v1.erase(begin(v1)); - EATEST_VERIFY(v1.empty()); - } -#endif // EASTL_TEST_CONCEPT_IMPLS - - { - // validates our vector implementation does not use 'operator<' on input iterators during vector construction. - // - struct container_value_type { int data; }; - struct container_with_custom_iterator - { - struct iterator - { - typedef EASTL_ITC_NS::input_iterator_tag iterator_category; - typedef int value_type; - typedef ptrdiff_t difference_type; - typedef int* pointer; - typedef int& reference; - - bool operator!=(const iterator&) const { return false; } - iterator& operator++() { return *this; } - iterator operator++(int) { return *this; } - container_value_type operator*() { return {}; } - }; - - container_with_custom_iterator() EA_NOEXCEPT {} - - iterator begin() const { return {}; } - iterator end() const { return {}; } - bool empty() const { return false; } - - private: - eastl::vector<container_value_type> m_vector; - }; - - static_assert(!is_less_comparable<container_with_custom_iterator::iterator>::value, "type cannot support comparison by '<' for this test"); - container_with_custom_iterator ci; - eastl::vector<container_value_type> v2(ci.begin(), ci.end()); - } - - // If the legacy code path is enabled we cannot handle non-copyable types - #ifndef EASTL_VECTOR_LEGACY_SWAP_BEHAVIOUR_REQUIRES_COPY_CTOR - // unique_ptr tests - { - // Simple move-assignment test to prevent regressions where eastl::vector utilizes operations on T that are not necessary. - { - eastl::vector<eastl::unique_ptr<int>> v1; - eastl::vector<eastl::unique_ptr<int>> v2; - v2 = eastl::move(v1); - } - - { - // This test verifies that eastl::vector can handle the move-assignment case where its utilizes two - // different allocator instances that do not compare equal. An example of an allocator that compares equal - // but isn't the same object instance is an allocator that shares the same memory allocation mechanism (eg. - // malloc). The memory allocated from one instance can be freed by another instance in the case where - // allocators compare equal. This test is verifying functionality in the opposite case where allocators - // instances do not compare equal and must clean up its own allocated memory. - InstanceAllocator::reset_all(); - { - InstanceAllocator a1(uint8_t(0)), a2(uint8_t(1)); - eastl::vector<eastl::unique_ptr<int>, InstanceAllocator> v1(a1); - eastl::vector<eastl::unique_ptr<int>, InstanceAllocator> v2(a2); - - VERIFY(v1.get_allocator() != v2.get_allocator()); - - // add some data in the vector so we can move it to the other vector. - v1.push_back(nullptr); - v1.push_back(nullptr); - v1.push_back(nullptr); - v1.push_back(nullptr); - - VERIFY(!v1.empty() && v2.empty()); - v2 = eastl::move(v1); - VERIFY(v1.empty() && !v2.empty()); - v1.swap(v2); - VERIFY(!v1.empty() && v2.empty()); - } - VERIFY(InstanceAllocator::mMismatchCount == 0); - } - } - #endif - - { - // CustomAllocator has no data members which reduces the size of an eastl::vector via the empty base class optimization. - typedef eastl::vector<int, CustomAllocator> EboVector; - static_assert(sizeof(EboVector) == 3 * sizeof(void*), ""); - } - - // eastl::erase / eastl::erase_if tests - { - { - eastl::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - - auto numErased = eastl::erase(v, 5); - VERIFY((v == eastl::vector<int> {1, 2, 3, 4, 6, 7, 8, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase(v, 2); - VERIFY((v == eastl::vector<int> {1, 3, 4, 6, 7, 8, 9})); - VERIFY(numErased == 1); - - numErased = eastl::erase(v, 9); - VERIFY((v == eastl::vector<int> {1, 3, 4, 6, 7, 8})); - VERIFY(numErased == 1); - } - - { - eastl::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - auto numErased = eastl::erase_if(v, [](auto i) { return i % 2 == 0; }); - VERIFY((v == eastl::vector<int>{1, 3, 5, 7, 9})); - VERIFY(numErased == 4); - } - } - - return nErrorCount; -} diff --git a/test/source/TestVectorMap.cpp b/test/source/TestVectorMap.cpp deleted file mode 100644 index ca400ed..0000000 --- a/test/source/TestVectorMap.cpp +++ /dev/null @@ -1,235 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - -#include "TestMap.h" -#include "EASTLTest.h" -#include <EASTL/vector_map.h> -#include <EASTL/vector_multimap.h> -#include <EASTL/vector.h> -#include <EASTL/deque.h> -#include <EASTL/string.h> -#include <EASTL/fixed_string.h> -#include <EASTL/fixed_vector.h> -#include <EASTL/utility.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <map> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::vector_map<int, int>; -template class eastl::vector_multimap<float, int>; -template class eastl::vector_map<TestObject, TestObject>; -template class eastl::vector_multimap<TestObject, TestObject>; - - -/////////////////////////////////////////////////////////////////////////////// -// typedefs -// -typedef eastl::vector_map<int, int> VM1; -typedef eastl::vector_map<int, int, eastl::less<int>, EASTLAllocatorType, eastl::deque<eastl::pair<int, int> > > VM2; - -typedef eastl::vector_map<TestObject, TestObject> VM4; -typedef eastl::vector_map<TestObject, TestObject, eastl::less<TestObject>, EASTLAllocatorType, eastl::deque<eastl::pair<TestObject, TestObject> > > VM5; - -typedef eastl::vector_multimap<int, int> VMM1; -typedef eastl::vector_multimap<int, int, eastl::less<int>, EASTLAllocatorType, eastl::deque<eastl::pair<int, int> > > VMM2; - -typedef eastl::vector_multimap<TestObject, TestObject> VMM4; -typedef eastl::vector_multimap<TestObject, TestObject, eastl::less<TestObject>, EASTLAllocatorType, eastl::deque<eastl::pair<TestObject, TestObject> > > VMM5; - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - typedef std::map<int, int> VM3; - typedef std::map<TestObject, TestObject> VM6; - typedef std::multimap<int, int> VMM3; - typedef std::multimap<TestObject, TestObject> VMM6; -#endif -/////////////////////////////////////////////////////////////////////////////// - - - -int TestVectorMap() -{ - int nErrorCount = 0; - - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - { // Test construction - nErrorCount += TestMapConstruction<VM1, VM3, false>(); - nErrorCount += TestMapConstruction<VM2, VM3, false>(); - nErrorCount += TestMapConstruction<VM4, VM6, false>(); - nErrorCount += TestMapConstruction<VM5, VM6, false>(); - - nErrorCount += TestMapConstruction<VMM1, VMM3, true>(); - nErrorCount += TestMapConstruction<VMM2, VMM3, true>(); - nErrorCount += TestMapConstruction<VMM4, VMM6, true>(); - nErrorCount += TestMapConstruction<VMM5, VMM6, true>(); - } - - - { // Test mutating functionality. - nErrorCount += TestMapMutation<VM1, VM3, false>(); - nErrorCount += TestMapMutation<VM2, VM3, false>(); - nErrorCount += TestMapMutation<VM4, VM6, false>(); - nErrorCount += TestMapMutation<VM5, VM6, false>(); - - nErrorCount += TestMapMutation<VMM1, VMM3, true>(); - nErrorCount += TestMapMutation<VMM2, VMM3, true>(); - nErrorCount += TestMapMutation<VMM4, VMM6, true>(); - nErrorCount += TestMapMutation<VMM5, VMM6, true>(); - } - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - - { // Test search functionality. - nErrorCount += TestMapSearch<VM1, false>(); - nErrorCount += TestMapSearch<VM2, false>(); - nErrorCount += TestMapSearch<VM4, false>(); - nErrorCount += TestMapSearch<VM5, false>(); - - nErrorCount += TestMapSearch<VMM1, true>(); - nErrorCount += TestMapSearch<VMM2, true>(); - nErrorCount += TestMapSearch<VMM4, true>(); - nErrorCount += TestMapSearch<VMM5, true>(); - } - - - { - // C++11 emplace and related functionality - nErrorCount += TestMapCpp11<eastl::vector_map<int, TestObject> >(); - nErrorCount += TestMapCpp11<eastl::vector_map<int, TestObject, eastl::less<int>, EASTLAllocatorType, eastl::deque<eastl::pair<int, TestObject> > > >(); - - nErrorCount += TestMultimapCpp11<eastl::vector_multimap<int, TestObject> >(); - nErrorCount += TestMultimapCpp11<eastl::vector_multimap<int, TestObject, eastl::less<int>, EASTLAllocatorType, eastl::deque<eastl::pair<int, TestObject> > > >(); - } - - - { - // insert at the upper bound of a range - VMM1 vmm = {{0, 0}}; - VERIFY(vmm.emplace(0, 0) != vmm.begin()); - } - - - { // Misc tests - - // const key_compare& key_comp() const; - // key_compare& key_comp(); - VM2 vm; - const VM2 vmc; - - const VM2::key_compare& kc = vmc.key_comp(); - vm.key_comp() = kc; - - // ensure count can be called from a const object - vmc.count(0); - } - - { - const VMM1 vmm; - - // ensure count can be called from a const object - vmm.count(0); - } - - { - // Misc testing - typedef eastl::fixed_vector<eastl::pair<int, float>, 8> FV; - typedef eastl::vector_map<int, float, eastl::less<int>, FV::allocator_type, FV> FixedVectorMap; - - FixedVectorMap fvm; - - for(int i = FV::kMaxSize - 1; i >= 0; i--) - fvm.insert(eastl::pair<int, float>(i, (float)i)); - - FixedVectorMap::iterator it = fvm.find(3); - EATEST_VERIFY(it != fvm.end()); - } - - { - // Misc testing - typedef eastl::fixed_string<char, 16> KeyStringType; - typedef eastl::fixed_string<char, 24> ValueStringType; - typedef eastl::pair<ValueStringType, bool> StringMapValueType; - - typedef eastl::vector_map<KeyStringType, StringMapValueType> StringMapType; - StringMapType stringMap; - - stringMap.reserve(20); - EATEST_VERIFY(stringMap.capacity() == 20); - - StringMapValueType& v1 = stringMap["abc"]; - EATEST_VERIFY(strlen(v1.first.c_str()) == 0); - v1.first.clear(); - EATEST_VERIFY(strlen(v1.first.c_str()) == 0); - - StringMapValueType& v2 = stringMap["def"]; - EATEST_VERIFY(strlen(v2.first.c_str()) == 0); - v2.first = "def"; - EATEST_VERIFY(strlen(v2.first.c_str()) == 3); - } - - { - // Regression for problem observed in EAWebKit - typedef eastl::vector_map<eastl::string, void*> TestVectorMap; - - TestVectorMap tvm; - - tvm["Parameters"] = NULL; - tvm["ThemeParameters"] = NULL; - tvm["CookieInfo"] = NULL; - tvm["DiskCacheInfo"] = NULL; - tvm["RamCacheInfo"] = NULL; - tvm["SSLCert"] = NULL; - tvm["AllowedDomain"] = NULL; - } - - { // find_as predicate - { // vector_map - eastl::vector_map<string, int> vss = {{"abc", 11}, {"def", 22}, {"ghi", 33}, {"jklmnop", 44}, - {"qrstu", 55}, {"vw", 66}, {"x", 77}, {"yz", 88}}; - VERIFY(vss.find_as("GHI", TestStrCmpI_2()) != vss.end()); - } - - { // const vector_map - const eastl::vector_map<string, int> vss = {{"abc", 11}, {"def", 22}, {"ghi", 33}, {"jklmnop", 44}, - {"qrstu", 55}, {"vw", 66}, {"x", 77}, {"yz", 88}}; - VERIFY(vss.find_as("GHI", TestStrCmpI_2()) != vss.end()); - } - - // vector_multimap - { - eastl::vector_multimap<string, int> vss = {{"abc", 11}, {"def", 22}, {"ghi", 33}, {"jklmnop", 44}, - {"qrstu", 55}, {"vw", 66}, {"x", 77}, {"yz", 88}}; - VERIFY(vss.find_as("GHI", TestStrCmpI_2()) != vss.end()); - } - - // const vector_multimap - { - const eastl::vector_multimap<string, int> vss = {{"abc", 11}, {"def", 22}, {"ghi", 33}, {"jklmnop", 44}, - {"qrstu", 55}, {"vw", 66}, {"x", 77}, {"yz", 88}}; - VERIFY(vss.find_as("GHI", TestStrCmpI_2()) != vss.end()); - } - } - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/TestVectorSet.cpp b/test/source/TestVectorSet.cpp deleted file mode 100644 index 067630f..0000000 --- a/test/source/TestVectorSet.cpp +++ /dev/null @@ -1,170 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - - - -#include "TestSet.h" -#include "EASTLTest.h" -#include <EASTL/vector_set.h> -#include <EASTL/vector_multiset.h> -#include <EASTL/vector.h> -#include <EASTL/deque.h> -#include <EABase/eabase.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - #include <set> -#endif -EA_RESTORE_ALL_VC_WARNINGS() - -using namespace eastl; - - -// Template instantations. -// These tell the compiler to compile all the functions for the given class. -template class eastl::vector_set<int>; -template class eastl::vector_multiset<float>; -template class eastl::vector_set<TestObject>; -template class eastl::vector_multiset<TestObject>; - - -/////////////////////////////////////////////////////////////////////////////// -// typedefs -// -typedef eastl::vector_set<int> VS1; -typedef eastl::vector_set<int, eastl::less<int>, EASTLAllocatorType, eastl::deque<int> > VS2; -typedef eastl::vector_set<TestObject> VS4; -typedef eastl::vector_set<TestObject, eastl::less<TestObject>, EASTLAllocatorType, eastl::deque<TestObject> > VS5; -typedef eastl::vector_multiset<int> VMS1; -typedef eastl::vector_multiset<int, eastl::less<int>, EASTLAllocatorType, eastl::deque<int> > VMS2; -typedef eastl::vector_multiset<TestObject> VMS4; -typedef eastl::vector_multiset<TestObject, eastl::less<TestObject>, EASTLAllocatorType, eastl::deque<TestObject> > VMS5; - -#ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - typedef std::set<int> VS3; - typedef std::set<TestObject> VS6; - typedef std::multiset<int> VMS3; - typedef std::multiset<TestObject> VMS6; -#endif -/////////////////////////////////////////////////////////////////////////////// - - -int TestVectorSet() -{ - int nErrorCount = 0; - - #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY - { // Test construction - nErrorCount += TestSetConstruction<VS1, VS3, false>(); - nErrorCount += TestSetConstruction<VS2, VS3, false>(); - nErrorCount += TestSetConstruction<VS4, VS6, false>(); - nErrorCount += TestSetConstruction<VS5, VS6, false>(); - - nErrorCount += TestSetConstruction<VMS1, VMS3, true>(); - nErrorCount += TestSetConstruction<VMS2, VMS3, true>(); - nErrorCount += TestSetConstruction<VMS4, VMS6, true>(); - nErrorCount += TestSetConstruction<VMS5, VMS6, true>(); - } - - - { // Test mutating functionality. - nErrorCount += TestSetMutation<VS1, VS3, false>(); - nErrorCount += TestSetMutation<VS2, VS3, false>(); - nErrorCount += TestSetMutation<VS4, VS6, false>(); - nErrorCount += TestSetMutation<VS5, VS6, false>(); - - nErrorCount += TestSetMutation<VMS1, VMS3, true>(); - nErrorCount += TestSetMutation<VMS2, VMS3, true>(); - nErrorCount += TestSetMutation<VMS4, VMS6, true>(); - nErrorCount += TestSetMutation<VMS5, VMS6, true>(); - } - #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - - - { // Test search functionality. - nErrorCount += TestSetSearch<VS1, false>(); - nErrorCount += TestSetSearch<VS2, false>(); - nErrorCount += TestSetSearch<VS4, false>(); - nErrorCount += TestSetSearch<VS5, false>(); - - nErrorCount += TestSetSearch<VMS1, true>(); - nErrorCount += TestSetSearch<VMS2, true>(); - nErrorCount += TestSetSearch<VMS4, true>(); - nErrorCount += TestSetSearch<VMS5, true>(); - } - - - { - // C++11 emplace and related functionality - nErrorCount += TestSetCpp11<VS4>(); - nErrorCount += TestSetCpp11<VS5>(); - - nErrorCount += TestMultisetCpp11<VMS4>(); - nErrorCount += TestMultisetCpp11<VMS5>(); - } - - - { - // insert at the upper bound of a range - VMS1 vms = {0}; - VERIFY(vms.insert(0) != vms.begin()); - } - - - { // Misc tests - { - // const key_compare& key_comp() const; - // key_compare& key_comp(); - VS2 vs; - const VS2 vsc; - - // ensure count can be called from a const object - const VS2::key_compare& kc = vsc.key_comp(); - vs.key_comp() = kc; - vsc.count(0); - } - - { - // ensure count can be called from a const object - const VMS1 vms; - vms.count(0); - } - } - - { // find_as predicate - { // vector_set - eastl::vector_set<string> vss = {"abc", "def", "ghi", "jklmnop", "qrstu", "vw", "x", "yz"}; - VERIFY(vss.find_as("GHI", TestStrCmpI_2()) != vss.end()); - } - - { // const vector_set - const eastl::vector_set<string> vss = {"abc", "def", "ghi", "jklmnop", "qrstu", "vw", "x", "yz"}; - VERIFY(vss.find_as("GHI", TestStrCmpI_2()) != vss.end()); - } - - { // vector_multiset - eastl::vector_multiset<string> vss = {"abc", "def", "ghi", "jklmnop", "qrstu", "vw", "x", "yz"}; - VERIFY(vss.find_as("GHI", TestStrCmpI_2()) != vss.end()); - } - - { // const vector_multiset - const eastl::vector_multiset<string> vss = {"abc", "def", "ghi", "jklmnop", "qrstu", "vw", "x", "yz"}; - VERIFY(vss.find_as("GHI", TestStrCmpI_2()) != vss.end()); - } - } - - return nErrorCount; -} - - - - - - - - - - - - diff --git a/test/source/main.cpp b/test/source/main.cpp deleted file mode 100644 index 132bab1..0000000 --- a/test/source/main.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -/////////////////////////////////////////////////////////////////////////////// - - -#include "EASTLTest.h" -#include <EAStdC/EASprintf.h> -#include <EASTL/internal/config.h> - -EA_DISABLE_ALL_VC_WARNINGS() -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -EA_RESTORE_ALL_VC_WARNINGS() - - -#include "EAMain/EAEntryPointMain.inl" -#include "EASTLTestAllocator.h" - -/////////////////////////////////////////////////////////////////////////////// -// Required by EASTL. -// -#if !EASTL_EASTDC_VSNPRINTF - int Vsnprintf8(char* pDestination, size_t n, const char* pFormat, va_list arguments) - { - return EA::StdC::Vsnprintf(pDestination, n, pFormat, arguments); - } - - int Vsnprintf16(char16_t* pDestination, size_t n, const char16_t* pFormat, va_list arguments) - { - return EA::StdC::Vsnprintf(pDestination, n, pFormat, arguments); - } - - int Vsnprintf32(char32_t* pDestination, size_t n, const char32_t* pFormat, va_list arguments) - { - return EA::StdC::Vsnprintf(pDestination, n, pFormat, arguments); - } - - #if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE - int Vsnprintf8(char8_t* pDestination, size_t n, const char8_t* pFormat, va_list arguments) - { - return EA::StdC::Vsnprintf(pDestination, n, pFormat, arguments); - } - #endif - - #if defined(EA_WCHAR_UNIQUE) && EA_WCHAR_UNIQUE - int VsnprintfW(wchar_t* pDestination, size_t n, const wchar_t* pFormat, va_list arguments) - { - return EA::StdC::Vsnprintf(pDestination, n, pFormat, arguments); - } - #endif -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// EAMain -// -int EAMain(int argc, char* argv[]) -{ - using namespace EA::UnitTest; - - int nErrorCount = 0; - - EA::EAMain::PlatformStartup(); - - EASTLTest_SetGeneralAllocator(); - - nErrorCount += EASTLTest_CheckMemory(); - - // Parse command line arguments - for(int i = 1; i < argc; i++) - { - // Example usage: -l:7 - if(strstr(argv[i], "-l:") == argv[i]) - { - gEASTL_TestLevel = atoi(argv[i] + 3); - - if(gEASTL_TestLevel < kEASTL_TestLevelLow) - gEASTL_TestLevel = kEASTL_TestLevelLow; - if(gEASTL_TestLevel > kEASTL_TestLevelHigh) - gEASTL_TestLevel = kEASTL_TestLevelHigh; - } - } - - TestApplication testSuite("EASTL Unit Tests", argc, argv); - - testSuite.AddTest("Algorithm", TestAlgorithm); - testSuite.AddTest("Allocator", TestAllocator); - testSuite.AddTest("Any", TestAny); - testSuite.AddTest("Array", TestArray); - testSuite.AddTest("BitVector", TestBitVector); - testSuite.AddTest("Bitset", TestBitset); - testSuite.AddTest("CharTraits", TestCharTraits); - testSuite.AddTest("Chrono", TestChrono); - testSuite.AddTest("Deque", TestDeque); - testSuite.AddTest("Extra", TestExtra); - testSuite.AddTest("Finally", TestFinally); - testSuite.AddTest("FixedFunction", TestFixedFunction); - testSuite.AddTest("FixedHash", TestFixedHash); - testSuite.AddTest("FixedList", TestFixedList); - testSuite.AddTest("FixedMap", TestFixedMap); - testSuite.AddTest("FixedSList", TestFixedSList); - testSuite.AddTest("FixedSet", TestFixedSet); - testSuite.AddTest("FixedString", TestFixedString); - testSuite.AddTest("FixedTupleVector", TestFixedTupleVector); - testSuite.AddTest("FixedVector", TestFixedVector); - testSuite.AddTest("Functional", TestFunctional); - testSuite.AddTest("Hash", TestHash); - testSuite.AddTest("Heap", TestHeap); - testSuite.AddTest("IntrusiveHash", TestIntrusiveHash); - testSuite.AddTest("IntrusiveList", TestIntrusiveList); - testSuite.AddTest("IntrusiveSDList", TestIntrusiveSDList); - testSuite.AddTest("IntrusiveSList", TestIntrusiveSList); - testSuite.AddTest("Iterator", TestIterator); - testSuite.AddTest("LRUCache", TestLruCache); - testSuite.AddTest("List", TestList); - testSuite.AddTest("ListMap", TestListMap); - testSuite.AddTest("Map", TestMap); - testSuite.AddTest("Memory", TestMemory); - testSuite.AddTest("Meta", TestMeta); - testSuite.AddTest("NumericLimits", TestNumericLimits); - testSuite.AddTest("Optional", TestOptional); - testSuite.AddTest("Random", TestRandom); - testSuite.AddTest("Ratio", TestRatio); - testSuite.AddTest("RingBuffer", TestRingBuffer); - testSuite.AddTest("SList", TestSList); - testSuite.AddTest("SegmentedVector", TestSegmentedVector); - testSuite.AddTest("Set", TestSet); - testSuite.AddTest("SmartPtr", TestSmartPtr); - testSuite.AddTest("Sort", TestSort); - testSuite.AddTest("Span", TestSpan); - testSuite.AddTest("String", TestString); - testSuite.AddTest("StringHashMap", TestStringHashMap); - testSuite.AddTest("StringMap", TestStringMap); - testSuite.AddTest("StringView", TestStringView); - testSuite.AddTest("TestCppCXTypeTraits", TestCppCXTypeTraits); - testSuite.AddTest("Tuple", TestTuple); - testSuite.AddTest("TupleVector", TestTupleVector); - testSuite.AddTest("TypeTraits", TestTypeTraits); - testSuite.AddTest("Utility", TestUtility); - testSuite.AddTest("Variant", TestVariant); - testSuite.AddTest("Vector", TestVector); - testSuite.AddTest("VectorMap", TestVectorMap); - testSuite.AddTest("VectorSet", TestVectorSet); - testSuite.AddTest("AtomicBasic", TestAtomicBasic); - testSuite.AddTest("AtomicAsm", TestAtomicAsm); - testSuite.AddTest("Bitcast", TestBitcast); - - - nErrorCount += testSuite.Run(); - - nErrorCount += EASTLTest_CheckMemory(); - - EA::EAMain::PlatformShutdown(nErrorCount); - - return nErrorCount; -} - - - - - - - - |