mvctor_test.cpp revision e46c9386c4f79aa40185f79a19fc5b2a7ef528b3
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)
17using namespace std;
18#  if defined (STLPORT)
19using namespace std::tr1;
20#  endif
21#endif
22
23CPPUNIT_TEST_SUITE_REGISTRATION(MoveConstructorTest);
24
25//
26// tests implementation
27//
28void 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
172void 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
397void 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 */
789class Standalone
790{
791public:
792  //Uncomment following to pass the test
793  //Standalone() {}
794  ~Standalone() {}
795
796  MovableStruct movableStruct;
797  vector<int> intVector;
798};
799
800void 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