///////////////////////////////////////////////////////////////////////////// // Copyright (c) Electronic Arts Inc. All rights reserved. ///////////////////////////////////////////////////////////////////////////// #include "TestSet.h" #include "EASTLTest.h" #include #include #include #include #include EA_DISABLE_ALL_VC_WARNINGS() #include #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY #include #include #include #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; template class eastl::multiset; template class eastl::set; template class eastl::multiset; /////////////////////////////////////////////////////////////////////////////// // typedefs // typedef eastl::set VS1; typedef eastl::set VS4; typedef eastl::multiset VMS1; typedef eastl::multiset VMS4; #ifndef EA_COMPILER_NO_STANDARD_CPP_LIBRARY typedef std::set VS3; typedef std::set VS6; typedef std::multiset VMS3; typedef std::multiset 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(); nErrorCount += TestSetConstruction(); nErrorCount += TestSetConstruction(); nErrorCount += TestSetConstruction(); } { // Test mutating functionality. nErrorCount += TestSetMutation(); nErrorCount += TestSetMutation(); nErrorCount += TestSetMutation(); nErrorCount += TestSetMutation(); } #endif // EA_COMPILER_NO_STANDARD_CPP_LIBRARY { // Test searching functionality. nErrorCount += TestSetSearch(); nErrorCount += TestSetSearch(); nErrorCount += TestSetSearch(); nErrorCount += TestSetSearch(); } { // C++11 emplace and related functionality nErrorCount += TestSetCpp11 >(); nErrorCount += TestMultisetCpp11 >(); } { // 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 a = {0, 1, 2, 3, 4}; auto i = a.find(42); VERIFY(i == a.end()); } } { // set erase_if tests set s = {0, 1, 2, 3, 4}; eastl::erase_if(s, [](auto i) { return i % 2 == 0;}); VERIFY((s == set{1,3})); } { // multiset erase_if tests multiset s = {0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4}; eastl::erase_if(s, [](auto i) { return i % 2 == 0;}); VERIFY((s == multiset{1, 1, 1, 3, 3, 3})); } { // user reported regression: ensure container elements are NOT // moved from during the eastl::set construction process. eastl::vector m1 = {{0}, {1}, {2}, {3}, {4}, {5}}; eastl::set 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 m1 = {{0}, {1}, {2}, {3}, {4}, {5}}; eastl::set 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; }