Update contrib.
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
10 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
13 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
21 # include <unordered_set>
22 # include <unordered_map>
24 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
32 #include "cppunit/cppunit_proxy.h"
34 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
41 class MoveConstructorTest : public CPPUNIT_NS::TestCase
43 CPPUNIT_TEST_SUITE(MoveConstructorTest);
44 CPPUNIT_TEST(move_construct_test);
45 CPPUNIT_TEST(deque_test);
49 CPPUNIT_TEST(vector_test);
51 CPPUNIT_TEST(move_traits);
52 #if !defined (STLPORT) || defined (_STLP_NO_MOVE_SEMANTIC) || \
53 defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) || \
54 defined (__BORLANDC__) || defined (__DMC__)
57 CPPUNIT_TEST(movable_declaration)
58 #if defined (__BORLANDC__)
60 CPPUNIT_TEST(nb_destructor_calls);
62 CPPUNIT_TEST_SUITE_END();
65 void move_construct_test();
69 void movable_declaration();
70 void nb_destructor_calls();
73 template <class _Container>
74 void standard_test1(_Container const& ref_cont) {
75 vector<_Container> vec_cont(1, ref_cont);
76 typedef typename _Container::value_type value_type;
77 value_type *pvalue = &(*vec_cont.front().begin());
78 size_t cur_capacity= vec_cont.capacity();
80 while (cur_capacity == vec_cont.capacity()) {
81 vec_cont.push_back(ref_cont);
83 bool b=( (pvalue==(&(*vec_cont.front().begin()))) );
89 CPPUNIT_TEST_SUITE_REGISTRATION(MoveConstructorTest);
92 // tests implementation
94 void MoveConstructorTest::move_construct_test()
96 //cout << "vector<vector<int>>";
97 vector<int> const ref_vec(10, 0);
98 vector<vector<int> > v_v_ints(1, ref_vec);
100 int *pint = &(v_v_ints.front().front());
102 size_t cur_capacity = v_v_ints.capacity();
103 while (v_v_ints.capacity() <= cur_capacity) {
104 v_v_ints.push_back(ref_vec);
107 //v_v_ints has been resized
108 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
109 CPPUNIT_ASSERT((pint == &v_v_ints.front().front()));
112 //cout << "vector<vector<int>>::erase";
113 //We need at least 3 elements:
114 while (v_v_ints.size() < 3) {
115 v_v_ints.push_back(ref_vec);
119 pint = &v_v_ints[2].front();
120 v_v_ints.erase(v_v_ints.begin() + 1);
121 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
122 CPPUNIT_ASSERT((pint == &v_v_ints[1].front()));
125 //cout << "vector<string>";
126 string const ref_str("ref string, big enough to be a dynamic one");
127 vector<string> vec_strs(1, ref_str);
129 char const* pstr = vec_strs.front().c_str();
130 cur_capacity = vec_strs.capacity();
131 while (vec_strs.capacity() <= cur_capacity) {
132 vec_strs.push_back(ref_str);
135 //vec_str has been resized
136 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
137 CPPUNIT_ASSERT((pstr == vec_strs.front().c_str()));
140 //cout << "vector<string>::erase";
141 //We need at least 3 elements:
142 while (vec_strs.size() < 3) {
143 vec_strs.push_back(ref_str);
147 pstr = vec_strs[2].c_str();
148 vec_strs.erase(vec_strs.begin() + 1);
149 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
150 CPPUNIT_ASSERT((pstr == vec_strs[1].c_str()));
153 //cout << "swap(vector<int>, vector<int>)";
154 vector<int> elem1(10, 0), elem2(10, 0);
155 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
156 int *p1 = &elem1.front();
157 int *p2 = &elem2.front();
160 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
161 CPPUNIT_ASSERT(((p1 == &elem2.front()) && (p2 == &elem1.front())));
165 vector<bool> bit_vec(5, true);
166 bit_vec.insert(bit_vec.end(), 5, false);
167 vector<vector<bool> > v_v_bits(1, bit_vec);
170 * This is a STLport specific test as we are using internal implementation
171 * details to check that the move has been correctly handled. For other
172 * STL implementation it is only a compile check.
174 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
175 # if defined (_STLP_DEBUG)
176 unsigned int *punit = v_v_bits.front().begin()._M_iterator._M_p;
178 unsigned int *punit = v_v_bits.front().begin()._M_p;
182 cur_capacity = v_v_bits.capacity();
183 while (v_v_bits.capacity() <= cur_capacity) {
184 v_v_bits.push_back(bit_vec);
187 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
188 //v_v_bits has been resized
189 # if defined (_STLP_DEBUG)
190 CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_iterator._M_p );
192 CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_p );
197 // zero: don't like this kind of tests
198 // because of template test function
199 // we should find another way to provide
200 // move constructor testing...
203 standard_test1(list<int>(10));
206 standard_test1(slist<int>(10));
208 standard_test1(deque<int>(10));
212 int int_values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
214 set<int> int_set(int_values, int_values + sizeof(in_values) / sizeof(int));
215 standard_test1(int_set);
217 multiset<int> int_multiset(int_values, int_values + sizeof(in_values) / sizeof(int));
218 standard_test1(int_multiset);
222 CheckFullMoveSupport(string());
223 CheckFullMoveSupport(vector<int>());
224 CheckFullMoveSupport(deque<int>());
225 CheckFullMoveSupport(list<int>());
226 CheckFullMoveSupport(slist<int>());
230 void MoveConstructorTest::deque_test()
232 //Check the insert range method.
235 # if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES)
236 deque<vector<int> > vect_deque;
238 vect_deque.assign(3, vector<int>(10));
239 bufs.push_back(&vect_deque[0].front());
240 bufs.push_back(&vect_deque[1].front());
241 bufs.push_back(&vect_deque[2].front());
244 //Initialize to 1 to generate a front insertion:
246 while (nb_insert--) {
247 vector<vector<int> > vect_vect(2, vector<int>(10));
248 vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end());
249 bufs.insert(bufs.begin() + pos, &vect_deque[pos].front());
250 bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front());
253 CPPUNIT_ASSERT( vect_deque.size() == 13 );
254 # if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
255 for (int i = 0; i < 5; ++i) {
256 CPPUNIT_ASSERT( bufs[i] == &vect_deque[i].front() );
257 CPPUNIT_ASSERT( bufs[11 - i] == &vect_deque[11 - i].front() );
265 # if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES)
266 deque<vector<int> > vect_deque;
268 vect_deque.assign(3, vector<int>(10));
269 bufs.push_back(&vect_deque[0].front());
270 bufs.push_back(&vect_deque[1].front());
271 bufs.push_back(&vect_deque[2].front());
274 //Initialize to 2 to generate a back insertion:
276 while (nb_insert--) {
277 vector<vector<int> > vect_vect(2, vector<int>(10));
278 vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end());
279 bufs.insert(bufs.begin() + pos, &vect_deque[pos].front());
280 bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front());
283 CPPUNIT_ASSERT( vect_deque.size() == 13 );
284 # if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
285 for (int i = 0; i < 5; ++i) {
286 CPPUNIT_ASSERT( bufs[i + 1] == &vect_deque[i + 1].front() );
287 CPPUNIT_ASSERT( bufs[12 - i] == &vect_deque[12 - i].front() );
293 //Check the different erase methods.
295 deque<vector<int> > vect_deque;
296 vect_deque.assign(20, vector<int>(10));
297 deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end());
299 for (; vdit != vditEnd; ++vdit) {
300 bufs.push_back(&vdit->front());
304 // This check, repeated after each operation, check the deque consistency:
305 deque<vector<int> >::iterator it = vect_deque.end() - 5;
307 for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
308 CPPUNIT_ASSERT( nb_incr == 5 );
313 vect_deque.erase(vect_deque.begin() + 2);
314 bufs.erase(bufs.begin() + 2);
315 CPPUNIT_ASSERT( vect_deque.size() == 19 );
316 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
317 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
318 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
319 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
325 deque<vector<int> >::iterator it = vect_deque.end() - 5;
327 for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
328 CPPUNIT_ASSERT( nb_incr == 5 );
333 vect_deque.erase(vect_deque.end() - 2);
334 bufs.erase(bufs.end() - 2);
335 CPPUNIT_ASSERT( vect_deque.size() == 18 );
336 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
337 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
338 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
339 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
345 deque<vector<int> >::iterator it = vect_deque.end() - 5;
347 for (; it != vect_deque.end() && nb_incr < 6; ++nb_incr, ++it) {}
348 CPPUNIT_ASSERT( nb_incr == 5 );
352 //range erase in front
353 vect_deque.erase(vect_deque.begin() + 3, vect_deque.begin() + 5);
354 bufs.erase(bufs.begin() + 3, bufs.begin() + 5);
355 CPPUNIT_ASSERT( vect_deque.size() == 16 );
356 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
357 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
358 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
359 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
365 deque<vector<int> >::iterator it = vect_deque.end() - 5;
367 for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
368 CPPUNIT_ASSERT( nb_incr == 5 );
372 //range erase in back
373 vect_deque.erase(vect_deque.end() - 5, vect_deque.end() - 3);
374 bufs.erase(bufs.end() - 5, bufs.end() - 3);
375 CPPUNIT_ASSERT( vect_deque.size() == 14 );
376 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
377 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
378 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
379 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
385 //Check the insert value(s)
387 deque<vector<int> > vect_deque;
388 vect_deque.assign(20, vector<int>(10));
389 deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end());
391 for (; vdit != vditEnd; ++vdit) {
392 bufs.push_back(&vdit->front());
397 vect_deque.insert(vect_deque.begin() + 2, 2, vector<int>(10));
398 bufs.insert(bufs.begin() + 2, &vect_deque[2].front());
399 bufs.insert(bufs.begin() + 3, &vect_deque[3].front());
400 CPPUNIT_ASSERT( vect_deque.size() == 22 );
401 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
402 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
403 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
404 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
411 vect_deque.insert(vect_deque.end() - 2, 2, vector<int>(10));
412 bufs.insert(bufs.end() - 2, &vect_deque[20].front());
413 bufs.insert(bufs.end() - 2, &vect_deque[21].front());
414 CPPUNIT_ASSERT( vect_deque.size() == 24 );
415 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
416 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
417 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
418 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
425 deque<vector<int> >::iterator ret;
426 ret = vect_deque.insert(vect_deque.begin() + 2, vector<int>(10));
427 bufs.insert(bufs.begin() + 2, &vect_deque[2].front());
428 CPPUNIT_ASSERT( vect_deque.size() == 25 );
429 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
430 CPPUNIT_ASSERT( &ret->front() == bufs[2] );
431 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
432 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
433 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
440 deque<vector<int> >::iterator ret;
441 ret = vect_deque.insert(vect_deque.end() - 2, vector<int>(10));
442 bufs.insert(bufs.end() - 2, &vect_deque[23].front());
443 CPPUNIT_ASSERT( vect_deque.size() == 26 );
444 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
445 CPPUNIT_ASSERT( &ret->front() == bufs[23] );
446 deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
447 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
448 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
455 void MoveConstructorTest::vector_test()
457 #if !defined (__DMC__)
458 //Check the insert range method.
461 vector<vector<int> > vect_vector;
463 vect_vector.assign(3, vector<int>(10));
464 bufs.push_back(&vect_vector[0].front());
465 bufs.push_back(&vect_vector[1].front());
466 bufs.push_back(&vect_vector[2].front());
470 while (nb_insert--) {
471 vector<vector<int> > vect_vect(2, vector<int>(10));
472 vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end());
473 bufs.insert(bufs.begin() + pos, &vect_vector[pos].front());
474 bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front());
477 CPPUNIT_ASSERT( vect_vector.size() == 13 );
478 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
479 for (int i = 0; i < 5; ++i) {
480 CPPUNIT_ASSERT( bufs[i] == &vect_vector[i].front() );
481 CPPUNIT_ASSERT( bufs[11 - i] == &vect_vector[11 - i].front() );
488 vector<vector<int> > vect_vector;
490 vect_vector.assign(3, vector<int>(10));
491 bufs.push_back(&vect_vector[0].front());
492 bufs.push_back(&vect_vector[1].front());
493 bufs.push_back(&vect_vector[2].front());
496 //Initialize to 2 to generate a back insertion:
498 while (nb_insert--) {
499 vector<vector<int> > vect_vect(2, vector<int>(10));
500 vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end());
501 bufs.insert(bufs.begin() + pos, &vect_vector[pos].front());
502 bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front());
505 CPPUNIT_ASSERT( vect_vector.size() == 13 );
506 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
507 for (int i = 0; i < 5; ++i) {
508 CPPUNIT_ASSERT( bufs[i + 1] == &vect_vector[i + 1].front() );
509 CPPUNIT_ASSERT( bufs[12 - i] == &vect_vector[12 - i].front() );
514 //Check the different erase methods.
516 vector<vector<int> > vect_vector;
517 vect_vector.assign(20, vector<int>(10));
518 vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end());
520 for (; vdit != vditEnd; ++vdit) {
521 bufs.push_back(&vdit->front());
525 // This check, repeated after each operation, check the vector consistency:
526 vector<vector<int> >::iterator it = vect_vector.end() - 5;
528 for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
529 CPPUNIT_ASSERT( nb_incr == 5 );
534 vect_vector.erase(vect_vector.begin() + 2);
535 bufs.erase(bufs.begin() + 2);
536 CPPUNIT_ASSERT( vect_vector.size() == 19 );
537 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
538 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
539 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
540 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
546 vector<vector<int> >::iterator it = vect_vector.end() - 5;
548 for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
549 CPPUNIT_ASSERT( nb_incr == 5 );
554 vect_vector.erase(vect_vector.end() - 2);
555 bufs.erase(bufs.end() - 2);
556 CPPUNIT_ASSERT( vect_vector.size() == 18 );
557 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
558 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
559 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
560 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
566 vector<vector<int> >::iterator it = vect_vector.end() - 5;
568 for (; it != vect_vector.end() && nb_incr < 6; ++nb_incr, ++it) {}
569 CPPUNIT_ASSERT( nb_incr == 5 );
573 //range erase in front
574 vect_vector.erase(vect_vector.begin() + 3, vect_vector.begin() + 5);
575 bufs.erase(bufs.begin() + 3, bufs.begin() + 5);
576 CPPUNIT_ASSERT( vect_vector.size() == 16 );
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() );
586 vector<vector<int> >::iterator it = vect_vector.end() - 5;
588 for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
589 CPPUNIT_ASSERT( nb_incr == 5 );
593 //range erase in back
594 vect_vector.erase(vect_vector.end() - 5, vect_vector.end() - 3);
595 bufs.erase(bufs.end() - 5, bufs.end() - 3);
596 CPPUNIT_ASSERT( vect_vector.size() == 14 );
597 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
598 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
599 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
600 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
606 //Check the insert value(s)
608 vector<vector<int> > vect_vector;
609 vect_vector.assign(20, vector<int>(10));
610 vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end());
612 for (; vdit != vditEnd; ++vdit) {
613 bufs.push_back(&vdit->front());
618 vect_vector.insert(vect_vector.begin() + 2, 2, vector<int>(10));
619 bufs.insert(bufs.begin() + 2, &vect_vector[2].front());
620 bufs.insert(bufs.begin() + 3, &vect_vector[3].front());
621 CPPUNIT_ASSERT( vect_vector.size() == 22 );
622 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
623 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
624 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
625 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
632 vect_vector.insert(vect_vector.end() - 2, 2, vector<int>(10));
633 bufs.insert(bufs.end() - 2, &vect_vector[20].front());
634 bufs.insert(bufs.end() - 2, &vect_vector[21].front());
635 CPPUNIT_ASSERT( vect_vector.size() == 24 );
636 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
637 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
638 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
639 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
646 vector<vector<int> >::iterator ret;
647 ret = vect_vector.insert(vect_vector.begin() + 2, vector<int>(10));
648 bufs.insert(bufs.begin() + 2, &vect_vector[2].front());
649 CPPUNIT_ASSERT( vect_vector.size() == 25 );
650 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
651 CPPUNIT_ASSERT( &ret->front() == bufs[2] );
652 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
653 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
654 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
661 vector<vector<int> >::iterator ret;
662 ret = vect_vector.insert(vect_vector.end() - 2, vector<int>(10));
663 bufs.insert(bufs.end() - 2, &vect_vector[23].front());
664 CPPUNIT_ASSERT( vect_vector.size() == 26 );
665 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
666 CPPUNIT_ASSERT( &ret->front() == bufs[23] );
667 vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
668 for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
669 CPPUNIT_ASSERT( bufs[i] == &dit->front() );
675 //The following tests are checking move contructor implementations:
676 const string long_str("long enough string to force dynamic allocation");
678 //vector move contructor:
679 vector<vector<string> > vect(10, vector<string>(10, long_str));
683 vector<vector<string> >::iterator it(vect.begin());
684 advance(it, index % vect.size());
685 strs.push_back(it->front());
686 it->erase(it->begin());
694 CPPUNIT_ASSERT( strs.size() == 10 * 10 );
695 vector<string>::iterator it(strs.begin()), itEnd(strs.end());
696 for (; it != itEnd; ++it) {
697 CPPUNIT_ASSERT( *it == long_str );
702 //deque move contructor:
703 vector<deque<string> > vect(10, deque<string>(10, long_str));
707 vector<deque<string> >::iterator it(vect.begin());
708 advance(it, index % vect.size());
709 strs.push_back(it->front());
718 CPPUNIT_ASSERT( strs.size() == 10 * 10 );
719 vector<string>::iterator it(strs.begin()), itEnd(strs.end());
720 for (; it != itEnd; ++it) {
721 CPPUNIT_ASSERT( *it == long_str );
726 //list move contructor:
727 vector<list<string> > vect(10, list<string>(10, long_str));
731 vector<list<string> >::iterator it(vect.begin());
732 advance(it, index % vect.size());
733 strs.push_back(it->front());
742 CPPUNIT_ASSERT( strs.size() == 10 * 10 );
743 vector<string>::iterator it(strs.begin()), itEnd(strs.end());
744 for (; it != itEnd; ++it) {
745 CPPUNIT_ASSERT( *it == long_str );
749 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
751 //slist move contructor:
752 vector<slist<string> > vect(10, slist<string>(10, long_str));
756 vector<slist<string> >::iterator it(vect.begin());
757 advance(it, index % vect.size());
758 strs.push_back(it->front());
767 CPPUNIT_ASSERT( strs.size() == 10 * 10 );
768 vector<string>::iterator it(strs.begin()), itEnd(strs.end());
769 for (; it != itEnd; ++it) {
770 CPPUNIT_ASSERT( *it == long_str );
776 //binary tree move contructor:
777 multiset<string> ref;
778 for (size_t i = 0; i < 10; ++i) {
779 ref.insert(long_str);
781 vector<multiset<string> > vect(10, ref);
785 vector<multiset<string> >::iterator it(vect.begin());
786 advance(it, index % vect.size());
787 strs.push_back(*it->begin());
788 it->erase(it->begin());
796 CPPUNIT_ASSERT( strs.size() == 10 * 10 );
797 vector<string>::iterator it(strs.begin()), itEnd(strs.end());
798 for (; it != itEnd; ++it) {
799 CPPUNIT_ASSERT( *it == long_str );
802 # endif /* __DMC__ */
804 #if defined (STLPORT)
805 # if !defined (__BORLANDC__) && !defined (__DMC__)
807 //hash container move contructor:
808 unordered_multiset<string> ref;
809 for (size_t i = 0; i < 10; ++i) {
810 ref.insert(long_str);
812 vector<unordered_multiset<string> > vect(10, ref);
816 vector<unordered_multiset<string> >::iterator it(vect.begin());
817 advance(it, index % vect.size());
818 strs.push_back(*it->begin());
819 it->erase(it->begin());
827 CPPUNIT_ASSERT( strs.size() == 10 * 10 );
828 vector<string>::iterator it(strs.begin()), itEnd(strs.end());
829 for (; it != itEnd; ++it) {
830 CPPUNIT_ASSERT( *it == long_str );
837 struct MovableStruct {
838 MovableStruct() { ++nb_dft_construct_call; }
839 MovableStruct(MovableStruct const&) { ++nb_cpy_construct_call; }
840 # if defined (STLPORT)
841 MovableStruct(__move_source<MovableStruct>) { ++nb_mv_construct_call; }
843 ~MovableStruct() { ++nb_destruct_call; }
845 MovableStruct& operator = (const MovableStruct&) {
846 ++nb_assignment_call;
850 static void reset() {
851 nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
852 nb_assignment_call = 0;
853 nb_destruct_call = 0;
856 static size_t nb_dft_construct_call;
857 static size_t nb_cpy_construct_call;
858 static size_t nb_mv_construct_call;
859 static size_t nb_assignment_call;
860 static size_t nb_destruct_call;
862 //Dummy data just to control struct sizeof
863 //As node allocator implementation align memory blocks on 2 * sizeof(void*)
864 //we give MovableStruct the same size in order to have expected allocation
869 size_t MovableStruct::nb_dft_construct_call = 0;
870 size_t MovableStruct::nb_cpy_construct_call = 0;
871 size_t MovableStruct::nb_mv_construct_call = 0;
872 size_t MovableStruct::nb_assignment_call = 0;
873 size_t MovableStruct::nb_destruct_call = 0;
875 # if defined (STLPORT)
878 struct __move_traits<MovableStruct> {
879 typedef __true_type implemented;
880 typedef __false_type complete;
885 struct CompleteMovableStruct {
886 CompleteMovableStruct() { ++nb_dft_construct_call; }
887 CompleteMovableStruct(CompleteMovableStruct const&) { ++nb_cpy_construct_call; }
888 # if defined (STLPORT)
889 CompleteMovableStruct(__move_source<CompleteMovableStruct>) { ++nb_mv_construct_call; }
891 ~CompleteMovableStruct() { ++nb_destruct_call; }
893 CompleteMovableStruct& operator = (const CompleteMovableStruct&) {
894 ++nb_assignment_call;
897 static void reset() {
898 nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
899 nb_assignment_call = 0;
900 nb_destruct_call = 0;
903 static size_t nb_dft_construct_call;
904 static size_t nb_cpy_construct_call;
905 static size_t nb_mv_construct_call;
906 static size_t nb_assignment_call;
907 static size_t nb_destruct_call;
913 size_t CompleteMovableStruct::nb_dft_construct_call = 0;
914 size_t CompleteMovableStruct::nb_cpy_construct_call = 0;
915 size_t CompleteMovableStruct::nb_mv_construct_call = 0;
916 size_t CompleteMovableStruct::nb_assignment_call = 0;
917 size_t CompleteMovableStruct::nb_destruct_call = 0;
919 # if defined (STLPORT)
922 struct __move_traits<CompleteMovableStruct> {
923 typedef __true_type implemented;
924 typedef __true_type complete;
929 void MoveConstructorTest::move_traits()
933 vector<MovableStruct> vect;
934 vect.push_back(MovableStruct());
935 vect.push_back(MovableStruct());
936 vect.push_back(MovableStruct());
937 vect.push_back(MovableStruct());
939 // vect contains 4 elements
940 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
941 #if defined (STLPORT)
942 # if !defined (_STLP_NO_MOVE_SEMANTIC)
943 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
944 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
946 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
948 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
949 #elif !defined (_MSC_VER)
950 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
951 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
953 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 14 );
954 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 14 );
956 CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
958 // Following test violate requirements to sequiences (23.1.1 Table 67)
960 vect.insert(vect.begin() + 2, vect.begin(), vect.end());
961 // vect contains 8 elements
962 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
963 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
964 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
965 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
968 MovableStruct::reset();
969 vector<MovableStruct> v2 = vect;
970 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
971 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
972 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
973 CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
974 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
976 MovableStruct::reset();
977 vect.insert(vect.begin() + 2, v2.begin(), v2.end() );
979 // vect contains 8 elements
980 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
981 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
982 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
983 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 4 );
985 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
987 CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
988 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
990 MovableStruct::reset();
991 vect.erase(vect.begin(), vect.begin() + 2 );
993 // vect contains 6 elements
994 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
995 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 6 );
996 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 8 );
998 CPPUNIT_ASSERT_EQUAL( MovableStruct::nb_assignment_call, 6 );
999 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1002 MovableStruct::reset();
1003 vect.erase(vect.end() - 2, vect.end());
1005 // vect contains 4 elements
1006 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1007 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1009 MovableStruct::reset();
1010 vect.erase(vect.begin());
1012 // vect contains 3 elements
1013 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1014 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
1015 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
1017 CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 3 );
1018 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
1021 MovableStruct::reset();
1023 //vect with 3 elements and v2 with 4 elements are now out of scope
1024 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
1029 vector<CompleteMovableStruct> vect;
1030 vect.push_back(CompleteMovableStruct());
1031 vect.push_back(CompleteMovableStruct());
1032 vect.push_back(CompleteMovableStruct());
1033 vect.push_back(CompleteMovableStruct());
1035 // vect contains 4 elements
1036 CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
1037 #if defined (STLPORT)
1038 # if !defined (_STLP_NO_MOVE_SEMANTIC)
1039 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1040 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
1042 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
1044 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1045 #elif !defined (_MSC_VER)
1046 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
1047 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 7 );
1049 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 14 );
1050 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 14 );
1053 // Following test violate requirements to sequiences (23.1.1 Table 67)
1055 vect.insert(vect.begin() + 2, vect.begin(), vect.end());
1057 // vect contains 8 elements
1058 CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
1059 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
1060 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
1061 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1064 CompleteMovableStruct::reset();
1065 vector<CompleteMovableStruct> v2 = vect;
1067 CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
1068 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1069 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1070 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
1072 CompleteMovableStruct::reset();
1073 vect.insert(vect.begin() + 2, v2.begin(), v2.end());
1075 // vect contains 8 elements
1076 CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
1077 #if defined (STLPORT)
1078 # if !defined (_STLP_NO_MOVE_SEMANTIC)
1079 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1080 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 4 );
1082 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
1084 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
1086 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
1087 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1090 CompleteMovableStruct::reset();
1091 vect.erase(vect.begin(), vect.begin() + 2);
1093 // vect contains 6 elements
1094 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1095 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 6 );
1097 CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 6 );
1099 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
1101 CompleteMovableStruct::reset();
1102 vect.erase(vect.end() - 2, vect.end());
1104 // vect contains 4 elements
1105 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1106 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
1108 CompleteMovableStruct::reset();
1109 vect.erase(vect.begin());
1111 // vect contains 3 elements
1112 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1113 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
1115 CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 3 );
1117 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
1119 CompleteMovableStruct::reset();
1121 //vect with 3 elements and v2 with 4 elements are now out of scope
1122 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
1126 MovableStruct::reset();
1128 deque<MovableStruct> deq;
1129 deq.push_back(MovableStruct());
1130 deq.push_back(MovableStruct());
1131 deq.push_back(MovableStruct());
1132 deq.push_back(MovableStruct());
1134 // deq contains 4 elements
1135 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
1136 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1137 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1138 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
1140 // Following test violate requirements to sequiences (23.1.1 Table 67)
1142 deq.insert(deq.begin() + 2, deq.begin(), deq.end());
1143 // deq contains 8 elements
1144 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
1145 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
1146 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
1147 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
1150 MovableStruct::reset();
1151 deque<MovableStruct> d2 = deq;
1153 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
1154 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1155 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1156 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
1158 MovableStruct::reset();
1159 deq.insert(deq.begin() + 2, d2.begin(), d2.end() );
1161 // deq contains 8 elements
1162 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
1163 CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1164 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1165 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 2 );
1166 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1168 CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 2 );
1169 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
1172 MovableStruct::reset();
1173 deq.erase(deq.begin() + 1, deq.begin() + 3 );
1175 // deq contains 6 elements
1176 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1177 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
1178 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
1180 //Following check is highly deque implementation dependant so
1181 //it might not always work...
1182 CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
1183 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1186 MovableStruct::reset();
1187 deq.erase(deq.end() - 3, deq.end() - 1);
1189 // deq contains 4 elements
1190 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1191 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
1192 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
1194 CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
1195 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1198 MovableStruct::reset();
1199 deq.erase(deq.begin());
1201 // deq contains 3 elements
1202 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1203 CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1205 CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
1207 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
1209 MovableStruct::reset();
1211 //deq with 3 elements and d2 with 4 elements are now out of scope
1212 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
1216 CompleteMovableStruct::reset();
1218 deque<CompleteMovableStruct> deq;
1219 deq.push_back(CompleteMovableStruct());
1220 deq.push_back(CompleteMovableStruct());
1221 deq.push_back(CompleteMovableStruct());
1222 deq.push_back(CompleteMovableStruct());
1224 // deq contains 4 elements
1225 CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
1226 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1227 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1228 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1230 // Following test violate requirements to sequiences (23.1.1 Table 67)
1232 deq.insert(deq.begin() + 2, deq.begin(), deq.end());
1234 // deq contains 8 elements
1235 CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
1236 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
1237 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
1238 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1241 CompleteMovableStruct::reset();
1242 deque<CompleteMovableStruct> d2 = deq;
1244 CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
1245 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1246 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1247 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
1249 CompleteMovableStruct::reset();
1250 deq.insert(deq.begin() + 2, d2.begin(), d2.end());
1252 // deq contains 8 elements
1253 CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
1254 CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1255 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1256 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 2 );
1258 CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 2 );
1260 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
1262 CompleteMovableStruct::reset();
1263 deq.erase(deq.begin() + 1, deq.begin() + 3);
1265 // deq contains 6 elements
1266 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1267 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
1269 CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
1271 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
1273 CompleteMovableStruct::reset();
1274 deq.erase(deq.end() - 3, deq.end() - 1);
1276 // deq contains 4 elements
1277 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1278 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
1280 CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
1282 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
1284 CompleteMovableStruct::reset();
1285 deq.erase(deq.begin());
1287 // deq contains 3 elements
1288 CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1289 CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 0 );
1290 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
1292 CompleteMovableStruct::reset();
1294 //deq with 3 elements and v2 with 4 elements are now out of scope
1295 CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
1299 #if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1301 # if defined (__GNUC__) && defined (_STLP_USE_NAMESPACES)
1302 // libstdc++ sometimes exposed its own __true_type in
1303 // global namespace resulting in an ambiguity.
1304 # define __true_type std::__true_type
1305 # define __false_type std::__false_type
1308 static bool type_to_bool(__true_type)
1310 static bool type_to_bool(__false_type)
1313 template <class _Tp>
1314 static bool is_movable(const _Tp&) {
1315 #if defined (__BORLANDC__) || defined (__SYMBIAN32__)
1316 return __type2bool<typename __move_traits<_Tp>::implemented>::_Ret != 0;
1318 typedef typename __move_traits<_Tp>::implemented _MovableTp;
1319 return type_to_bool(_MovableTp());
1323 template <class _Tp>
1324 static bool is_move_complete(const _Tp&) {
1325 typedef __move_traits<_Tp> _TpMoveTraits;
1326 #if defined (__BORLANDC__) || defined (__SYMBIAN32__)
1327 return __type2bool<typename __move_traits<_Tp>::complete>::_Ret != 0;
1329 typedef typename _TpMoveTraits::complete _TpMoveComplete;
1330 return type_to_bool(_TpMoveComplete());
1334 struct specially_allocated_struct {
1335 bool operator < (specially_allocated_struct) const;
1338 struct struct_with_specialized_less {};
1343 class allocator<specially_allocated_struct>
1345 //This allocator just represent what a STLport could do and in this
1346 //case the STL containers implemented with it should still be movable
1347 //but not completely as we cannot do any hypothesis on what is in this
1350 typedef specially_allocated_struct value_type;
1351 typedef value_type * pointer;
1352 typedef const value_type* const_pointer;
1353 typedef value_type& reference;
1354 typedef const value_type& const_reference;
1355 typedef size_t size_type;
1356 typedef ptrdiff_t difference_type;
1357 #if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
1358 template <class _Tp1> struct rebind {
1359 typedef allocator<_Tp1> other;
1362 allocator() _STLP_NOTHROW {}
1363 #if defined (_STLP_MEMBER_TEMPLATES)
1364 template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
1366 allocator(const allocator&) _STLP_NOTHROW {}
1367 ~allocator() _STLP_NOTHROW {}
1368 pointer address(reference __x) const { return &__x; }
1369 const_pointer address(const_reference __x) const { return &__x; }
1370 pointer allocate(size_type, const void* = 0) { return 0; }
1371 void deallocate(pointer, size_type) {}
1372 size_type max_size() const _STLP_NOTHROW { return 0; }
1373 void construct(pointer, const_reference) {}
1374 void destroy(pointer) {}
1378 struct less<struct_with_specialized_less> {
1379 bool operator() (struct_with_specialized_less const&,
1380 struct_with_specialized_less const&) const;
1385 void MoveConstructorTest::movable_declaration()
1387 #if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
1388 !defined (_STLP_NO_MOVE_SEMANTIC) && \
1390 //This test purpose is to check correct detection of the STL movable
1391 //traits declaration
1394 CPPUNIT_ASSERT( is_movable(string()) );
1395 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1396 CPPUNIT_ASSERT( is_move_complete(string()) );
1398 CPPUNIT_ASSERT( !is_move_complete(string()) );
1400 # if defined (_STLP_HAS_WCHAR_T)
1401 CPPUNIT_ASSERT( is_movable(wstring()) );
1402 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1403 CPPUNIT_ASSERT( is_move_complete(wstring()) );
1405 CPPUNIT_ASSERT( !is_move_complete(wstring()) );
1410 # if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1413 CPPUNIT_ASSERT( is_movable(crope()) );
1414 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1415 CPPUNIT_ASSERT( is_move_complete(crope()) );
1417 CPPUNIT_ASSERT( !is_move_complete(crope()) );
1419 # if defined (_STLP_HAS_WCHAR_T)
1420 CPPUNIT_ASSERT( is_movable(wrope()) );
1421 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1422 CPPUNIT_ASSERT( is_move_complete(wrope()) );
1424 CPPUNIT_ASSERT( !is_move_complete(wrope()) );
1432 CPPUNIT_ASSERT( is_movable(vector<char>()) );
1433 CPPUNIT_ASSERT( is_movable(vector<specially_allocated_struct>()) );
1434 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1435 CPPUNIT_ASSERT( is_move_complete(vector<char>()) );
1436 CPPUNIT_ASSERT( !is_move_complete(vector<specially_allocated_struct>()) );
1438 CPPUNIT_ASSERT( !is_move_complete(vector<char>()) );
1444 CPPUNIT_ASSERT( is_movable(deque<char>()) );
1445 CPPUNIT_ASSERT( is_movable(deque<specially_allocated_struct>()) );
1446 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1447 CPPUNIT_ASSERT( is_move_complete(deque<char>()) );
1448 CPPUNIT_ASSERT( !is_move_complete(deque<specially_allocated_struct>()) );
1450 CPPUNIT_ASSERT( !is_move_complete(deque<char>()) );
1456 CPPUNIT_ASSERT( is_movable(list<char>()) );
1457 CPPUNIT_ASSERT( is_movable(list<specially_allocated_struct>()) );
1458 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1459 CPPUNIT_ASSERT( is_move_complete(list<char>()) );
1460 CPPUNIT_ASSERT( !is_move_complete(list<specially_allocated_struct>()) );
1462 CPPUNIT_ASSERT( !is_move_complete(list<char>()) );
1466 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1469 CPPUNIT_ASSERT( is_movable(slist<char>()) );
1470 CPPUNIT_ASSERT( is_movable(slist<specially_allocated_struct>()) );
1471 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1472 CPPUNIT_ASSERT( is_move_complete(slist<char>()) );
1473 CPPUNIT_ASSERT( !is_move_complete(slist<specially_allocated_struct>()) );
1475 CPPUNIT_ASSERT( !is_move_complete(slist<char>()) );
1482 CPPUNIT_ASSERT( is_movable(queue<char>()) );
1483 CPPUNIT_ASSERT( is_movable(queue<specially_allocated_struct>()) );
1484 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1485 CPPUNIT_ASSERT( is_move_complete(queue<char>()) );
1486 CPPUNIT_ASSERT( !is_move_complete(queue<specially_allocated_struct>()) );
1488 CPPUNIT_ASSERT( !is_move_complete(queue<char>()) );
1494 CPPUNIT_ASSERT( is_movable(stack<char>()) );
1495 CPPUNIT_ASSERT( is_movable(stack<specially_allocated_struct>()) );
1496 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1497 CPPUNIT_ASSERT( is_move_complete(stack<char>()) );
1498 CPPUNIT_ASSERT( !is_move_complete(stack<specially_allocated_struct>()) );
1500 CPPUNIT_ASSERT( !is_move_complete(stack<char>()) );
1505 //associative containers, set multiset, map, multimap:
1507 //For associative containers it is important that less is correctly recognize as
1508 //the STLport less or a user specialized less:
1509 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1510 CPPUNIT_ASSERT( is_move_complete(less<char>()) );
1512 CPPUNIT_ASSERT( !is_move_complete(less<struct_with_specialized_less>()) );
1515 CPPUNIT_ASSERT( is_movable(set<char>()) );
1516 CPPUNIT_ASSERT( is_movable(set<specially_allocated_struct>()) );
1517 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1518 CPPUNIT_ASSERT( is_move_complete(set<char>()) );
1519 CPPUNIT_ASSERT( !is_move_complete(set<specially_allocated_struct>()) );
1521 CPPUNIT_ASSERT( !is_move_complete(set<char>()) );
1525 CPPUNIT_ASSERT( is_movable(multiset<char>()) );
1526 CPPUNIT_ASSERT( is_movable(multiset<specially_allocated_struct>()) );
1527 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1528 CPPUNIT_ASSERT( is_move_complete(multiset<char>()) );
1529 CPPUNIT_ASSERT( !is_move_complete(multiset<specially_allocated_struct>()) );
1531 CPPUNIT_ASSERT( !is_move_complete(multiset<char>()) );
1535 CPPUNIT_ASSERT( is_movable(map<char, char>()) );
1536 CPPUNIT_ASSERT( is_movable(map<specially_allocated_struct, char>()) );
1537 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1538 CPPUNIT_ASSERT( is_move_complete(map<char, char>()) );
1539 //Here even if allocator has been specialized for specially_allocated_struct
1540 //this pecialization won't be used in default map instanciation as the default
1541 //allocator is allocator<pair<specially_allocated_struct, char> >
1542 CPPUNIT_ASSERT( is_move_complete(map<specially_allocated_struct, char>()) );
1544 CPPUNIT_ASSERT( !is_move_complete(map<char, char>()) );
1548 CPPUNIT_ASSERT( is_movable(multimap<char, char>()) );
1549 CPPUNIT_ASSERT( is_movable(multimap<specially_allocated_struct, char>()) );
1550 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1551 CPPUNIT_ASSERT( is_move_complete(multimap<char, char>()) );
1553 CPPUNIT_ASSERT( is_move_complete(multimap<specially_allocated_struct, char>()) );
1555 CPPUNIT_ASSERT( !is_move_complete(multimap<char, char>()) );
1559 # if defined (STLPORT)
1561 //hashed containers, unordered_set unordered_multiset, unordered_map, unordered_multimap,
1562 // hash_set, hash_multiset, hash_map, hash_multimap:
1564 //We only check that they are movable, completness is not yet supported
1565 CPPUNIT_ASSERT( is_movable(unordered_set<char>()) );
1566 CPPUNIT_ASSERT( is_movable(unordered_multiset<char>()) );
1567 CPPUNIT_ASSERT( is_movable(unordered_map<char, char>()) );
1568 CPPUNIT_ASSERT( is_movable(unordered_multimap<char, char>()) );
1569 # if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1570 CPPUNIT_ASSERT( is_movable(hash_set<char>()) );
1571 CPPUNIT_ASSERT( is_movable(hash_multiset<char>()) );
1572 CPPUNIT_ASSERT( is_movable(hash_map<char, char>()) );
1573 CPPUNIT_ASSERT( is_movable(hash_multimap<char, char>()) );
1580 #if defined (__BORLANDC__)
1581 /* Specific Borland test case to show a really weird compiler behavior.
1586 //Uncomment following to pass the test
1590 MovableStruct movableStruct;
1591 vector<int> intVector;
1594 void MoveConstructorTest::nb_destructor_calls()
1596 MovableStruct::reset();
1600 Standalone standalone;
1601 throw "some exception";
1602 MovableStruct movableStruct;
1606 CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 1 );
1607 CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );