Home | History | Annotate | Download | only in unit
      1 #include <vector>
      2 #include <algorithm>
      3 #include <string>
      4 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
      5 #  include <rope>
      6 #endif
      7 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
      8 #  include <slist>
      9 #endif
     10 #include <list>
     11 #include <deque>
     12 #include <set>
     13 #include <map>
     14 #if defined (STLPORT)
     15 #  include <unordered_set>
     16 #  include <unordered_map>
     17 #endif
     18 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
     19 #  include <hash_set>
     20 #  include <hash_map>
     21 #endif
     22 #include <queue>
     23 #include <stack>
     24 
     25 #include "mvctor_test.h"
     26 
     27 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     28 using namespace std;
     29 #  if defined (STLPORT)
     30 using namespace std::tr1;
     31 #  endif
     32 #endif
     33 
     34 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
     35 
     36 #  if defined (__GNUC__) && defined (_STLP_USE_NAMESPACES)
     37 // libstdc++ sometimes exposed its own __true_type in
     38 // global namespace resulting in an ambiguity.
     39 #    define __true_type std::__true_type
     40 #    define __false_type std::__false_type
     41 #  endif
     42 
     43 static bool type_to_bool(__true_type)
     44 { return true; }
     45 static bool type_to_bool(__false_type)
     46 { return false; }
     47 
     48 template <class _Tp>
     49 static bool is_movable(const _Tp&) {
     50   typedef typename __move_traits<_Tp>::implemented _MovableTp;
     51   return type_to_bool(_MovableTp());
     52 }
     53 
     54 template <class _Tp>
     55 static bool is_move_complete(const _Tp&) {
     56   typedef __move_traits<_Tp> _TpMoveTraits;
     57   typedef typename _TpMoveTraits::complete _TpMoveComplete;
     58   return type_to_bool(_TpMoveComplete());
     59 }
     60 
     61 struct specially_allocated_struct {
     62   bool operator < (const specially_allocated_struct&) const;
     63 #  if defined (__DMC__) // slist<_Tp,_Alloc>::remove error
     64   bool operator==(const specially_allocated_struct&) const;
     65 #  endif
     66 };
     67 
     68 #if defined (__DMC__)
     69 bool specially_allocated_struct::operator < (const specially_allocated_struct&) const
     70 { return false; }
     71 #endif
     72 
     73 struct struct_with_specialized_less {};
     74 
     75 #  if defined (_STLP_USE_NAMESPACES)
     76 namespace std {
     77 #  endif
     78   _STLP_TEMPLATE_NULL
     79   class allocator<specially_allocated_struct> {
     80     //This allocator just represent what a STLport could do and in this
     81     //case the STL containers implemented with it should still be movable
     82     //but not completely as we cannot do any hypothesis on what is in this
     83     //allocator.
     84   public:
     85     typedef specially_allocated_struct value_type;
     86     typedef value_type *       pointer;
     87     typedef const value_type* const_pointer;
     88     typedef value_type&       reference;
     89     typedef const value_type& const_reference;
     90     typedef size_t     size_type;
     91     typedef ptrdiff_t  difference_type;
     92 #  if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
     93     template <class _Tp1> struct rebind {
     94       typedef allocator<_Tp1> other;
     95     };
     96 #  endif
     97     allocator() _STLP_NOTHROW {}
     98 #  if defined (_STLP_MEMBER_TEMPLATES)
     99     template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
    100 #  endif
    101     allocator(const allocator&) _STLP_NOTHROW {}
    102     ~allocator() _STLP_NOTHROW {}
    103     pointer address(reference __x) const { return &__x; }
    104     const_pointer address(const_reference __x) const { return &__x; }
    105     pointer allocate(size_type, const void* = 0) { return 0; }
    106     void deallocate(pointer, size_type) {}
    107     size_type max_size() const _STLP_NOTHROW  { return 0; }
    108     void construct(pointer, const_reference) {}
    109     void destroy(pointer) {}
    110   };
    111 
    112   _STLP_TEMPLATE_NULL
    113   struct less<struct_with_specialized_less> {
    114     bool operator() (struct_with_specialized_less const&,
    115                      struct_with_specialized_less const&) const;
    116   };
    117 
    118 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    119 #    if !defined (_STLP_NO_MOVE_SEMANTIC)
    120 #      if defined (__BORLANDC__) && (__BORLANDC__ >= 0x564)
    121   _STLP_TEMPLATE_NULL
    122   struct __move_traits<vector<specially_allocated_struct> > {
    123     typedef __true_type implemented;
    124     typedef __false_type complete;
    125   };
    126   _STLP_TEMPLATE_NULL
    127   struct __move_traits<deque<specially_allocated_struct> > {
    128     typedef __true_type implemented;
    129     typedef __false_type complete;
    130   };
    131   _STLP_TEMPLATE_NULL
    132   struct __move_traits<list<specially_allocated_struct> > {
    133     typedef __true_type implemented;
    134     typedef __false_type complete;
    135   };
    136   _STLP_TEMPLATE_NULL
    137   struct __move_traits<slist<specially_allocated_struct> > {
    138     typedef __true_type implemented;
    139     typedef __false_type complete;
    140   };
    141   _STLP_TEMPLATE_NULL
    142   struct __move_traits<less<struct_with_specialized_less> > {
    143     typedef __true_type implemented;
    144     typedef __false_type complete;
    145   };
    146   _STLP_TEMPLATE_NULL
    147   struct __move_traits<set<specially_allocated_struct> > {
    148     typedef __true_type implemented;
    149     typedef __false_type complete;
    150   };
    151   _STLP_TEMPLATE_NULL
    152   struct __move_traits<multiset<specially_allocated_struct> > {
    153     typedef __true_type implemented;
    154     typedef __false_type complete;
    155   };
    156 #      endif
    157 #    endif
    158 #  endif
    159 
    160 #  if defined (_STLP_USE_NAMESPACES)
    161 }
    162 #  endif
    163 #endif
    164 
    165 void MoveConstructorTest::movable_declaration()
    166 {
    167 #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
    168                          !defined (_STLP_NO_MOVE_SEMANTIC)
    169   //This test purpose is to check correct detection of the STL movable
    170   //traits declaration
    171   {
    172     //string, wstring:
    173     CPPUNIT_ASSERT( is_movable(string()) );
    174 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    175     CPPUNIT_ASSERT( is_move_complete(string()) );
    176 #  else
    177     CPPUNIT_ASSERT( !is_move_complete(string()) );
    178 #  endif
    179 #  if defined (_STLP_HAS_WCHAR_T)
    180     CPPUNIT_ASSERT( is_movable(wstring()) );
    181 #    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    182     CPPUNIT_ASSERT( is_move_complete(wstring()) );
    183 #    else
    184     CPPUNIT_ASSERT( !is_move_complete(wstring()) );
    185 #    endif
    186 #  endif
    187   }
    188 
    189 #  if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
    190   {
    191     //crope, wrope:
    192     CPPUNIT_ASSERT( is_movable(crope()) );
    193 #    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    194     CPPUNIT_ASSERT( is_move_complete(crope()) );
    195 #    else
    196     CPPUNIT_ASSERT( !is_move_complete(crope()) );
    197 #    endif
    198 #    if defined (_STLP_HAS_WCHAR_T)
    199     CPPUNIT_ASSERT( is_movable(wrope()) );
    200 #      if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    201     CPPUNIT_ASSERT( is_move_complete(wrope()) );
    202 #      else
    203     CPPUNIT_ASSERT( !is_move_complete(wrope()) );
    204 #      endif
    205 #    endif
    206   }
    207 #  endif
    208 
    209   {
    210     //vector:
    211     CPPUNIT_ASSERT( is_movable(vector<char>()) );
    212     CPPUNIT_ASSERT( is_movable(vector<specially_allocated_struct>()) );
    213 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    214     CPPUNIT_ASSERT( is_move_complete(vector<char>()) );
    215     CPPUNIT_ASSERT( !is_move_complete(vector<specially_allocated_struct>()) );
    216 #  else
    217     CPPUNIT_ASSERT( !is_move_complete(vector<char>()) );
    218 #  endif
    219   }
    220 
    221   {
    222     //deque:
    223     CPPUNIT_ASSERT( is_movable(deque<char>()) );
    224     CPPUNIT_ASSERT( is_movable(deque<specially_allocated_struct>()) );
    225 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    226     CPPUNIT_ASSERT( is_move_complete(deque<char>()) );
    227     CPPUNIT_ASSERT( !is_move_complete(deque<specially_allocated_struct>()) );
    228 #  else
    229     CPPUNIT_ASSERT( !is_move_complete(deque<char>()) );
    230 #  endif
    231   }
    232 
    233   {
    234     //list:
    235     CPPUNIT_ASSERT( is_movable(list<char>()) );
    236     CPPUNIT_ASSERT( is_movable(list<specially_allocated_struct>()) );
    237 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    238     CPPUNIT_ASSERT( is_move_complete(list<char>()) );
    239     CPPUNIT_ASSERT( !is_move_complete(list<specially_allocated_struct>()) );
    240 #  else
    241     CPPUNIT_ASSERT( !is_move_complete(list<char>()) );
    242 #  endif
    243   }
    244 
    245 #  if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
    246   {
    247     //slist:
    248     CPPUNIT_ASSERT( is_movable(slist<char>()) );
    249     CPPUNIT_ASSERT( is_movable(slist<specially_allocated_struct>()) );
    250 #    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    251     CPPUNIT_ASSERT( is_move_complete(slist<char>()) );
    252     CPPUNIT_ASSERT( !is_move_complete(slist<specially_allocated_struct>()) );
    253 #    else
    254     CPPUNIT_ASSERT( !is_move_complete(slist<char>()) );
    255 #    endif
    256   }
    257 #  endif
    258 
    259   {
    260     //queue:
    261     CPPUNIT_ASSERT( is_movable(queue<char>()) );
    262     CPPUNIT_ASSERT( is_movable(queue<specially_allocated_struct>()) );
    263 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    264     CPPUNIT_ASSERT( is_move_complete(queue<char>()) );
    265     CPPUNIT_ASSERT( !is_move_complete(queue<specially_allocated_struct>()) );
    266 #  else
    267     CPPUNIT_ASSERT( !is_move_complete(queue<char>()) );
    268 #  endif
    269   }
    270 
    271   {
    272     //stack:
    273     CPPUNIT_ASSERT( is_movable(stack<char>()) );
    274     CPPUNIT_ASSERT( is_movable(stack<specially_allocated_struct>()) );
    275 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    276     CPPUNIT_ASSERT( is_move_complete(stack<char>()) );
    277     CPPUNIT_ASSERT( !is_move_complete(stack<specially_allocated_struct>()) );
    278 #  else
    279     CPPUNIT_ASSERT( !is_move_complete(stack<char>()) );
    280 #  endif
    281   }
    282 
    283 #endif
    284 }
    285 
    286 void MoveConstructorTest::movable_declaration_assoc()
    287 {
    288 #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
    289                          !defined (_STLP_NO_MOVE_SEMANTIC)
    290   {
    291     //associative containers, set multiset, map, multimap:
    292 
    293     //For associative containers it is important that less is correctly recognize as
    294     //the STLport less or a user specialized less:
    295 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    296     CPPUNIT_ASSERT( is_move_complete(less<char>()) );
    297 #  endif
    298     CPPUNIT_ASSERT( !is_move_complete(less<struct_with_specialized_less>()) );
    299 
    300     //set
    301     CPPUNIT_ASSERT( is_movable(set<char>()) );
    302     CPPUNIT_ASSERT( is_movable(set<specially_allocated_struct>()) );
    303 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    304     CPPUNIT_ASSERT( is_move_complete(set<char>()) );
    305     CPPUNIT_ASSERT( !is_move_complete(set<specially_allocated_struct>()) );
    306 #  else
    307     CPPUNIT_ASSERT( !is_move_complete(set<char>()) );
    308 #  endif
    309 
    310     //multiset
    311     CPPUNIT_ASSERT( is_movable(multiset<char>()) );
    312     CPPUNIT_ASSERT( is_movable(multiset<specially_allocated_struct>()) );
    313 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    314     CPPUNIT_ASSERT( is_move_complete(multiset<char>()) );
    315     CPPUNIT_ASSERT( !is_move_complete(multiset<specially_allocated_struct>()) );
    316 #  else
    317     CPPUNIT_ASSERT( !is_move_complete(multiset<char>()) );
    318 #  endif
    319 
    320     //map
    321     CPPUNIT_ASSERT( is_movable(map<char, char>()) );
    322     CPPUNIT_ASSERT( is_movable(map<specially_allocated_struct, char>()) );
    323 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    324     CPPUNIT_ASSERT( is_move_complete(map<char, char>()) );
    325     //Here even if allocator has been specialized for specially_allocated_struct
    326     //this pecialization won't be used in default map instanciation as the default
    327     //allocator is allocator<pair<specially_allocated_struct, char> >
    328     CPPUNIT_ASSERT( is_move_complete(map<specially_allocated_struct, char>()) );
    329 #  else
    330     CPPUNIT_ASSERT( !is_move_complete(map<char, char>()) );
    331 #  endif
    332 
    333     //multimap
    334     CPPUNIT_ASSERT( is_movable(multimap<char, char>()) );
    335     CPPUNIT_ASSERT( is_movable(multimap<specially_allocated_struct, char>()) );
    336 #  if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
    337     CPPUNIT_ASSERT( is_move_complete(multimap<char, char>()) );
    338     //Idem map remark
    339     CPPUNIT_ASSERT( is_move_complete(multimap<specially_allocated_struct, char>()) );
    340 #  else
    341     CPPUNIT_ASSERT( !is_move_complete(multimap<char, char>()) );
    342 #  endif
    343   }
    344 #endif
    345 }
    346 
    347 void MoveConstructorTest::movable_declaration_hash()
    348 {
    349 #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
    350                          !defined (_STLP_NO_MOVE_SEMANTIC)
    351   {
    352     //hashed containers, unordered_set unordered_multiset, unordered_map, unordered_multimap,
    353     //                   hash_set, hash_multiset, hash_map, hash_multimap:
    354 
    355     //We only check that they are movable, completness is not yet supported
    356     CPPUNIT_ASSERT( is_movable(unordered_set<char>()) );
    357     CPPUNIT_ASSERT( is_movable(unordered_multiset<char>()) );
    358     CPPUNIT_ASSERT( is_movable(unordered_map<char, char>()) );
    359     CPPUNIT_ASSERT( is_movable(unordered_multimap<char, char>()) );
    360 #  if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
    361     CPPUNIT_ASSERT( is_movable(hash_set<char>()) );
    362     CPPUNIT_ASSERT( is_movable(hash_multiset<char>()) );
    363     CPPUNIT_ASSERT( is_movable(hash_map<char, char>()) );
    364     CPPUNIT_ASSERT( is_movable(hash_multimap<char, char>()) );
    365 #  endif
    366   }
    367 #endif
    368 }
    369 
    370