1#include <vector>
2#include <deque>
3
4#include "mvctor_test.h"
5
6#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
7using namespace std;
8#endif
9
10size_t MovableStruct::nb_dft_construct_call = 0;
11size_t MovableStruct::nb_cpy_construct_call = 0;
12size_t MovableStruct::nb_mv_construct_call = 0;
13size_t MovableStruct::nb_assignment_call = 0;
14size_t MovableStruct::nb_destruct_call = 0;
15
16#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
17#  if defined (_STLP_USE_NAMESPACES)
18namespace std {
19#  endif
20  _STLP_TEMPLATE_NULL
21  struct __move_traits<MovableStruct> {
22    typedef __true_type implemented;
23    typedef __false_type complete;
24  };
25#  if defined (_STLP_USE_NAMESPACES)
26}
27#  endif
28#endif
29
30struct CompleteMovableStruct {
31  CompleteMovableStruct() { ++nb_dft_construct_call; }
32  CompleteMovableStruct(CompleteMovableStruct const&) { ++nb_cpy_construct_call; }
33#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
34  CompleteMovableStruct(__move_source<CompleteMovableStruct>) { ++nb_mv_construct_call; }
35#endif
36  ~CompleteMovableStruct() { ++nb_destruct_call; }
37
38  CompleteMovableStruct& operator = (const CompleteMovableStruct&) {
39    ++nb_assignment_call;
40    return *this;
41  }
42  static void reset() {
43    nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
44    nb_assignment_call = 0;
45    nb_destruct_call = 0;
46  }
47
48  static size_t nb_dft_construct_call;
49  static size_t nb_cpy_construct_call;
50  static size_t nb_mv_construct_call;
51  static size_t nb_assignment_call;
52  static size_t nb_destruct_call;
53
54  //See MovableStruct
55  void* dummy_data[2];
56};
57
58size_t CompleteMovableStruct::nb_dft_construct_call = 0;
59size_t CompleteMovableStruct::nb_cpy_construct_call = 0;
60size_t CompleteMovableStruct::nb_mv_construct_call = 0;
61size_t CompleteMovableStruct::nb_assignment_call = 0;
62size_t CompleteMovableStruct::nb_destruct_call = 0;
63
64#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
65#  if defined (_STLP_USE_NAMESPACES)
66namespace std {
67#  endif
68  _STLP_TEMPLATE_NULL
69  struct __move_traits<CompleteMovableStruct> {
70    typedef __true_type implemented;
71    typedef __true_type complete;
72  };
73#  if defined (_STLP_USE_NAMESPACES)
74}
75#  endif
76#endif
77
78void MoveConstructorTest::move_traits()
79{
80  move_traits_vec();
81  move_traits_vec_complete();
82  move_traits_deq();
83  move_traits_deq_complete();
84}
85
86void MoveConstructorTest::move_traits_vec()
87{
88  {
89    {
90      vector<MovableStruct> vect;
91      vect.push_back(MovableStruct());
92      vect.push_back(MovableStruct());
93      vect.push_back(MovableStruct());
94      vect.push_back(MovableStruct());
95
96      // vect contains 4 elements
97      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
98#if defined (STLPORT)
99#  if !defined (_STLP_NO_MOVE_SEMANTIC)
100      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
101      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
102#  else
103      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
104#  endif
105      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
106#elif !defined (_MSC_VER)
107      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
108      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
109#else
110      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 14 );
111      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 14 );
112#endif
113      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
114
115      // Following test violate requirements to sequiences (23.1.1 Table 67)
116      /*
117      vect.insert(vect.begin() + 2, vect.begin(), vect.end());
118      // vect contains 8 elements
119      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
120      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
121      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
122      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
123      */
124
125      MovableStruct::reset();
126      vector<MovableStruct> v2 = vect;
127      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
128      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
129      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
130      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
131      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
132
133      MovableStruct::reset();
134      vect.insert(vect.begin() + 2, v2.begin(), v2.end() );
135
136      // vect contains 8 elements
137      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
138#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
139      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
140      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 4 );
141#else
142      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
143#endif
144      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
145      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
146
147      MovableStruct::reset();
148      vect.erase(vect.begin(), vect.begin() + 2 );
149
150      // vect contains 6 elements
151#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
152      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 6 );
153      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 8 );
154#else
155      CPPUNIT_ASSERT_EQUAL( MovableStruct::nb_assignment_call, 6 );
156      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
157#endif
158
159      MovableStruct::reset();
160      vect.erase(vect.end() - 2, vect.end());
161
162      // vect contains 4 elements
163      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
164      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
165
166      MovableStruct::reset();
167      vect.erase(vect.begin());
168
169      // vect contains 3 elements
170#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
171      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
172      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
173#else
174      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 3 );
175      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
176#endif
177
178      MovableStruct::reset();
179    }
180    //vect with 3 elements and v2 with 4 elements are now out of scope
181    CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
182  }
183}
184
185void MoveConstructorTest::move_traits_vec_complete()
186{
187  {
188    {
189      vector<CompleteMovableStruct> vect;
190      vect.push_back(CompleteMovableStruct());
191      vect.push_back(CompleteMovableStruct());
192      vect.push_back(CompleteMovableStruct());
193      vect.push_back(CompleteMovableStruct());
194
195      // vect contains 4 elements
196      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
197#if defined (STLPORT)
198#  if !defined (_STLP_NO_MOVE_SEMANTIC)
199      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
200      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
201      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
202#  else
203      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
204      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 7 );
205#  endif
206#elif !defined (_MSC_VER)
207      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
208      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 7 );
209#else
210      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 14 );
211      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 14 );
212#endif
213
214      // Following test violate requirements to sequiences (23.1.1 Table 67)
215      /*
216      vect.insert(vect.begin() + 2, vect.begin(), vect.end());
217
218      // vect contains 8 elements
219      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
220      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
221      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
222      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
223      */
224
225      CompleteMovableStruct::reset();
226      vector<CompleteMovableStruct> v2 = vect;
227
228      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
229      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
230      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
231      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
232
233      CompleteMovableStruct::reset();
234      vect.insert(vect.begin() + 2, v2.begin(), v2.end());
235
236      // vect contains 8 elements
237      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
238#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
239      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
240      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 4 );
241      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
242#else
243      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
244      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
245#endif
246
247      CompleteMovableStruct::reset();
248      vect.erase(vect.begin(), vect.begin() + 2);
249
250      // vect contains 6 elements
251#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
252      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 6 );
253#else
254      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 6 );
255#endif
256      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
257
258      CompleteMovableStruct::reset();
259      vect.erase(vect.end() - 2, vect.end());
260
261      // vect contains 4 elements
262      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
263      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
264
265      CompleteMovableStruct::reset();
266      vect.erase(vect.begin());
267
268      // vect contains 3 elements
269#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
270      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
271#else
272      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 3 );
273#endif
274      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
275
276      CompleteMovableStruct::reset();
277    }
278    //vect with 3 elements and v2 with 4 elements are now out of scope
279    CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
280  }
281}
282
283void MoveConstructorTest::move_traits_deq()
284{
285  {
286    MovableStruct::reset();
287    {
288      deque<MovableStruct> deq;
289      deq.push_back(MovableStruct());
290      deq.push_back(MovableStruct());
291      deq.push_back(MovableStruct());
292      deq.push_back(MovableStruct());
293
294      // deq contains 4 elements
295      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
296      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
297      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
298      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
299
300      // Following test violate requirements to sequiences (23.1.1 Table 67)
301      /*
302      deq.insert(deq.begin() + 2, deq.begin(), deq.end());
303      // deq contains 8 elements
304      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
305      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
306      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
307      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
308      */
309
310      MovableStruct::reset();
311      deque<MovableStruct> d2 = deq;
312
313      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
314      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
315      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
316      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
317
318      MovableStruct::reset();
319      deq.insert(deq.begin() + 2, d2.begin(), d2.end() );
320
321      // deq contains 8 elements
322      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
323      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
324#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
325      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 2 );
326      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
327#else
328      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 2 );
329      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
330#endif
331
332      MovableStruct::reset();
333      deq.erase(deq.begin() + 1, deq.begin() + 3 );
334
335      // deq contains 6 elements
336#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
337      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
338      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
339#else
340      //Following check is highly deque implementation dependant so
341      //it might not always work...
342      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
343      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
344#endif
345
346      MovableStruct::reset();
347      deq.erase(deq.end() - 3, deq.end() - 1);
348
349      // deq contains 4 elements
350#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
351      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
352      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
353#else
354      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
355      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
356#endif
357
358      MovableStruct::reset();
359      deq.erase(deq.begin());
360
361      // deq contains 3 elements
362#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
363      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
364#else
365      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
366#endif
367      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
368
369      MovableStruct::reset();
370    }
371    //deq with 3 elements and d2 with 4 elements are now out of scope
372    CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
373  }
374}
375
376void MoveConstructorTest::move_traits_deq_complete()
377{
378  {
379    CompleteMovableStruct::reset();
380    {
381      deque<CompleteMovableStruct> deq;
382      deq.push_back(CompleteMovableStruct());
383      deq.push_back(CompleteMovableStruct());
384      deq.push_back(CompleteMovableStruct());
385      deq.push_back(CompleteMovableStruct());
386
387      // deq contains 4 elements
388      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
389      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
390      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
391      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
392
393      // Following test violate requirements to sequiences (23.1.1 Table 67)
394      /*
395      deq.insert(deq.begin() + 2, deq.begin(), deq.end());
396
397      // deq contains 8 elements
398      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
399      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
400      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
401      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
402      */
403
404      CompleteMovableStruct::reset();
405      deque<CompleteMovableStruct> d2 = deq;
406
407      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
408      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
409      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
410      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
411
412      CompleteMovableStruct::reset();
413      deq.insert(deq.begin() + 2, d2.begin(), d2.end());
414
415      // deq contains 8 elements
416      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
417      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
418#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
419      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 2 );
420#else
421      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 2 );
422#endif
423      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
424
425      CompleteMovableStruct::reset();
426      deq.erase(deq.begin() + 1, deq.begin() + 3);
427
428      // deq contains 6 elements
429#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
430      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
431#else
432      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
433#endif
434      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
435
436      CompleteMovableStruct::reset();
437      deq.erase(deq.end() - 3, deq.end() - 1);
438
439      // deq contains 4 elements
440#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
441      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
442#else
443      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
444#endif
445      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
446
447      CompleteMovableStruct::reset();
448      deq.erase(deq.begin());
449
450      // deq contains 3 elements
451      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
452      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 0 );
453      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
454
455      CompleteMovableStruct::reset();
456    }
457    //deq with 3 elements and v2 with 4 elements are now out of scope
458    CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
459  }
460}
461