• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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