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