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 <deque>
      6 #include <algorithm>
      7 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
      8 # include <stdexcept>
      9 #endif
     10 
     11 #include "cppunit/cppunit_proxy.h"
     12 
     13 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     14 using namespace std;
     15 #endif
     16 
     17 //
     18 // TestCase class
     19 //
     20 class DequeTest : public CPPUNIT_NS::TestCase
     21 {
     22   CPPUNIT_TEST_SUITE(DequeTest);
     23   CPPUNIT_TEST(deque1);
     24   CPPUNIT_TEST(at);
     25   CPPUNIT_TEST(insert);
     26   CPPUNIT_TEST(erase);
     27   CPPUNIT_TEST(auto_ref);
     28   CPPUNIT_TEST(allocator_with_state);
     29 #if defined (STLPORT) && defined (_STLP_NO_MEMBER_TEMPLATES)
     30   CPPUNIT_IGNORE;
     31 #endif
     32   CPPUNIT_TEST(optimizations_check);
     33   CPPUNIT_TEST_SUITE_END();
     34 
     35 protected:
     36   void deque1();
     37   void insert();
     38   void erase();
     39   void at();
     40   void auto_ref();
     41   void allocator_with_state();
     42   void optimizations_check();
     43 };
     44 
     45 CPPUNIT_TEST_SUITE_REGISTRATION(DequeTest);
     46 
     47 //
     48 // tests implementation
     49 //
     50 void DequeTest::deque1()
     51 {
     52   deque<int> d;
     53   d.push_back(4);
     54   d.push_back(9);
     55   d.push_back(16);
     56   d.push_front(1);
     57 
     58   CPPUNIT_ASSERT( d[0] == 1 );
     59   CPPUNIT_ASSERT( d[1] == 4 );
     60   CPPUNIT_ASSERT( d[2] == 9 );
     61   CPPUNIT_ASSERT( d[3] == 16 );
     62 
     63   d.pop_front();
     64   d[2] = 25;
     65 
     66   CPPUNIT_ASSERT( d[0] == 4 );
     67   CPPUNIT_ASSERT( d[1] == 9 );
     68   CPPUNIT_ASSERT( d[2] == 25 );
     69 
     70   //Some compile time tests:
     71   deque<int>::iterator dit = d.begin();
     72   deque<int>::const_iterator cdit(d.begin());
     73   CPPUNIT_ASSERT( (dit - cdit) == 0 );
     74   CPPUNIT_ASSERT( (cdit - dit) == 0 );
     75   CPPUNIT_ASSERT( (dit - dit) == 0 );
     76   CPPUNIT_ASSERT( (cdit - cdit) == 0 );
     77   CPPUNIT_ASSERT(!((dit < cdit) || (dit > cdit) || (dit != cdit) || !(dit <= cdit) || !(dit >= cdit)));
     78 }
     79 
     80 void DequeTest::insert()
     81 {
     82   deque<int> d;
     83   d.push_back(0);
     84   d.push_back(1);
     85   d.push_back(2);
     86   CPPUNIT_ASSERT( d.size() == 3 );
     87 
     88   deque<int>::iterator dit;
     89 
     90   //Insertion before begin:
     91   dit = d.insert(d.begin(), 3);
     92   CPPUNIT_ASSERT( dit != d.end() );
     93   CPPUNIT_CHECK( *dit == 3 );
     94   CPPUNIT_ASSERT( d.size() == 4 );
     95   CPPUNIT_ASSERT( d[0] == 3 );
     96 
     97   //Insertion after begin:
     98   dit = d.insert(d.begin() + 1, 4);
     99   CPPUNIT_ASSERT( dit != d.end() );
    100   CPPUNIT_CHECK( *dit == 4 );
    101   CPPUNIT_ASSERT( d.size() == 5 );
    102   CPPUNIT_ASSERT( d[1] == 4 );
    103 
    104   //Insertion at end:
    105   dit = d.insert(d.end(), 5);
    106   CPPUNIT_ASSERT( dit != d.end() );
    107   CPPUNIT_CHECK( *dit == 5 );
    108   CPPUNIT_ASSERT( d.size() == 6 );
    109   CPPUNIT_ASSERT( d[5] == 5 );
    110 
    111   //Insertion before last element:
    112   dit = d.insert(d.end() - 1, 6);
    113   CPPUNIT_ASSERT( dit != d.end() );
    114   CPPUNIT_CHECK( *dit == 6 );
    115   CPPUNIT_ASSERT( d.size() == 7 );
    116   CPPUNIT_ASSERT( d[5] == 6 );
    117 
    118   //Insertion of several elements before begin
    119   d.insert(d.begin(), 2, 7);
    120   CPPUNIT_ASSERT( d.size() == 9 );
    121   CPPUNIT_ASSERT( d[0] == 7 );
    122   CPPUNIT_ASSERT( d[1] == 7 );
    123 
    124   //Insertion of several elements after begin
    125   //There is more elements to insert than elements before insertion position
    126   d.insert(d.begin() + 1, 2, 8);
    127   CPPUNIT_ASSERT( d.size() == 11 );
    128   CPPUNIT_ASSERT( d[1] == 8 );
    129   CPPUNIT_ASSERT( d[2] == 8 );
    130 
    131   //There is less elements to insert than elements before insertion position
    132   d.insert(d.begin() + 3, 2, 9);
    133   CPPUNIT_ASSERT( d.size() == 13 );
    134   CPPUNIT_ASSERT( d[3] == 9 );
    135   CPPUNIT_ASSERT( d[4] == 9 );
    136 
    137   //Insertion of several elements at end:
    138   d.insert(d.end(), 2, 10);
    139   CPPUNIT_ASSERT( d.size() == 15 );
    140   CPPUNIT_ASSERT( d[14] == 10 );
    141   CPPUNIT_ASSERT( d[13] == 10 );
    142 
    143   //Insertion of several elements before last:
    144   //There is more elements to insert than elements after insertion position
    145   d.insert(d.end() - 1, 2, 11);
    146   CPPUNIT_ASSERT( d.size() == 17 );
    147   CPPUNIT_ASSERT( d[15] == 11 );
    148   CPPUNIT_ASSERT( d[14] == 11 );
    149 
    150   //There is less elements to insert than elements after insertion position
    151   d.insert(d.end() - 3, 2, 12);
    152   CPPUNIT_ASSERT( d.size() == 19 );
    153   CPPUNIT_ASSERT( d[15] == 12 );
    154   CPPUNIT_ASSERT( d[14] == 12 );
    155 }
    156 
    157 void DequeTest::at() {
    158   deque<int> d;
    159   deque<int> const& cd = d;
    160 
    161   d.push_back(10);
    162   CPPUNIT_ASSERT( d.at(0) == 10 );
    163   d.at(0) = 20;
    164   CPPUNIT_ASSERT( cd.at(0) == 20 );
    165 
    166 #if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    167   for (;;) {
    168     try {
    169       d.at(1) = 20;
    170       CPPUNIT_ASSERT(false);
    171     }
    172     catch (out_of_range const&) {
    173       return;
    174     }
    175     catch (...) {
    176       CPPUNIT_ASSERT(false);
    177     }
    178   }
    179 #endif
    180 }
    181 
    182 void DequeTest::auto_ref()
    183 {
    184   int i;
    185   deque<int> ref;
    186   for (i = 0; i < 5; ++i) {
    187     ref.push_back(i);
    188   }
    189 
    190   deque<deque<int> > d_d_int(1, ref);
    191   d_d_int.push_back(d_d_int[0]);
    192   d_d_int.push_back(ref);
    193   d_d_int.push_back(d_d_int[0]);
    194   d_d_int.push_back(d_d_int[0]);
    195   d_d_int.push_back(ref);
    196 
    197   for (i = 0; i < 5; ++i) {
    198     CPPUNIT_ASSERT( d_d_int[i] == ref );
    199   }
    200 }
    201 
    202 void DequeTest::allocator_with_state()
    203 {
    204   char buf1[1024];
    205   StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1));
    206 
    207   char buf2[1024];
    208   StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2));
    209 
    210   {
    211     typedef deque<int, StackAllocator<int> > DequeInt;
    212     DequeInt dint1(10, 0, stack1);
    213     DequeInt dint1Cpy(dint1);
    214 
    215     DequeInt dint2(10, 1, stack2);
    216     DequeInt dint2Cpy(dint2);
    217 
    218     dint1.swap(dint2);
    219 
    220     CPPUNIT_ASSERT( dint1.get_allocator().swaped() );
    221     CPPUNIT_ASSERT( dint2.get_allocator().swaped() );
    222 
    223     CPPUNIT_ASSERT( dint1 == dint2Cpy );
    224     CPPUNIT_ASSERT( dint2 == dint1Cpy );
    225     CPPUNIT_ASSERT( dint1.get_allocator() == stack2 );
    226     CPPUNIT_ASSERT( dint2.get_allocator() == stack1 );
    227   }
    228   CPPUNIT_ASSERT( stack1.ok() );
    229   CPPUNIT_ASSERT( stack2.ok() );
    230 }
    231 
    232 struct Point {
    233   int x, y;
    234 };
    235 
    236 struct PointEx : public Point {
    237   PointEx() : builtFromBase(false) {}
    238   PointEx(const Point&) : builtFromBase(true) {}
    239 
    240   bool builtFromBase;
    241 };
    242 
    243 #if defined (STLPORT)
    244 #  if defined (_STLP_USE_NAMESPACES)
    245 namespace std {
    246 #  endif
    247   _STLP_TEMPLATE_NULL
    248   struct __type_traits<PointEx> {
    249     typedef __false_type has_trivial_default_constructor;
    250     typedef __true_type has_trivial_copy_constructor;
    251     typedef __true_type has_trivial_assignment_operator;
    252     typedef __true_type has_trivial_destructor;
    253     typedef __true_type is_POD_type;
    254   };
    255 #  if defined (_STLP_USE_NAMESPACES)
    256 }
    257 #  endif
    258 #endif
    259 
    260 //This test check that deque implementation do not over optimize
    261 //operation as PointEx copy constructor is trivial
    262 void DequeTest::optimizations_check()
    263 {
    264 #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
    265   deque<Point> d1(1);
    266   CPPUNIT_ASSERT( d1.size() == 1 );
    267 
    268   deque<PointEx> d2(d1.begin(), d1.end());
    269   CPPUNIT_ASSERT( d2.size() == 1 );
    270   CPPUNIT_ASSERT( d2[0].builtFromBase == true );
    271 
    272   d2.insert(d2.end(), d1.begin(), d1.end());
    273   CPPUNIT_ASSERT( d2.size() == 2 );
    274   CPPUNIT_ASSERT( d2[1].builtFromBase == true );
    275 #endif
    276 }
    277 
    278 void DequeTest::erase()
    279 {
    280   deque<int> dint;
    281   dint.push_back(3);
    282   dint.push_front(2);
    283   dint.push_back(4);
    284   dint.push_front(1);
    285   dint.push_back(5);
    286   dint.push_front(0);
    287   dint.push_back(6);
    288 
    289   deque<int>::iterator it(dint.begin() + 1);
    290   CPPUNIT_ASSERT( *it == 1 );
    291 
    292   dint.erase(dint.begin());
    293   CPPUNIT_ASSERT( *it == 1 );
    294 
    295   it = dint.end() - 2;
    296   CPPUNIT_ASSERT( *it == 5 );
    297 
    298   dint.erase(dint.end() - 1);
    299   CPPUNIT_ASSERT( *it == 5 );
    300 
    301   dint.push_back(6);
    302   dint.push_front(0);
    303 
    304   it = dint.begin() + 2;
    305   CPPUNIT_ASSERT( *it == 2 );
    306 
    307   dint.erase(dint.begin(), dint.begin() + 2);
    308   CPPUNIT_ASSERT( *it == 2 );
    309 
    310   it = dint.end() - 3;
    311   CPPUNIT_ASSERT( *it == 4 );
    312 
    313   dint.erase(dint.end() - 2, dint.end());
    314   CPPUNIT_ASSERT( *it == 4 );
    315 }
    316 
    317 #if (!defined (STLPORT) || \
    318     (!defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION))) && \
    319      (!defined (_MSC_VER) || (_MSC_VER > 1400)) && \
    320      (!defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 3))
    321 /* Simple compilation test: Check that nested types like iterator
    322  * can be access even if type used to instanciate container is not
    323  * yet completely defined.
    324  */
    325 class IncompleteClass
    326 {
    327   deque<IncompleteClass> instances;
    328   typedef deque<IncompleteClass>::size_type size;
    329 };
    330 #endif
    331