Home | History | Annotate | Download | only in unit
      1 #include <memory>
      2 #include <vector>
      3 #include <list>
      4 
      5 #include "cppunit/cppunit_proxy.h"
      6 
      7 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
      8 using namespace std;
      9 #endif
     10 
     11 //
     12 // TestCase class
     13 //
     14 class UninitializedTest : public CPPUNIT_NS::TestCase
     15 {
     16   CPPUNIT_TEST_SUITE(UninitializedTest);
     17   CPPUNIT_TEST(copy_test);
     18   //CPPUNIT_TEST(fill_test);
     19   //CPPUNIT_TEST(fill_n_test);
     20   CPPUNIT_TEST_SUITE_END();
     21 
     22 protected:
     23   void copy_test();
     24   void fill_test();
     25   void fill_n_test();
     26 };
     27 
     28 CPPUNIT_TEST_SUITE_REGISTRATION(UninitializedTest);
     29 
     30 struct NotTrivialCopyStruct {
     31   NotTrivialCopyStruct() : member(0) {}
     32   NotTrivialCopyStruct(NotTrivialCopyStruct const&) : member(1) {}
     33 
     34   int member;
     35 };
     36 
     37 struct TrivialCopyStruct {
     38   TrivialCopyStruct() : member(0) {}
     39   TrivialCopyStruct(TrivialCopyStruct const&) : member(1) {}
     40 
     41   int member;
     42 };
     43 
     44 struct TrivialInitStruct {
     45   TrivialInitStruct()
     46   { ++nbConstructorCalls; }
     47 
     48   static size_t nbConstructorCalls;
     49 };
     50 
     51 size_t TrivialInitStruct::nbConstructorCalls = 0;
     52 
     53 #if defined (STLPORT)
     54 #  if defined (_STLP_USE_NAMESPACES)
     55 namespace std {
     56 #  endif
     57   _STLP_TEMPLATE_NULL
     58   struct __type_traits<TrivialCopyStruct> {
     59      typedef __false_type has_trivial_default_constructor;
     60      //This is a wrong declaration just to check that internaly a simple memcpy is called:
     61      typedef __true_type has_trivial_copy_constructor;
     62      typedef __true_type has_trivial_assignment_operator;
     63      typedef __true_type has_trivial_destructor;
     64      typedef __false_type is_POD_type;
     65   };
     66 
     67   _STLP_TEMPLATE_NULL
     68   struct __type_traits<TrivialInitStruct> {
     69      //This is a wrong declaration just to check that internaly no initialization is done:
     70      typedef __true_type has_trivial_default_constructor;
     71      typedef __true_type has_trivial_copy_constructor;
     72      typedef __true_type has_trivial_assignment_operator;
     73      typedef __true_type has_trivial_destructor;
     74      typedef __false_type is_POD_type;
     75   };
     76 #  if defined (_STLP_USE_NAMESPACES)
     77 }
     78 #  endif
     79 #endif
     80 
     81 struct base {};
     82 struct derived : public base {};
     83 
     84 //
     85 // tests implementation
     86 //
     87 void UninitializedTest::copy_test()
     88 {
     89   {
     90     //Random iterators
     91     {
     92       vector<NotTrivialCopyStruct> src(10);
     93       vector<NotTrivialCopyStruct> dst(10);
     94       uninitialized_copy(src.begin(), src.end(), dst.begin());
     95       vector<NotTrivialCopyStruct>::const_iterator it(dst.begin()), end(dst.end());
     96       for (; it != end; ++it) {
     97         CPPUNIT_ASSERT( (*it).member == 1 );
     98       }
     99     }
    100     {
    101       /** Note: we use static arrays here so the iterators are always
    102       pointers, even in debug mode. */
    103       size_t const count = 10;
    104       TrivialCopyStruct src[count];
    105       TrivialCopyStruct dst[count];
    106 
    107       TrivialCopyStruct* it = src + 0;
    108       TrivialCopyStruct* end = src + count;
    109       for (; it != end; ++it) {
    110         (*it).member = 0;
    111       }
    112 
    113       uninitialized_copy(src+0, src+count, dst+0);
    114       for (it = dst+0, end = dst+count; it != end; ++it) {
    115 #if defined (STLPORT)
    116         /* If the member is 1, it means that library has not found any
    117         optimization oportunity and called the regular copy-ctor instead. */
    118         CPPUNIT_ASSERT( (*it).member == 0 );
    119 #else
    120         CPPUNIT_ASSERT( (*it).member == 1 );
    121 #endif
    122       }
    123     }
    124   }
    125 
    126   {
    127     //Bidirectional iterator
    128     {
    129       vector<NotTrivialCopyStruct> src(10);
    130       list<NotTrivialCopyStruct> dst(10);
    131 
    132       list<NotTrivialCopyStruct>::iterator it(dst.begin()), end(dst.end());
    133       for (; it != end; ++it) {
    134         (*it).member = -1;
    135       }
    136 
    137       uninitialized_copy(src.begin(), src.end(), dst.begin());
    138 
    139       for (it = dst.begin(); it != end; ++it) {
    140         CPPUNIT_ASSERT( (*it).member == 1 );
    141       }
    142     }
    143 
    144     {
    145       list<NotTrivialCopyStruct> src(10);
    146       vector<NotTrivialCopyStruct> dst(10);
    147 
    148       vector<NotTrivialCopyStruct>::iterator it(dst.begin()), end(dst.end());
    149       for (; it != end; ++it) {
    150         (*it).member = -1;
    151       }
    152 
    153       uninitialized_copy(src.begin(), src.end(), dst.begin());
    154 
    155       for (it = dst.begin(); it != end; ++it) {
    156         CPPUNIT_ASSERT( (*it).member == 1 );
    157       }
    158     }
    159   }
    160 
    161   {
    162     //Using containers of native types:
    163 #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
    164     {
    165       vector<int> src;
    166       int i;
    167       for (i = -5; i < 6; ++i) {
    168         src.push_back(i);
    169       }
    170 
    171       //Building a vector result in a uninitialized_copy call internally
    172       vector<unsigned int> dst(src.begin(), src.end());
    173       vector<unsigned int>::const_iterator it(dst.begin());
    174       for (i = -5; i < 6; ++i, ++it) {
    175         CPPUNIT_ASSERT( *it == (unsigned int)i );
    176       }
    177     }
    178 
    179     {
    180       vector<char> src;
    181       char i;
    182       for (i = -5; i < 6; ++i) {
    183         src.push_back(i);
    184       }
    185 
    186       //Building a vector result in a uninitialized_copy call internally
    187       vector<unsigned int> dst(src.begin(), src.end());
    188       vector<unsigned int>::const_iterator it(dst.begin());
    189       for (i = -5; i < 6; ++i, ++it) {
    190         CPPUNIT_ASSERT( *it == (unsigned int)i );
    191       }
    192     }
    193 
    194     {
    195       vector<int> src;
    196       int i;
    197       for (i = -5; i < 6; ++i) {
    198         src.push_back(i);
    199       }
    200 
    201       //Building a vector result in a uninitialized_copy call internally
    202       vector<float> dst(src.begin(), src.end());
    203       vector<float>::const_iterator it(dst.begin());
    204       for (i = -5; i < 6; ++i, ++it) {
    205         CPPUNIT_ASSERT( *it == (float)i );
    206       }
    207     }
    208 
    209     {
    210       vector<vector<float>*> src(10);
    211       vector<vector<float>*> dst(src.begin(), src.end());
    212     }
    213 
    214     {
    215       derived d;
    216       //base *pb = &d;
    217       derived *pd = &d;
    218       //base **ppb = &pd;
    219       vector<derived*> src(10, pd);
    220       vector<base*> dst(src.begin(), src.end());
    221       vector<base*>::iterator it(dst.begin()), end(dst.end());
    222       for (; it != end; ++it) {
    223         CPPUNIT_ASSERT( (*it) == pd );
    224       }
    225     }
    226 #endif
    227   }
    228 
    229   {
    230     //Vector initialization:
    231     vector<TrivialInitStruct> vect(10);
    232     //Just 1 constructor call for the default value:
    233     CPPUNIT_ASSERT( TrivialInitStruct::nbConstructorCalls == 1  );
    234   }
    235 }
    236 
    237 /*
    238 void UninitializedTest::fill_test()
    239 {
    240 }
    241 
    242 void UninitializedTest::fill_n_test()
    243 {
    244 }
    245 */
    246