//Has to be first for StackAllocator swap overload to be taken //into account (at least using GCC 4.0.1) #include "stack_allocator.h" #include <algorithm> #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) # include <slist> # if !defined (_STLP_USE_NO_IOSTREAMS) # include <sstream> # endif # include <iterator> # include <functional> #endif #include "cppunit/cppunit_proxy.h" #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) using namespace std; #endif #if !defined (STLPORT) && defined(__GNUC__) using namespace __gnu_cxx; #endif // // TestCase class // class SlistTest : public CPPUNIT_NS::TestCase { CPPUNIT_TEST_SUITE(SlistTest); #if !defined (STLPORT) || defined (_STLP_NO_EXTENSIONS) || defined (_STLP_USE_NO_IOSTREAMS) CPPUNIT_IGNORE; #endif CPPUNIT_TEST(slist1); #if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS) CPPUNIT_STOP_IGNORE; #endif CPPUNIT_TEST(erase); CPPUNIT_TEST(insert); CPPUNIT_TEST(splice); CPPUNIT_TEST(allocator_with_state); CPPUNIT_TEST_SUITE_END(); protected: void slist1(); void erase(); void insert(); void splice(); void allocator_with_state(); }; CPPUNIT_TEST_SUITE_REGISTRATION(SlistTest); // // tests implementation // void SlistTest::slist1() { #if defined (STLPORT) && !defined (_STLP_USE_NO_IOSTREAMS) && !defined (_STLP_NO_EXTENSIONS) /* original: xlxtss reversed: sstxlx removed: sstl uniqued: stl sorted: lst */ char array [] = { 'x', 'l', 'x', 't', 's', 's' }; ostringstream os; ostream_iterator<char> o(os,""); slist<char> str(array+0, array + 6); slist<char>::iterator i; //Check const_iterator construction from iterator slist<char>::const_iterator ci(i); slist<char>::const_iterator ci2(ci); // cout << "reversed: "; str.reverse(); for(i = str.begin(); i != str.end(); i++) os << *i; stringbuf* buff=os.rdbuf(); string result=buff->str(); CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstxlx")); //cout << "removed: "; str.remove('x'); ostringstream os2; for(i = str.begin(); i != str.end(); i++) os2 << *i; buff=os2.rdbuf(); result=buff->str(); CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstl")); //cout << "uniqued: "; str.unique(); ostringstream os3; for(i = str.begin(); i != str.end(); i++) os3 << *i; buff=os3.rdbuf(); result=buff->str(); CPPUNIT_ASSERT(!strcmp(result.c_str(),"stl")); //cout << "sorted: "; str.sort(); ostringstream os4; for(i = str.begin(); i != str.end(); i++) os4 << *i; buff = os4.rdbuf(); result = buff->str(); CPPUNIT_ASSERT(!strcmp(result.c_str(),"lst")); //A small compilation time check to be activated from time to time: # if 0 { slist<char>::iterator sl_char_ite; slist<int>::iterator sl_int_ite; CPPUNIT_ASSERT( sl_char_ite != sl_int_ite ); } # endif #endif } void SlistTest::erase() { #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) int array[] = { 0, 1, 2, 3, 4 }; slist<int> sl(array, array + 5); slist<int>::iterator slit; slit = sl.erase(sl.begin()); CPPUNIT_ASSERT( *slit == 1); ++slit++; ++slit; slit = sl.erase(sl.begin(), slit); CPPUNIT_ASSERT( *slit == 3 ); sl.assign(array, array + 5); slit = sl.erase_after(sl.begin()); CPPUNIT_ASSERT( *slit == 2 ); slit = sl.begin(); ++slit; ++slit; slit = sl.erase_after(sl.begin(), slit); CPPUNIT_ASSERT( *slit == 3 ); sl.erase_after(sl.before_begin()); CPPUNIT_ASSERT( sl.front() == 3 ); #endif } void SlistTest::insert() { #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) int array[] = { 0, 1, 2, 3, 4 }; //insert { slist<int> sl; sl.insert(sl.begin(), 5); CPPUNIT_ASSERT( sl.front() == 5 ); CPPUNIT_ASSERT( sl.size() == 1 ); //debug mode check: //sl.insert(sl.before_begin(), array, array + 5); sl.insert(sl.begin(), array, array + 5); CPPUNIT_ASSERT( sl.size() == 6 ); int i; slist<int>::iterator slit(sl.begin()); for (i = 0; slit != sl.end(); ++slit, ++i) { CPPUNIT_ASSERT( *slit == i ); } } //insert_after { slist<int> sl; //debug check: //sl.insert_after(sl.begin(), 5); sl.insert_after(sl.before_begin(), 5); CPPUNIT_ASSERT( sl.front() == 5 ); CPPUNIT_ASSERT( sl.size() == 1 ); sl.insert_after(sl.before_begin(), array, array + 5); CPPUNIT_ASSERT( sl.size() == 6 ); int i; slist<int>::iterator slit(sl.begin()); for (i = 0; slit != sl.end(); ++slit, ++i) { CPPUNIT_ASSERT( *slit == i ); } } #endif } void SlistTest::splice() { #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) int array[] = { 0, 1, 2, 3, 4 }; //splice { slist<int> sl1(array, array + 5); slist<int> sl2(array, array + 5); slist<int>::iterator slit; //a no op: sl1.splice(sl1.begin(), sl1, sl1.begin()); CPPUNIT_ASSERT( sl1 == sl2 ); slit = sl1.begin(); ++slit; //a no op: sl1.splice(slit, sl1, sl1.begin()); CPPUNIT_ASSERT( sl1 == sl2 ); sl1.splice(sl1.end(), sl1, sl1.begin()); slit = sl1.begin(); CPPUNIT_ASSERT( *(slit++) == 1 ); CPPUNIT_ASSERT( *(slit++) == 2 ); CPPUNIT_ASSERT( *(slit++) == 3 ); CPPUNIT_ASSERT( *(slit++) == 4 ); CPPUNIT_ASSERT( *slit == 0 ); sl1.splice(sl1.begin(), sl1, slit); CPPUNIT_ASSERT( sl1 == sl2 ); sl1.splice(sl1.begin(), sl2); size_t i; for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) { if (i == 5) i = 0; CPPUNIT_ASSERT( *slit == array[i] ); } slit = sl1.begin(); advance(slit, 5); CPPUNIT_ASSERT( *slit == 0 ); sl2.splice(sl2.begin(), sl1, sl1.begin(), slit); CPPUNIT_ASSERT( sl1 == sl2 ); slit = sl1.begin(); ++slit; sl1.splice(sl1.begin(), sl1, slit, sl1.end()); slit = sl1.begin(); CPPUNIT_ASSERT( *(slit++) == 1 ); CPPUNIT_ASSERT( *(slit++) == 2 ); CPPUNIT_ASSERT( *(slit++) == 3 ); CPPUNIT_ASSERT( *(slit++) == 4 ); CPPUNIT_ASSERT( *slit == 0 ); // a no op sl2.splice(sl2.end(), sl2, sl2.begin(), sl2.end()); for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) { CPPUNIT_ASSERT( i < 5 ); CPPUNIT_ASSERT( *slit == array[i] ); } slit = sl2.begin(); advance(slit, 3); sl2.splice(sl2.end(), sl2, sl2.begin(), slit); slit = sl2.begin(); CPPUNIT_ASSERT( *(slit++) == 3 ); CPPUNIT_ASSERT( *(slit++) == 4 ); CPPUNIT_ASSERT( *(slit++) == 0 ); CPPUNIT_ASSERT( *(slit++) == 1 ); CPPUNIT_ASSERT( *slit == 2 ); } //splice_after { slist<int> sl1(array, array + 5); slist<int> sl2(array, array + 5); slist<int>::iterator slit; //a no op: sl1.splice_after(sl1.begin(), sl1, sl1.begin()); CPPUNIT_ASSERT( sl1 == sl2 ); sl1.splice_after(sl1.before_begin(), sl1, sl1.begin()); slit = sl1.begin(); CPPUNIT_ASSERT( *(slit++) == 1 ); CPPUNIT_ASSERT( *(slit++) == 0 ); CPPUNIT_ASSERT( *(slit++) == 2 ); CPPUNIT_ASSERT( *(slit++) == 3 ); CPPUNIT_ASSERT( *slit == 4 ); sl1.splice_after(sl1.before_begin(), sl1, sl1.begin()); CPPUNIT_ASSERT( sl1 == sl2 ); sl1.splice_after(sl1.before_begin(), sl2); size_t i; for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) { if (i == 5) i = 0; CPPUNIT_ASSERT( *slit == array[i] ); } slit = sl1.begin(); advance(slit, 4); CPPUNIT_ASSERT( *slit == 4 ); sl2.splice_after(sl2.before_begin(), sl1, sl1.before_begin(), slit); CPPUNIT_ASSERT( sl1 == sl2 ); sl1.splice_after(sl1.before_begin(), sl1, sl1.begin(), sl1.previous(sl1.end())); slit = sl1.begin(); CPPUNIT_ASSERT( *(slit++) == 1 ); CPPUNIT_ASSERT( *(slit++) == 2 ); CPPUNIT_ASSERT( *(slit++) == 3 ); CPPUNIT_ASSERT( *(slit++) == 4 ); CPPUNIT_ASSERT( *slit == 0 ); // a no op sl2.splice_after(sl2.before_begin(), sl2, sl2.before_begin(), sl2.previous(sl2.end())); for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) { CPPUNIT_ASSERT( i < 5 ); CPPUNIT_ASSERT( *slit == array[i] ); } slit = sl2.begin(); advance(slit, 2); sl2.splice_after(sl2.previous(sl2.end()), sl2, sl2.before_begin(), slit); slit = sl2.begin(); CPPUNIT_ASSERT( *(slit++) == 3 ); CPPUNIT_ASSERT( *(slit++) == 4 ); CPPUNIT_ASSERT( *(slit++) == 0 ); CPPUNIT_ASSERT( *(slit++) == 1 ); CPPUNIT_ASSERT( *slit == 2 ); } #endif } void SlistTest::allocator_with_state() { #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) char buf1[1024]; StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1)); char buf2[1024]; StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2)); typedef slist<int, StackAllocator<int> > SlistInt; { SlistInt slint1(10, 0, stack1); SlistInt slint1Cpy(slint1); SlistInt slint2(10, 1, stack2); SlistInt slint2Cpy(slint2); slint1.swap(slint2); CPPUNIT_ASSERT( slint1.get_allocator().swaped() ); CPPUNIT_ASSERT( slint2.get_allocator().swaped() ); CPPUNIT_ASSERT( slint1 == slint2Cpy ); CPPUNIT_ASSERT( slint2 == slint1Cpy ); CPPUNIT_ASSERT( slint1.get_allocator() == stack2 ); CPPUNIT_ASSERT( slint2.get_allocator() == stack1 ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); { SlistInt slint1(stack1); SlistInt slint1Cpy(slint1); SlistInt slint2(10, 1, stack2); SlistInt slint2Cpy(slint2); slint1.swap(slint2); CPPUNIT_ASSERT( slint1.get_allocator().swaped() ); CPPUNIT_ASSERT( slint2.get_allocator().swaped() ); CPPUNIT_ASSERT( slint1 == slint2Cpy ); CPPUNIT_ASSERT( slint2 == slint1Cpy ); CPPUNIT_ASSERT( slint1.get_allocator() == stack2 ); CPPUNIT_ASSERT( slint2.get_allocator() == stack1 ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); { SlistInt slint1(10, 0, stack1); SlistInt slint1Cpy(slint1); SlistInt slint2(stack2); SlistInt slint2Cpy(slint2); slint1.swap(slint2); CPPUNIT_ASSERT( slint1.get_allocator().swaped() ); CPPUNIT_ASSERT( slint2.get_allocator().swaped() ); CPPUNIT_ASSERT( slint1 == slint2Cpy ); CPPUNIT_ASSERT( slint2 == slint1Cpy ); CPPUNIT_ASSERT( slint1.get_allocator() == stack2 ); CPPUNIT_ASSERT( slint2.get_allocator() == stack1 ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); //splice(iterator, slist) { SlistInt slint1(10, 0, stack1); SlistInt slint2(10, 1, stack2); slint1.splice(slint1.begin(), slint2); CPPUNIT_ASSERT( slint1.size() == 20 ); CPPUNIT_ASSERT( slint2.empty() ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); //splice(iterator, slist, iterator) { SlistInt slint1(10, 0, stack1); SlistInt slint2(10, 1, stack2); slint1.splice(slint1.begin(), slint2, slint2.begin()); CPPUNIT_ASSERT( slint1.size() == 11 ); CPPUNIT_ASSERT( slint2.size() == 9 ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); //splice(iterator, slist, iterator, iterator) { SlistInt slint1(10, 0, stack1); SlistInt slint2(10, 1, stack2); SlistInt::iterator lit(slint2.begin()); advance(lit, 5); slint1.splice(slint1.begin(), slint2, slint2.begin(), lit); CPPUNIT_ASSERT( slint1.size() == 15 ); CPPUNIT_ASSERT( slint2.size() == 5 ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); //splice_after(iterator, slist) { SlistInt slint1(10, 0, stack1); SlistInt slint2(10, 1, stack2); slint1.splice_after(slint1.before_begin(), slint2); CPPUNIT_ASSERT( slint1.size() == 20 ); CPPUNIT_ASSERT( slint2.empty() ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); //splice_after(iterator, slist, iterator) { SlistInt slint1(10, 0, stack1); SlistInt slint2(10, 1, stack2); slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin()); CPPUNIT_ASSERT( slint1.size() == 11 ); CPPUNIT_ASSERT( slint2.size() == 9 ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); //splice_after(iterator, slist, iterator, iterator) { SlistInt slint1(10, 0, stack1); SlistInt slint2(10, 1, stack2); SlistInt::iterator lit(slint2.begin()); advance(lit, 4); slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin(), lit); CPPUNIT_ASSERT( slint1.size() == 15 ); CPPUNIT_ASSERT( slint2.size() == 5 ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); stack1.reset(); stack2.reset(); //merge(slist) { SlistInt slint1(10, 0, stack1); SlistInt slint2(10, 1, stack2); SlistInt slintref(stack2); slintref.insert_after(slintref.before_begin(), 10, 1); slintref.insert_after(slintref.before_begin(), 10, 0); slint1.merge(slint2); CPPUNIT_ASSERT( slint1.size() == 20 ); CPPUNIT_ASSERT( slint1 == slintref ); CPPUNIT_ASSERT( slint2.empty() ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); //merge(slist, predicate) # if (!defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)) && \ (!defined (_MSC_VER) || (_MSC_VER >= 1300)) { SlistInt slint1(10, 0, stack1); SlistInt slint2(10, 1, stack2); SlistInt slintref(stack2); slintref.insert_after(slintref.before_begin(), 10, 0); slintref.insert_after(slintref.before_begin(), 10, 1); slint1.merge(slint2, greater<int>()); CPPUNIT_ASSERT( slint1.size() == 20 ); CPPUNIT_ASSERT( slint1 == slintref ); CPPUNIT_ASSERT( slint2.empty() ); } CPPUNIT_CHECK( stack1.ok() ); CPPUNIT_CHECK( stack2.ok() ); //sort { //This is rather a compile time test. //We check that sort implementation is correct when list is instanciated //with an allocator that do not have a default constructor. SlistInt slint1(stack1); slint1.push_front(1); slint1.insert_after(slint1.before_begin(), 10, 0); greater<int> gt; slint1.sort(gt); CPPUNIT_ASSERT( slint1.front() == 1 ); slint1.sort(); SlistInt::iterator slit(slint1.begin()); advance(slit, 10); CPPUNIT_ASSERT( *slit == 1 ); } # endif #endif } #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && \ (!defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)) # if !defined (__DMC__) /* Simple compilation test: Check that nested types like iterator * can be access even if type used to instanciate container is not * yet completely defined. */ class IncompleteClass { slist<IncompleteClass> instances; typedef slist<IncompleteClass>::iterator it; }; # endif #endif