diff options
Diffstat (limited to 'EASTL/test/source/TestIntrusiveSDList.cpp')
-rw-r--r-- | EASTL/test/source/TestIntrusiveSDList.cpp | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/EASTL/test/source/TestIntrusiveSDList.cpp b/EASTL/test/source/TestIntrusiveSDList.cpp new file mode 100644 index 0000000..13a4802 --- /dev/null +++ b/EASTL/test/source/TestIntrusiveSDList.cpp @@ -0,0 +1,315 @@ +///////////////////////////////////////////////////////////////////////////// +// 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; +} + + + + + + + + + |