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 //
move_construct_test()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
deque_test()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
vector_test()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() {}
~Standalone()794 ~Standalone() {}
795
796 MovableStruct movableStruct;
797 vector<int> intVector;
798 };
799
nb_destructor_calls()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