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) 28using namespace std; 29# if defined (STLPORT) 30using 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 43static bool type_to_bool(__true_type) 44{ return true; } 45static bool type_to_bool(__false_type) 46{ return false; } 47 48template <class _Tp> 49static bool is_movable(const _Tp&) { 50 typedef typename __move_traits<_Tp>::implemented _MovableTp; 51 return type_to_bool(_MovableTp()); 52} 53 54template <class _Tp> 55static 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 61struct 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__) 69bool specially_allocated_struct::operator < (const specially_allocated_struct&) const 70{ return false; } 71#endif 72 73struct struct_with_specialized_less {}; 74 75# if defined (_STLP_USE_NAMESPACES) 76namespace 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 165void 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 286void 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 347void 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