1 #include <vector> 2 #include <algorithm> 3 #include <string> 4 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 5 # include <slist> 6 #endif 7 #include <list> 8 #include <deque> 9 #include <set> 10 #if defined (STLPORT) 11 # include <unordered_set> 12 #endif 13 14 #include "mvctor_test.h" 15 16 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) 17 using namespace std; 18 # if defined (STLPORT) 19 using namespace std::tr1; 20 # endif 21 #endif 22 23 CPPUNIT_TEST_SUITE_REGISTRATION(MoveConstructorTest); 24 25 // 26 // tests implementation 27 // 28 void MoveConstructorTest::move_construct_test() 29 { 30 //cout << "vector<vector<int>>"; 31 vector<int> const ref_vec(10, 0); 32 vector<vector<int> > v_v_ints(1, ref_vec); 33 34 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 35 int *pint = &(v_v_ints.front().front()); 36 #endif 37 38 size_t cur_capacity = v_v_ints.capacity(); 39 while (v_v_ints.capacity() <= cur_capacity) { 40 v_v_ints.push_back(ref_vec); 41 } 42 43 //v_v_ints has been resized 44 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 45 CPPUNIT_ASSERT((pint == &v_v_ints.front().front())); 46 #endif 47 48 //cout << "vector<vector<int>>::erase"; 49 //We need at least 3 elements: 50 while (v_v_ints.size() < 3) { 51 v_v_ints.push_back(ref_vec); 52 } 53 54 //We erase the 2nd 55 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 56 pint = &v_v_ints[2].front(); 57 #endif 58 v_v_ints.erase(v_v_ints.begin() + 1); 59 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 60 CPPUNIT_ASSERT((pint == &v_v_ints[1].front())); 61 #endif 62 63 //cout << "vector<string>"; 64 string const ref_str("ref string, big enough to be a dynamic one"); 65 vector<string> vec_strs(1, ref_str); 66 67 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 68 char const* pstr = vec_strs.front().c_str(); 69 #endif 70 cur_capacity = vec_strs.capacity(); 71 while (vec_strs.capacity() <= cur_capacity) { 72 vec_strs.push_back(ref_str); 73 } 74 75 //vec_str has been resized 76 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 77 CPPUNIT_ASSERT((pstr == vec_strs.front().c_str())); 78 #endif 79 80 //cout << "vector<string>::erase"; 81 //We need at least 3 elements: 82 while (vec_strs.size() < 3) { 83 vec_strs.push_back(ref_str); 84 } 85 86 //We erase the 2nd 87 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 88 pstr = vec_strs[2].c_str(); 89 #endif 90 vec_strs.erase(vec_strs.begin() + 1); 91 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 92 CPPUNIT_ASSERT((pstr == vec_strs[1].c_str())); 93 #endif 94 95 //cout << "swap(vector<int>, vector<int>)"; 96 vector<int> elem1(10, 0), elem2(10, 0); 97 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 98 int *p1 = &elem1.front(); 99 int *p2 = &elem2.front(); 100 #endif 101 swap(elem1, elem2); 102 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 103 CPPUNIT_ASSERT(((p1 == &elem2.front()) && (p2 == &elem1.front()))); 104 #endif 105 106 { 107 vector<bool> bit_vec(5, true); 108 bit_vec.insert(bit_vec.end(), 5, false); 109 vector<vector<bool> > v_v_bits(1, bit_vec); 110 111 /* 112 * This is a STLport specific test as we are using internal implementation 113 * details to check that the move has been correctly handled. For other 114 * STL implementation it is only a compile check. 115 */ 116 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 117 # if defined (_STLP_DEBUG) 118 unsigned int *punit = v_v_bits.front().begin()._M_iterator._M_p; 119 # else 120 unsigned int *punit = v_v_bits.front().begin()._M_p; 121 # endif 122 #endif 123 124 cur_capacity = v_v_bits.capacity(); 125 while (v_v_bits.capacity() <= cur_capacity) { 126 v_v_bits.push_back(bit_vec); 127 } 128 129 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 130 //v_v_bits has been resized 131 # if defined (_STLP_DEBUG) 132 CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_iterator._M_p ); 133 # else 134 CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_p ); 135 # endif 136 #endif 137 } 138 139 // zero: don't like this kind of tests 140 // because of template test function 141 // we should find another way to provide 142 // move constructor testing... 143 144 /* 145 standard_test1(list<int>(10)); 146 147 148 standard_test1(slist<int>(10)); 149 150 standard_test1(deque<int>(10)); 151 */ 152 153 /* 154 int int_values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 155 156 set<int> int_set(int_values, int_values + sizeof(in_values) / sizeof(int)); 157 standard_test1(int_set); 158 159 multiset<int> int_multiset(int_values, int_values + sizeof(in_values) / sizeof(int)); 160 standard_test1(int_multiset); 161 */ 162 163 /* 164 CheckFullMoveSupport(string()); 165 CheckFullMoveSupport(vector<int>()); 166 CheckFullMoveSupport(deque<int>()); 167 CheckFullMoveSupport(list<int>()); 168 CheckFullMoveSupport(slist<int>()); 169 */ 170 } 171 172 void MoveConstructorTest::deque_test() 173 { 174 //Check the insert range method. 175 //To the front: 176 { 177 # if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES) 178 deque<vector<int> > vect_deque; 179 vector<int*> bufs; 180 vect_deque.assign(3, vector<int>(10)); 181 bufs.push_back(&vect_deque[0].front()); 182 bufs.push_back(&vect_deque[1].front()); 183 bufs.push_back(&vect_deque[2].front()); 184 185 int nb_insert = 5; 186 //Initialize to 1 to generate a front insertion: 187 int pos = 1; 188 while (nb_insert--) { 189 vector<vector<int> > vect_vect(2, vector<int>(10)); 190 vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end()); 191 bufs.insert(bufs.begin() + pos, &vect_deque[pos].front()); 192 bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front()); 193 ++pos; 194 } 195 CPPUNIT_ASSERT( vect_deque.size() == 13 ); 196 # if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 197 for (int i = 0; i < 5; ++i) { 198 CPPUNIT_ASSERT( bufs[i] == &vect_deque[i].front() ); 199 CPPUNIT_ASSERT( bufs[11 - i] == &vect_deque[11 - i].front() ); 200 } 201 # endif 202 # endif 203 } 204 205 //To the back 206 { 207 # if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES) 208 deque<vector<int> > vect_deque; 209 vector<int*> bufs; 210 vect_deque.assign(3, vector<int>(10)); 211 bufs.push_back(&vect_deque[0].front()); 212 bufs.push_back(&vect_deque[1].front()); 213 bufs.push_back(&vect_deque[2].front()); 214 215 int nb_insert = 5; 216 //Initialize to 2 to generate a back insertion: 217 int pos = 2; 218 while (nb_insert--) { 219 vector<vector<int> > vect_vect(2, vector<int>(10)); 220 vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end()); 221 bufs.insert(bufs.begin() + pos, &vect_deque[pos].front()); 222 bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front()); 223 ++pos; 224 } 225 CPPUNIT_ASSERT( vect_deque.size() == 13 ); 226 # if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 227 for (int i = 0; i < 5; ++i) { 228 CPPUNIT_ASSERT( bufs[i + 1] == &vect_deque[i + 1].front() ); 229 CPPUNIT_ASSERT( bufs[12 - i] == &vect_deque[12 - i].front() ); 230 } 231 # endif 232 # endif 233 } 234 235 //Check the different erase methods. 236 { 237 deque<vector<int> > vect_deque; 238 vect_deque.assign(20, vector<int>(10)); 239 deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end()); 240 vector<int*> bufs; 241 for (; vdit != vditEnd; ++vdit) { 242 bufs.push_back(&vdit->front()); 243 } 244 245 { 246 // This check, repeated after each operation, check the deque consistency: 247 deque<vector<int> >::iterator it = vect_deque.end() - 5; 248 int nb_incr = 0; 249 for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {} 250 CPPUNIT_ASSERT( nb_incr == 5 ); 251 } 252 253 { 254 //erase in front: 255 vect_deque.erase(vect_deque.begin() + 2); 256 bufs.erase(bufs.begin() + 2); 257 CPPUNIT_ASSERT( vect_deque.size() == 19 ); 258 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end()); 259 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 260 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 261 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 262 } 263 #endif 264 } 265 266 { 267 deque<vector<int> >::iterator it = vect_deque.end() - 5; 268 int nb_incr = 0; 269 for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {} 270 CPPUNIT_ASSERT( nb_incr == 5 ); 271 } 272 273 { 274 //erase in the back: 275 vect_deque.erase(vect_deque.end() - 2); 276 bufs.erase(bufs.end() - 2); 277 CPPUNIT_ASSERT( vect_deque.size() == 18 ); 278 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end()); 279 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 280 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 281 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 282 } 283 #endif 284 } 285 286 { 287 deque<vector<int> >::iterator it = vect_deque.end() - 5; 288 int nb_incr = 0; 289 for (; it != vect_deque.end() && nb_incr < 6; ++nb_incr, ++it) {} 290 CPPUNIT_ASSERT( nb_incr == 5 ); 291 } 292 293 { 294 //range erase in front 295 vect_deque.erase(vect_deque.begin() + 3, vect_deque.begin() + 5); 296 bufs.erase(bufs.begin() + 3, bufs.begin() + 5); 297 CPPUNIT_ASSERT( vect_deque.size() == 16 ); 298 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end()); 299 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 300 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 301 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 302 } 303 #endif 304 } 305 306 { 307 deque<vector<int> >::iterator it = vect_deque.end() - 5; 308 int nb_incr = 0; 309 for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {} 310 CPPUNIT_ASSERT( nb_incr == 5 ); 311 } 312 313 { 314 //range erase in back 315 vect_deque.erase(vect_deque.end() - 5, vect_deque.end() - 3); 316 bufs.erase(bufs.end() - 5, bufs.end() - 3); 317 CPPUNIT_ASSERT( vect_deque.size() == 14 ); 318 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end()); 319 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 320 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 321 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 322 } 323 #endif 324 } 325 } 326 327 //Check the insert value(s) 328 { 329 deque<vector<int> > vect_deque; 330 vect_deque.assign(20, vector<int>(10)); 331 deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end()); 332 vector<int*> bufs; 333 for (; vdit != vditEnd; ++vdit) { 334 bufs.push_back(&vdit->front()); 335 } 336 337 { 338 //2 values in front: 339 vect_deque.insert(vect_deque.begin() + 2, 2, vector<int>(10)); 340 bufs.insert(bufs.begin() + 2, &vect_deque[2].front()); 341 bufs.insert(bufs.begin() + 3, &vect_deque[3].front()); 342 CPPUNIT_ASSERT( vect_deque.size() == 22 ); 343 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end()); 344 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 345 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 346 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 347 } 348 #endif 349 } 350 351 { 352 //2 values in back: 353 vect_deque.insert(vect_deque.end() - 2, 2, vector<int>(10)); 354 bufs.insert(bufs.end() - 2, &vect_deque[20].front()); 355 bufs.insert(bufs.end() - 2, &vect_deque[21].front()); 356 CPPUNIT_ASSERT( vect_deque.size() == 24 ); 357 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 358 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end()); 359 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 360 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 361 } 362 #endif 363 } 364 365 { 366 //1 value in front: 367 deque<vector<int> >::iterator ret; 368 ret = vect_deque.insert(vect_deque.begin() + 2, vector<int>(10)); 369 bufs.insert(bufs.begin() + 2, &vect_deque[2].front()); 370 CPPUNIT_ASSERT( vect_deque.size() == 25 ); 371 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 372 CPPUNIT_ASSERT( &ret->front() == bufs[2] ); 373 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end()); 374 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 375 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 376 } 377 #endif 378 } 379 380 { 381 //1 value in back: 382 deque<vector<int> >::iterator ret; 383 ret = vect_deque.insert(vect_deque.end() - 2, vector<int>(10)); 384 bufs.insert(bufs.end() - 2, &vect_deque[23].front()); 385 CPPUNIT_ASSERT( vect_deque.size() == 26 ); 386 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 387 CPPUNIT_ASSERT( &ret->front() == bufs[23] ); 388 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end()); 389 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 390 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 391 } 392 #endif 393 } 394 } 395 } 396 397 void MoveConstructorTest::vector_test() 398 { 399 //Check the insert range method. 400 //To the front: 401 { 402 vector<vector<int> > vect_vector; 403 vector<int*> bufs; 404 vect_vector.assign(3, vector<int>(10)); 405 bufs.push_back(&vect_vector[0].front()); 406 bufs.push_back(&vect_vector[1].front()); 407 bufs.push_back(&vect_vector[2].front()); 408 409 int nb_insert = 5; 410 int pos = 1; 411 while (nb_insert--) { 412 vector<vector<int> > vect_vect(2, vector<int>(10)); 413 vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end()); 414 bufs.insert(bufs.begin() + pos, &vect_vector[pos].front()); 415 bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front()); 416 ++pos; 417 } 418 CPPUNIT_ASSERT( vect_vector.size() == 13 ); 419 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 420 for (int i = 0; i < 5; ++i) { 421 CPPUNIT_ASSERT( bufs[i] == &vect_vector[i].front() ); 422 CPPUNIT_ASSERT( bufs[11 - i] == &vect_vector[11 - i].front() ); 423 } 424 #endif 425 } 426 427 //To the back 428 { 429 vector<vector<int> > vect_vector; 430 vector<int*> bufs; 431 vect_vector.assign(3, vector<int>(10)); 432 bufs.push_back(&vect_vector[0].front()); 433 bufs.push_back(&vect_vector[1].front()); 434 bufs.push_back(&vect_vector[2].front()); 435 436 int nb_insert = 5; 437 //Initialize to 2 to generate a back insertion: 438 int pos = 2; 439 while (nb_insert--) { 440 vector<vector<int> > vect_vect(2, vector<int>(10)); 441 vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end()); 442 bufs.insert(bufs.begin() + pos, &vect_vector[pos].front()); 443 bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front()); 444 ++pos; 445 } 446 CPPUNIT_ASSERT( vect_vector.size() == 13 ); 447 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 448 for (int i = 0; i < 5; ++i) { 449 CPPUNIT_ASSERT( bufs[i + 1] == &vect_vector[i + 1].front() ); 450 CPPUNIT_ASSERT( bufs[12 - i] == &vect_vector[12 - i].front() ); 451 } 452 #endif 453 } 454 455 //Check the different erase methods. 456 { 457 vector<vector<int> > vect_vector; 458 vect_vector.assign(20, vector<int>(10)); 459 vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end()); 460 vector<int*> bufs; 461 for (; vdit != vditEnd; ++vdit) { 462 bufs.push_back(&vdit->front()); 463 } 464 465 { 466 // This check, repeated after each operation, check the vector consistency: 467 vector<vector<int> >::iterator it = vect_vector.end() - 5; 468 int nb_incr = 0; 469 for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {} 470 CPPUNIT_ASSERT( nb_incr == 5 ); 471 } 472 473 { 474 //erase in front: 475 vect_vector.erase(vect_vector.begin() + 2); 476 bufs.erase(bufs.begin() + 2); 477 CPPUNIT_ASSERT( vect_vector.size() == 19 ); 478 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 479 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end()); 480 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 481 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 482 } 483 #endif 484 } 485 486 { 487 vector<vector<int> >::iterator it = vect_vector.end() - 5; 488 int nb_incr = 0; 489 for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {} 490 CPPUNIT_ASSERT( nb_incr == 5 ); 491 } 492 493 { 494 //erase in the back: 495 vect_vector.erase(vect_vector.end() - 2); 496 bufs.erase(bufs.end() - 2); 497 CPPUNIT_ASSERT( vect_vector.size() == 18 ); 498 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 499 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end()); 500 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 501 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 502 } 503 #endif 504 } 505 506 { 507 vector<vector<int> >::iterator it = vect_vector.end() - 5; 508 int nb_incr = 0; 509 for (; it != vect_vector.end() && nb_incr < 6; ++nb_incr, ++it) {} 510 CPPUNIT_ASSERT( nb_incr == 5 ); 511 } 512 513 { 514 //range erase in front 515 vect_vector.erase(vect_vector.begin() + 3, vect_vector.begin() + 5); 516 bufs.erase(bufs.begin() + 3, bufs.begin() + 5); 517 CPPUNIT_ASSERT( vect_vector.size() == 16 ); 518 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 519 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end()); 520 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 521 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 522 } 523 #endif 524 } 525 526 { 527 vector<vector<int> >::iterator it = vect_vector.end() - 5; 528 int nb_incr = 0; 529 for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {} 530 CPPUNIT_ASSERT( nb_incr == 5 ); 531 } 532 533 { 534 //range erase in back 535 vect_vector.erase(vect_vector.end() - 5, vect_vector.end() - 3); 536 bufs.erase(bufs.end() - 5, bufs.end() - 3); 537 CPPUNIT_ASSERT( vect_vector.size() == 14 ); 538 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 539 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end()); 540 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 541 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 542 } 543 #endif 544 } 545 } 546 547 //Check the insert value(s) 548 { 549 vector<vector<int> > vect_vector; 550 vect_vector.assign(20, vector<int>(10)); 551 vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end()); 552 vector<int*> bufs; 553 for (; vdit != vditEnd; ++vdit) { 554 bufs.push_back(&vdit->front()); 555 } 556 557 { 558 //2 values in front: 559 vect_vector.insert(vect_vector.begin() + 2, 2, vector<int>(10)); 560 bufs.insert(bufs.begin() + 2, &vect_vector[2].front()); 561 bufs.insert(bufs.begin() + 3, &vect_vector[3].front()); 562 CPPUNIT_ASSERT( vect_vector.size() == 22 ); 563 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 564 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end()); 565 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 566 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 567 } 568 #endif 569 } 570 571 { 572 //2 values in back: 573 vect_vector.insert(vect_vector.end() - 2, 2, vector<int>(10)); 574 bufs.insert(bufs.end() - 2, &vect_vector[20].front()); 575 bufs.insert(bufs.end() - 2, &vect_vector[21].front()); 576 CPPUNIT_ASSERT( vect_vector.size() == 24 ); 577 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 578 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end()); 579 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 580 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 581 } 582 #endif 583 } 584 585 { 586 //1 value in front: 587 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 588 vector<vector<int> >::iterator ret = 589 #endif 590 vect_vector.insert(vect_vector.begin() + 2, vector<int>(10)); 591 bufs.insert(bufs.begin() + 2, &vect_vector[2].front()); 592 CPPUNIT_ASSERT( vect_vector.size() == 25 ); 593 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 594 CPPUNIT_ASSERT( &ret->front() == bufs[2] ); 595 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end()); 596 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 597 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 598 } 599 #endif 600 } 601 602 { 603 //1 value in back: 604 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 605 vector<vector<int> >::iterator ret = 606 #endif 607 vect_vector.insert(vect_vector.end() - 2, vector<int>(10)); 608 bufs.insert(bufs.end() - 2, &vect_vector[23].front()); 609 CPPUNIT_ASSERT( vect_vector.size() == 26 ); 610 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 611 CPPUNIT_ASSERT( &ret->front() == bufs[23] ); 612 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end()); 613 for (size_t i = 0; dit != ditEnd; ++dit, ++i) { 614 CPPUNIT_ASSERT( bufs[i] == &dit->front() ); 615 } 616 #endif 617 } 618 } 619 620 //The following tests are checking move contructor implementations: 621 const string long_str("long enough string to force dynamic allocation"); 622 { 623 //vector move contructor: 624 vector<vector<string> > vect(10, vector<string>(10, long_str)); 625 vector<string> strs; 626 size_t index = 0; 627 for (;;) { 628 vector<vector<string> >::iterator it(vect.begin()); 629 advance(it, index % vect.size()); 630 strs.push_back(it->front()); 631 it->erase(it->begin()); 632 if (it->empty()) { 633 vect.erase(it); 634 if (vect.empty()) 635 break; 636 } 637 index += 3; 638 } 639 CPPUNIT_ASSERT( strs.size() == 10 * 10 ); 640 vector<string>::iterator it(strs.begin()), itEnd(strs.end()); 641 for (; it != itEnd; ++it) { 642 CPPUNIT_ASSERT( *it == long_str ); 643 } 644 } 645 646 { 647 //deque move contructor: 648 # if !defined (__DMC__) 649 vector<deque<string> > vect(10, deque<string>(10, long_str)); 650 # else 651 deque<string> deq_str = deque<string>(10, long_str); 652 vector<deque<string> > vect(10, deq_str); 653 # endif 654 vector<string> strs; 655 size_t index = 0; 656 for (;;) { 657 vector<deque<string> >::iterator it(vect.begin()); 658 advance(it, index % vect.size()); 659 strs.push_back(it->front()); 660 it->pop_front(); 661 if (it->empty()) { 662 vect.erase(it); 663 if (vect.empty()) 664 break; 665 } 666 index += 3; 667 } 668 CPPUNIT_ASSERT( strs.size() == 10 * 10 ); 669 vector<string>::iterator it(strs.begin()), itEnd(strs.end()); 670 for (; it != itEnd; ++it) { 671 CPPUNIT_ASSERT( *it == long_str ); 672 } 673 } 674 675 { 676 //list move contructor: 677 vector<list<string> > vect(10, list<string>(10, long_str)); 678 vector<string> strs; 679 size_t index = 0; 680 for (;;) { 681 vector<list<string> >::iterator it(vect.begin()); 682 advance(it, index % vect.size()); 683 strs.push_back(it->front()); 684 it->pop_front(); 685 if (it->empty()) { 686 vect.erase(it); 687 if (vect.empty()) 688 break; 689 } 690 index += 3; 691 } 692 CPPUNIT_ASSERT( strs.size() == 10 * 10 ); 693 vector<string>::iterator it(strs.begin()), itEnd(strs.end()); 694 for (; it != itEnd; ++it) { 695 CPPUNIT_ASSERT( *it == long_str ); 696 } 697 } 698 699 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 700 { 701 //slist move contructor: 702 vector<slist<string> > vect(10, slist<string>(10, long_str)); 703 vector<string> strs; 704 size_t index = 0; 705 while (true) { 706 vector<slist<string> >::iterator it(vect.begin()); 707 advance(it, index % vect.size()); 708 strs.push_back(it->front()); 709 it->pop_front(); 710 if (it->empty()) { 711 vect.erase(it); 712 if (vect.empty()) 713 break; 714 } 715 index += 3; 716 } 717 CPPUNIT_ASSERT( strs.size() == 10 * 10 ); 718 vector<string>::iterator it(strs.begin()), itEnd(strs.end()); 719 for (; it != itEnd; ++it) { 720 CPPUNIT_ASSERT( *it == long_str ); 721 } 722 } 723 #endif 724 725 { 726 //binary tree move contructor: 727 multiset<string> ref; 728 for (size_t i = 0; i < 10; ++i) { 729 ref.insert(long_str); 730 } 731 vector<multiset<string> > vect(10, ref); 732 vector<string> strs; 733 size_t index = 0; 734 for (;;) { 735 vector<multiset<string> >::iterator it(vect.begin()); 736 advance(it, index % vect.size()); 737 strs.push_back(*it->begin()); 738 it->erase(it->begin()); 739 if (it->empty()) { 740 vect.erase(it); 741 if (vect.empty()) 742 break; 743 } 744 index += 3; 745 } 746 CPPUNIT_ASSERT( strs.size() == 10 * 10 ); 747 vector<string>::iterator it(strs.begin()), itEnd(strs.end()); 748 for (; it != itEnd; ++it) { 749 CPPUNIT_ASSERT( *it == long_str ); 750 } 751 } 752 753 #if defined (STLPORT) 754 # if !defined (__DMC__) 755 { 756 //hash container move contructor: 757 unordered_multiset<string> ref; 758 for (size_t i = 0; i < 10; ++i) { 759 ref.insert(long_str); 760 } 761 vector<unordered_multiset<string> > vect(10, ref); 762 vector<string> strs; 763 size_t index = 0; 764 while (true) { 765 vector<unordered_multiset<string> >::iterator it(vect.begin()); 766 advance(it, index % vect.size()); 767 strs.push_back(*it->begin()); 768 it->erase(it->begin()); 769 if (it->empty()) { 770 vect.erase(it); 771 if (vect.empty()) 772 break; 773 } 774 index += 3; 775 } 776 CPPUNIT_ASSERT( strs.size() == 10 * 10 ); 777 vector<string>::iterator it(strs.begin()), itEnd(strs.end()); 778 for (; it != itEnd; ++it) { 779 CPPUNIT_ASSERT( *it == long_str ); 780 } 781 } 782 # endif 783 #endif 784 } 785 786 #if defined (__BORLANDC__) 787 /* Specific Borland test case to show a really weird compiler behavior. 788 */ 789 class Standalone 790 { 791 public: 792 //Uncomment following to pass the test 793 //Standalone() {} 794 ~Standalone() {} 795 796 MovableStruct movableStruct; 797 vector<int> intVector; 798 }; 799 800 void MoveConstructorTest::nb_destructor_calls() 801 { 802 MovableStruct::reset(); 803 804 try 805 { 806 Standalone standalone; 807 throw "some exception"; 808 MovableStruct movableStruct; 809 } 810 catch (const char*) 811 { 812 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 1 ); 813 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 ); 814 } 815 } 816 #endif 817