Home | History | Annotate | Download | only in unit
      1 //Has to be first for StackAllocator swap overload to be taken
      2 //into account (at least using GCC 4.0.1)
      3 #include "stack_allocator.h"
      4 
      5 #include <algorithm>
      6 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
      7 #  include <slist>
      8 #  if !defined (_STLP_USE_NO_IOSTREAMS)
      9 #    include <sstream>
     10 #  endif
     11 #  include <iterator>
     12 #  include <functional>
     13 #endif
     14 
     15 #include "cppunit/cppunit_proxy.h"
     16 
     17 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     18 using namespace std;
     19 #endif
     20 
     21 #if !defined (STLPORT) && defined(__GNUC__)
     22 using namespace __gnu_cxx;
     23 #endif
     24 
     25 //
     26 // TestCase class
     27 //
     28 class SlistTest : public CPPUNIT_NS::TestCase
     29 {
     30   CPPUNIT_TEST_SUITE(SlistTest);
     31 #if !defined (STLPORT) || defined (_STLP_NO_EXTENSIONS) || defined (_STLP_USE_NO_IOSTREAMS)
     32   CPPUNIT_IGNORE;
     33 #endif
     34   CPPUNIT_TEST(slist1);
     35 #if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS)
     36   CPPUNIT_STOP_IGNORE;
     37 #endif
     38   CPPUNIT_TEST(erase);
     39   CPPUNIT_TEST(insert);
     40   CPPUNIT_TEST(splice);
     41   CPPUNIT_TEST(allocator_with_state);
     42   CPPUNIT_TEST_SUITE_END();
     43 
     44 protected:
     45   void slist1();
     46   void erase();
     47   void insert();
     48   void splice();
     49   void allocator_with_state();
     50 };
     51 
     52 CPPUNIT_TEST_SUITE_REGISTRATION(SlistTest);
     53 
     54 //
     55 // tests implementation
     56 //
     57 void SlistTest::slist1()
     58 {
     59 #if defined (STLPORT) && !defined (_STLP_USE_NO_IOSTREAMS) && !defined (_STLP_NO_EXTENSIONS)
     60 /*
     61 original: xlxtss
     62 reversed: sstxlx
     63 removed: sstl
     64 uniqued: stl
     65 sorted: lst
     66 */
     67 
     68   char array [] = { 'x', 'l', 'x', 't', 's', 's' };
     69   ostringstream os;
     70   ostream_iterator<char> o(os,"");
     71   slist<char> str(array+0, array + 6);
     72   slist<char>::iterator i;
     73   //Check const_iterator construction from iterator
     74   slist<char>::const_iterator ci(i);
     75   slist<char>::const_iterator ci2(ci);
     76 //  cout << "reversed: ";
     77   str.reverse();
     78   for(i = str.begin(); i != str.end(); i++)
     79     os << *i;
     80   stringbuf* buff=os.rdbuf();
     81   string result=buff->str();
     82   CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstxlx"));
     83 
     84   //cout << "removed: ";
     85   str.remove('x');
     86   ostringstream os2;
     87   for(i = str.begin(); i != str.end(); i++)
     88     os2 << *i;
     89   buff=os2.rdbuf();
     90   result=buff->str();
     91   CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstl"));
     92 
     93 
     94   //cout << "uniqued: ";
     95   str.unique();
     96   ostringstream os3;
     97   for(i = str.begin(); i != str.end(); i++)
     98     os3 << *i;
     99   buff=os3.rdbuf();
    100   result=buff->str();
    101   CPPUNIT_ASSERT(!strcmp(result.c_str(),"stl"));
    102 
    103   //cout << "sorted: ";
    104   str.sort();
    105   ostringstream os4;
    106   for(i = str.begin(); i != str.end(); i++)
    107     os4 << *i;
    108   buff = os4.rdbuf();
    109   result = buff->str();
    110   CPPUNIT_ASSERT(!strcmp(result.c_str(),"lst"));
    111 
    112   //A small compilation time check to be activated from time to time:
    113 #  if 0
    114   {
    115     slist<char>::iterator sl_char_ite;
    116     slist<int>::iterator sl_int_ite;
    117     CPPUNIT_ASSERT( sl_char_ite != sl_int_ite );
    118   }
    119 #  endif
    120 #endif
    121 }
    122 
    123 void SlistTest::erase()
    124 {
    125 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
    126   int array[] = { 0, 1, 2, 3, 4 };
    127   slist<int> sl(array, array + 5);
    128   slist<int>::iterator slit;
    129 
    130   slit = sl.erase(sl.begin());
    131   CPPUNIT_ASSERT( *slit == 1);
    132 
    133   ++slit++; ++slit;
    134   slit = sl.erase(sl.begin(), slit);
    135   CPPUNIT_ASSERT( *slit == 3 );
    136 
    137   sl.assign(array, array + 5);
    138 
    139   slit = sl.erase_after(sl.begin());
    140   CPPUNIT_ASSERT( *slit == 2 );
    141 
    142   slit = sl.begin(); ++slit; ++slit;
    143   slit = sl.erase_after(sl.begin(), slit);
    144   CPPUNIT_ASSERT( *slit == 3 );
    145 
    146   sl.erase_after(sl.before_begin());
    147   CPPUNIT_ASSERT( sl.front() == 3 );
    148 #endif
    149 }
    150 
    151 void SlistTest::insert()
    152 {
    153 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
    154   int array[] = { 0, 1, 2, 3, 4 };
    155 
    156   //insert
    157   {
    158     slist<int> sl;
    159 
    160     sl.insert(sl.begin(), 5);
    161     CPPUNIT_ASSERT( sl.front() == 5 );
    162     CPPUNIT_ASSERT( sl.size() == 1 );
    163 
    164     //debug mode check:
    165     //sl.insert(sl.before_begin(), array, array + 5);
    166 
    167     sl.insert(sl.begin(), array, array + 5);
    168     CPPUNIT_ASSERT( sl.size() == 6 );
    169     int i;
    170     slist<int>::iterator slit(sl.begin());
    171     for (i = 0; slit != sl.end(); ++slit, ++i) {
    172       CPPUNIT_ASSERT( *slit == i );
    173     }
    174   }
    175 
    176   //insert_after
    177   {
    178     slist<int> sl;
    179 
    180     //debug check:
    181     //sl.insert_after(sl.begin(), 5);
    182 
    183     sl.insert_after(sl.before_begin(), 5);
    184     CPPUNIT_ASSERT( sl.front() == 5 );
    185     CPPUNIT_ASSERT( sl.size() == 1 );
    186 
    187     sl.insert_after(sl.before_begin(), array, array + 5);
    188     CPPUNIT_ASSERT( sl.size() == 6 );
    189     int i;
    190     slist<int>::iterator slit(sl.begin());
    191     for (i = 0; slit != sl.end(); ++slit, ++i) {
    192       CPPUNIT_ASSERT( *slit == i );
    193     }
    194   }
    195 #endif
    196 }
    197 
    198 void SlistTest::splice()
    199 {
    200 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
    201   int array[] = { 0, 1, 2, 3, 4 };
    202 
    203   //splice
    204   {
    205     slist<int> sl1(array, array + 5);
    206     slist<int> sl2(array, array + 5);
    207     slist<int>::iterator slit;
    208 
    209     //a no op:
    210     sl1.splice(sl1.begin(), sl1, sl1.begin());
    211     CPPUNIT_ASSERT( sl1 == sl2 );
    212 
    213     slit = sl1.begin(); ++slit;
    214     //a no op:
    215     sl1.splice(slit, sl1, sl1.begin());
    216     CPPUNIT_ASSERT( sl1 == sl2 );
    217 
    218     sl1.splice(sl1.end(), sl1, sl1.begin());
    219     slit = sl1.begin();
    220     CPPUNIT_ASSERT( *(slit++) == 1 );
    221     CPPUNIT_ASSERT( *(slit++) == 2 );
    222     CPPUNIT_ASSERT( *(slit++) == 3 );
    223     CPPUNIT_ASSERT( *(slit++) == 4 );
    224     CPPUNIT_ASSERT( *slit == 0 );
    225     sl1.splice(sl1.begin(), sl1, slit);
    226     CPPUNIT_ASSERT( sl1 == sl2 );
    227 
    228     sl1.splice(sl1.begin(), sl2);
    229     size_t i;
    230     for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) {
    231       if (i == 5) i = 0;
    232       CPPUNIT_ASSERT( *slit == array[i] );
    233     }
    234 
    235     slit = sl1.begin();
    236     advance(slit, 5);
    237     CPPUNIT_ASSERT( *slit == 0 );
    238     sl2.splice(sl2.begin(), sl1, sl1.begin(), slit);
    239     CPPUNIT_ASSERT( sl1 == sl2 );
    240 
    241     slit = sl1.begin(); ++slit;
    242     sl1.splice(sl1.begin(), sl1, slit, sl1.end());
    243     slit = sl1.begin();
    244     CPPUNIT_ASSERT( *(slit++) == 1 );
    245     CPPUNIT_ASSERT( *(slit++) == 2 );
    246     CPPUNIT_ASSERT( *(slit++) == 3 );
    247     CPPUNIT_ASSERT( *(slit++) == 4 );
    248     CPPUNIT_ASSERT( *slit == 0 );
    249 
    250     // a no op
    251     sl2.splice(sl2.end(), sl2, sl2.begin(), sl2.end());
    252     for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) {
    253       CPPUNIT_ASSERT( i < 5 );
    254       CPPUNIT_ASSERT( *slit == array[i] );
    255     }
    256 
    257     slit = sl2.begin();
    258     advance(slit, 3);
    259     sl2.splice(sl2.end(), sl2, sl2.begin(), slit);
    260     slit = sl2.begin();
    261     CPPUNIT_ASSERT( *(slit++) == 3 );
    262     CPPUNIT_ASSERT( *(slit++) == 4 );
    263     CPPUNIT_ASSERT( *(slit++) == 0 );
    264     CPPUNIT_ASSERT( *(slit++) == 1 );
    265     CPPUNIT_ASSERT( *slit == 2 );
    266   }
    267 
    268   //splice_after
    269   {
    270     slist<int> sl1(array, array + 5);
    271     slist<int> sl2(array, array + 5);
    272     slist<int>::iterator slit;
    273 
    274     //a no op:
    275     sl1.splice_after(sl1.begin(), sl1, sl1.begin());
    276     CPPUNIT_ASSERT( sl1 == sl2 );
    277 
    278     sl1.splice_after(sl1.before_begin(), sl1, sl1.begin());
    279     slit = sl1.begin();
    280     CPPUNIT_ASSERT( *(slit++) == 1 );
    281     CPPUNIT_ASSERT( *(slit++) == 0 );
    282     CPPUNIT_ASSERT( *(slit++) == 2 );
    283     CPPUNIT_ASSERT( *(slit++) == 3 );
    284     CPPUNIT_ASSERT( *slit == 4 );
    285     sl1.splice_after(sl1.before_begin(), sl1, sl1.begin());
    286     CPPUNIT_ASSERT( sl1 == sl2 );
    287 
    288     sl1.splice_after(sl1.before_begin(), sl2);
    289     size_t i;
    290     for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) {
    291       if (i == 5) i = 0;
    292       CPPUNIT_ASSERT( *slit == array[i] );
    293     }
    294 
    295     slit = sl1.begin();
    296     advance(slit, 4);
    297     CPPUNIT_ASSERT( *slit == 4 );
    298     sl2.splice_after(sl2.before_begin(), sl1, sl1.before_begin(), slit);
    299     CPPUNIT_ASSERT( sl1 == sl2 );
    300 
    301     sl1.splice_after(sl1.before_begin(), sl1, sl1.begin(), sl1.previous(sl1.end()));
    302     slit = sl1.begin();
    303     CPPUNIT_ASSERT( *(slit++) == 1 );
    304     CPPUNIT_ASSERT( *(slit++) == 2 );
    305     CPPUNIT_ASSERT( *(slit++) == 3 );
    306     CPPUNIT_ASSERT( *(slit++) == 4 );
    307     CPPUNIT_ASSERT( *slit == 0 );
    308 
    309     // a no op
    310     sl2.splice_after(sl2.before_begin(), sl2, sl2.before_begin(), sl2.previous(sl2.end()));
    311     for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) {
    312       CPPUNIT_ASSERT( i < 5 );
    313       CPPUNIT_ASSERT( *slit == array[i] );
    314     }
    315 
    316     slit = sl2.begin();
    317     advance(slit, 2);
    318     sl2.splice_after(sl2.previous(sl2.end()), sl2, sl2.before_begin(), slit);
    319     slit = sl2.begin();
    320     CPPUNIT_ASSERT( *(slit++) == 3 );
    321     CPPUNIT_ASSERT( *(slit++) == 4 );
    322     CPPUNIT_ASSERT( *(slit++) == 0 );
    323     CPPUNIT_ASSERT( *(slit++) == 1 );
    324     CPPUNIT_ASSERT( *slit == 2 );
    325   }
    326 #endif
    327 }
    328 
    329 
    330 void SlistTest::allocator_with_state()
    331 {
    332 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
    333   char buf1[1024];
    334   StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1));
    335 
    336   char buf2[1024];
    337   StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2));
    338 
    339   typedef slist<int, StackAllocator<int> > SlistInt;
    340   {
    341     SlistInt slint1(10, 0, stack1);
    342     SlistInt slint1Cpy(slint1);
    343 
    344     SlistInt slint2(10, 1, stack2);
    345     SlistInt slint2Cpy(slint2);
    346 
    347     slint1.swap(slint2);
    348 
    349     CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
    350     CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
    351 
    352     CPPUNIT_ASSERT( slint1 == slint2Cpy );
    353     CPPUNIT_ASSERT( slint2 == slint1Cpy );
    354     CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
    355     CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
    356   }
    357   CPPUNIT_CHECK( stack1.ok() );
    358   CPPUNIT_CHECK( stack2.ok() );
    359   stack1.reset(); stack2.reset();
    360 
    361   {
    362     SlistInt slint1(stack1);
    363     SlistInt slint1Cpy(slint1);
    364 
    365     SlistInt slint2(10, 1, stack2);
    366     SlistInt slint2Cpy(slint2);
    367 
    368     slint1.swap(slint2);
    369 
    370     CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
    371     CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
    372 
    373     CPPUNIT_ASSERT( slint1 == slint2Cpy );
    374     CPPUNIT_ASSERT( slint2 == slint1Cpy );
    375     CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
    376     CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
    377   }
    378   CPPUNIT_CHECK( stack1.ok() );
    379   CPPUNIT_CHECK( stack2.ok() );
    380   stack1.reset(); stack2.reset();
    381 
    382   {
    383     SlistInt slint1(10, 0, stack1);
    384     SlistInt slint1Cpy(slint1);
    385 
    386     SlistInt slint2(stack2);
    387     SlistInt slint2Cpy(slint2);
    388 
    389     slint1.swap(slint2);
    390 
    391     CPPUNIT_ASSERT( slint1.get_allocator().swaped() );
    392     CPPUNIT_ASSERT( slint2.get_allocator().swaped() );
    393 
    394     CPPUNIT_ASSERT( slint1 == slint2Cpy );
    395     CPPUNIT_ASSERT( slint2 == slint1Cpy );
    396     CPPUNIT_ASSERT( slint1.get_allocator() == stack2 );
    397     CPPUNIT_ASSERT( slint2.get_allocator() == stack1 );
    398   }
    399   CPPUNIT_CHECK( stack1.ok() );
    400   CPPUNIT_CHECK( stack2.ok() );
    401   stack1.reset(); stack2.reset();
    402 
    403   //splice(iterator, slist)
    404   {
    405     SlistInt slint1(10, 0, stack1);
    406     SlistInt slint2(10, 1, stack2);
    407 
    408     slint1.splice(slint1.begin(), slint2);
    409     CPPUNIT_ASSERT( slint1.size() == 20 );
    410     CPPUNIT_ASSERT( slint2.empty() );
    411   }
    412   CPPUNIT_CHECK( stack1.ok() );
    413   CPPUNIT_CHECK( stack2.ok() );
    414   stack1.reset(); stack2.reset();
    415 
    416   //splice(iterator, slist, iterator)
    417   {
    418     SlistInt slint1(10, 0, stack1);
    419     SlistInt slint2(10, 1, stack2);
    420 
    421     slint1.splice(slint1.begin(), slint2, slint2.begin());
    422     CPPUNIT_ASSERT( slint1.size() == 11 );
    423     CPPUNIT_ASSERT( slint2.size() == 9 );
    424   }
    425   CPPUNIT_CHECK( stack1.ok() );
    426   CPPUNIT_CHECK( stack2.ok() );
    427   stack1.reset(); stack2.reset();
    428 
    429   //splice(iterator, slist, iterator, iterator)
    430   {
    431     SlistInt slint1(10, 0, stack1);
    432     SlistInt slint2(10, 1, stack2);
    433 
    434     SlistInt::iterator lit(slint2.begin());
    435     advance(lit, 5);
    436     slint1.splice(slint1.begin(), slint2, slint2.begin(), lit);
    437     CPPUNIT_ASSERT( slint1.size() == 15 );
    438     CPPUNIT_ASSERT( slint2.size() == 5 );
    439   }
    440   CPPUNIT_CHECK( stack1.ok() );
    441   CPPUNIT_CHECK( stack2.ok() );
    442   stack1.reset(); stack2.reset();
    443 
    444   //splice_after(iterator, slist)
    445   {
    446     SlistInt slint1(10, 0, stack1);
    447     SlistInt slint2(10, 1, stack2);
    448 
    449     slint1.splice_after(slint1.before_begin(), slint2);
    450     CPPUNIT_ASSERT( slint1.size() == 20 );
    451     CPPUNIT_ASSERT( slint2.empty() );
    452   }
    453   CPPUNIT_CHECK( stack1.ok() );
    454   CPPUNIT_CHECK( stack2.ok() );
    455   stack1.reset(); stack2.reset();
    456 
    457   //splice_after(iterator, slist, iterator)
    458   {
    459     SlistInt slint1(10, 0, stack1);
    460     SlistInt slint2(10, 1, stack2);
    461 
    462     slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin());
    463     CPPUNIT_ASSERT( slint1.size() == 11 );
    464     CPPUNIT_ASSERT( slint2.size() == 9 );
    465   }
    466   CPPUNIT_CHECK( stack1.ok() );
    467   CPPUNIT_CHECK( stack2.ok() );
    468   stack1.reset(); stack2.reset();
    469 
    470   //splice_after(iterator, slist, iterator, iterator)
    471   {
    472     SlistInt slint1(10, 0, stack1);
    473     SlistInt slint2(10, 1, stack2);
    474 
    475     SlistInt::iterator lit(slint2.begin());
    476     advance(lit, 4);
    477     slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin(), lit);
    478     CPPUNIT_ASSERT( slint1.size() == 15 );
    479     CPPUNIT_ASSERT( slint2.size() == 5 );
    480   }
    481   CPPUNIT_CHECK( stack1.ok() );
    482   CPPUNIT_CHECK( stack2.ok() );
    483   stack1.reset(); stack2.reset();
    484 
    485   //merge(slist)
    486   {
    487     SlistInt slint1(10, 0, stack1);
    488     SlistInt slint2(10, 1, stack2);
    489 
    490     SlistInt slintref(stack2);
    491     slintref.insert_after(slintref.before_begin(), 10, 1);
    492     slintref.insert_after(slintref.before_begin(), 10, 0);
    493 
    494     slint1.merge(slint2);
    495     CPPUNIT_ASSERT( slint1.size() == 20 );
    496     CPPUNIT_ASSERT( slint1 == slintref );
    497     CPPUNIT_ASSERT( slint2.empty() );
    498   }
    499   CPPUNIT_CHECK( stack1.ok() );
    500   CPPUNIT_CHECK( stack2.ok() );
    501 
    502   //merge(slist, predicate)
    503 #  if (!defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)) && \
    504       (!defined (_MSC_VER) || (_MSC_VER >= 1300))
    505   {
    506     SlistInt slint1(10, 0, stack1);
    507     SlistInt slint2(10, 1, stack2);
    508 
    509     SlistInt slintref(stack2);
    510     slintref.insert_after(slintref.before_begin(), 10, 0);
    511     slintref.insert_after(slintref.before_begin(), 10, 1);
    512 
    513     slint1.merge(slint2, greater<int>());
    514     CPPUNIT_ASSERT( slint1.size() == 20 );
    515     CPPUNIT_ASSERT( slint1 == slintref );
    516     CPPUNIT_ASSERT( slint2.empty() );
    517   }
    518   CPPUNIT_CHECK( stack1.ok() );
    519   CPPUNIT_CHECK( stack2.ok() );
    520 
    521   //sort
    522   {
    523     //This is rather a compile time test.
    524     //We check that sort implementation is correct when list is instanciated
    525     //with an allocator that do not have a default constructor.
    526     SlistInt slint1(stack1);
    527     slint1.push_front(1);
    528     slint1.insert_after(slint1.before_begin(), 10, 0);
    529     greater<int> gt;
    530     slint1.sort(gt);
    531     CPPUNIT_ASSERT( slint1.front() == 1 );
    532     slint1.sort();
    533     SlistInt::iterator slit(slint1.begin());
    534     advance(slit, 10);
    535     CPPUNIT_ASSERT( *slit == 1 );
    536   }
    537 #  endif
    538 #endif
    539 }
    540 
    541 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && \
    542     (!defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION))
    543 #  if !defined (__DMC__)
    544 /* Simple compilation test: Check that nested types like iterator
    545  * can be access even if type used to instanciate container is not
    546  * yet completely defined.
    547  */
    548 class IncompleteClass
    549 {
    550   slist<IncompleteClass> instances;
    551   typedef slist<IncompleteClass>::iterator it;
    552 };
    553 #  endif
    554 #endif
    555