os/ossrv/genericopenlibs/cppstdlib/stl/test/unit/mvctor_test.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
 */
sl@0
     5
sl@0
     6
#include <vector>
sl@0
     7
#include <algorithm>
sl@0
     8
#include <vector>
sl@0
     9
#include <string>
sl@0
    10
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
sl@0
    11
#  include <rope>
sl@0
    12
#endif
sl@0
    13
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
sl@0
    14
#  include <slist>
sl@0
    15
#endif
sl@0
    16
#include <list>
sl@0
    17
#include <deque>
sl@0
    18
#include <set>
sl@0
    19
#include <map>
sl@0
    20
#if defined (STLPORT)
sl@0
    21
#  include <unordered_set>
sl@0
    22
#  include <unordered_map>
sl@0
    23
#endif
sl@0
    24
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
sl@0
    25
#  include <hash_set>
sl@0
    26
#  include <hash_map>
sl@0
    27
#endif
sl@0
    28
#include <queue>
sl@0
    29
#include <stack>
sl@0
    30
//#include <iostream>
sl@0
    31
sl@0
    32
#include "cppunit/cppunit_proxy.h"
sl@0
    33
sl@0
    34
#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
sl@0
    35
using namespace std;
sl@0
    36
#endif
sl@0
    37
sl@0
    38
//
sl@0
    39
// TestCase class
sl@0
    40
//
sl@0
    41
class MoveConstructorTest : public CPPUNIT_NS::TestCase
sl@0
    42
{
sl@0
    43
  CPPUNIT_TEST_SUITE(MoveConstructorTest);
sl@0
    44
  CPPUNIT_TEST(move_construct_test);
sl@0
    45
  CPPUNIT_TEST(deque_test);
sl@0
    46
#if defined (__DMC__)
sl@0
    47
  CPPUNIT_IGNORE;
sl@0
    48
#endif
sl@0
    49
  CPPUNIT_TEST(vector_test);
sl@0
    50
  CPPUNIT_STOP_IGNORE;
sl@0
    51
  CPPUNIT_TEST(move_traits);
sl@0
    52
#if !defined (STLPORT) || defined (_STLP_NO_MOVE_SEMANTIC) || \
sl@0
    53
    defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) || \
sl@0
    54
    defined (__BORLANDC__) || defined (__DMC__)
sl@0
    55
  CPPUNIT_IGNORE;
sl@0
    56
#  endif
sl@0
    57
  CPPUNIT_TEST(movable_declaration)
sl@0
    58
#if defined (__BORLANDC__)
sl@0
    59
  CPPUNIT_STOP_IGNORE;
sl@0
    60
  CPPUNIT_TEST(nb_destructor_calls);
sl@0
    61
#endif
sl@0
    62
  CPPUNIT_TEST_SUITE_END();
sl@0
    63
sl@0
    64
protected:
sl@0
    65
  void move_construct_test();
sl@0
    66
  void deque_test();
sl@0
    67
  void vector_test();
sl@0
    68
  void move_traits();
sl@0
    69
  void movable_declaration();
sl@0
    70
  void nb_destructor_calls();
sl@0
    71
sl@0
    72
  /*
sl@0
    73
  template <class _Container>
sl@0
    74
  void standard_test1(_Container const& ref_cont) {
sl@0
    75
    vector<_Container> vec_cont(1, ref_cont);
sl@0
    76
    typedef typename _Container::value_type value_type;
sl@0
    77
    value_type *pvalue = &(*vec_cont.front().begin());
sl@0
    78
    size_t cur_capacity= vec_cont.capacity();
sl@0
    79
    //force reallocation
sl@0
    80
    while (cur_capacity == vec_cont.capacity()) {
sl@0
    81
      vec_cont.push_back(ref_cont);
sl@0
    82
    }
sl@0
    83
    bool b=( (pvalue==(&(*vec_cont.front().begin()))) );
sl@0
    84
    CPPUNIT_ASSERT(b);
sl@0
    85
  }
sl@0
    86
  */
sl@0
    87
};
sl@0
    88
sl@0
    89
CPPUNIT_TEST_SUITE_REGISTRATION(MoveConstructorTest);
sl@0
    90
sl@0
    91
//
sl@0
    92
// tests implementation
sl@0
    93
//
sl@0
    94
void MoveConstructorTest::move_construct_test()
sl@0
    95
{
sl@0
    96
  //cout << "vector<vector<int>>";
sl@0
    97
  vector<int> const ref_vec(10, 0);
sl@0
    98
  vector<vector<int> > v_v_ints(1, ref_vec);
sl@0
    99
sl@0
   100
  int *pint = &(v_v_ints.front().front());
sl@0
   101
sl@0
   102
  size_t cur_capacity = v_v_ints.capacity();
sl@0
   103
  while (v_v_ints.capacity() <= cur_capacity) {
sl@0
   104
    v_v_ints.push_back(ref_vec);
sl@0
   105
  }
sl@0
   106
sl@0
   107
  //v_v_ints has been resized
sl@0
   108
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   109
  CPPUNIT_ASSERT((pint == &v_v_ints.front().front()));
sl@0
   110
#endif
sl@0
   111
sl@0
   112
  //cout << "vector<vector<int>>::erase";
sl@0
   113
  //We need at least 3 elements:
sl@0
   114
  while (v_v_ints.size() < 3) {
sl@0
   115
    v_v_ints.push_back(ref_vec);
sl@0
   116
  }
sl@0
   117
sl@0
   118
  //We erase the 2nd
sl@0
   119
  pint = &v_v_ints[2].front();
sl@0
   120
  v_v_ints.erase(v_v_ints.begin() + 1);
sl@0
   121
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   122
  CPPUNIT_ASSERT((pint == &v_v_ints[1].front()));
sl@0
   123
#endif
sl@0
   124
sl@0
   125
  //cout << "vector<string>";
sl@0
   126
  string const ref_str("ref string, big enough to be a dynamic one");
sl@0
   127
  vector<string> vec_strs(1, ref_str);
sl@0
   128
sl@0
   129
  char const* pstr = vec_strs.front().c_str();
sl@0
   130
  cur_capacity = vec_strs.capacity();
sl@0
   131
  while (vec_strs.capacity() <= cur_capacity) {
sl@0
   132
    vec_strs.push_back(ref_str);
sl@0
   133
  }
sl@0
   134
sl@0
   135
  //vec_str has been resized
sl@0
   136
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   137
  CPPUNIT_ASSERT((pstr == vec_strs.front().c_str()));
sl@0
   138
#endif
sl@0
   139
sl@0
   140
  //cout << "vector<string>::erase";
sl@0
   141
  //We need at least 3 elements:
sl@0
   142
  while (vec_strs.size() < 3) {
sl@0
   143
    vec_strs.push_back(ref_str);
sl@0
   144
  }
sl@0
   145
sl@0
   146
  //We erase the 2nd
sl@0
   147
  pstr = vec_strs[2].c_str();
sl@0
   148
  vec_strs.erase(vec_strs.begin() + 1);
sl@0
   149
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   150
  CPPUNIT_ASSERT((pstr == vec_strs[1].c_str()));
sl@0
   151
#endif
sl@0
   152
sl@0
   153
  //cout << "swap(vector<int>, vector<int>)";
sl@0
   154
  vector<int> elem1(10, 0), elem2(10, 0);
sl@0
   155
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   156
  int *p1 = &elem1.front();
sl@0
   157
  int *p2 = &elem2.front();
sl@0
   158
#endif
sl@0
   159
  swap(elem1, elem2);
sl@0
   160
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   161
  CPPUNIT_ASSERT(((p1 == &elem2.front()) && (p2 == &elem1.front())));
sl@0
   162
#endif
sl@0
   163
sl@0
   164
  {
sl@0
   165
    vector<bool> bit_vec(5, true);
sl@0
   166
    bit_vec.insert(bit_vec.end(), 5, false);
sl@0
   167
    vector<vector<bool> > v_v_bits(1, bit_vec);
sl@0
   168
sl@0
   169
    /*
sl@0
   170
     * This is a STLport specific test as we are using internal implementation
sl@0
   171
     * details to check that the move has been correctly handled. For other
sl@0
   172
     * STL implementation it is only a compile check.
sl@0
   173
     */
sl@0
   174
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   175
#  if defined (_STLP_DEBUG)
sl@0
   176
    unsigned int *punit = v_v_bits.front().begin()._M_iterator._M_p;
sl@0
   177
#  else
sl@0
   178
    unsigned int *punit = v_v_bits.front().begin()._M_p;
sl@0
   179
#  endif
sl@0
   180
#endif
sl@0
   181
sl@0
   182
    cur_capacity = v_v_bits.capacity();
sl@0
   183
    while (v_v_bits.capacity() <= cur_capacity) {
sl@0
   184
      v_v_bits.push_back(bit_vec);
sl@0
   185
    }
sl@0
   186
sl@0
   187
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   188
    //v_v_bits has been resized
sl@0
   189
#  if defined (_STLP_DEBUG)
sl@0
   190
    CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_iterator._M_p );
sl@0
   191
#  else
sl@0
   192
    CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_p );
sl@0
   193
#  endif
sl@0
   194
#endif
sl@0
   195
  }
sl@0
   196
sl@0
   197
  // zero: don't like this kind of tests
sl@0
   198
  // because of template test function
sl@0
   199
  // we should find another way to provide
sl@0
   200
  // move constructor testing...
sl@0
   201
sl@0
   202
/*
sl@0
   203
  standard_test1(list<int>(10));
sl@0
   204
sl@0
   205
sl@0
   206
  standard_test1(slist<int>(10));
sl@0
   207
sl@0
   208
  standard_test1(deque<int>(10));
sl@0
   209
*/
sl@0
   210
sl@0
   211
  /*
sl@0
   212
  int int_values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
sl@0
   213
sl@0
   214
  set<int> int_set(int_values, int_values + sizeof(in_values) / sizeof(int));
sl@0
   215
  standard_test1(int_set);
sl@0
   216
sl@0
   217
  multiset<int> int_multiset(int_values, int_values + sizeof(in_values) / sizeof(int));
sl@0
   218
  standard_test1(int_multiset);
sl@0
   219
  */
sl@0
   220
sl@0
   221
  /*
sl@0
   222
  CheckFullMoveSupport(string());
sl@0
   223
  CheckFullMoveSupport(vector<int>());
sl@0
   224
  CheckFullMoveSupport(deque<int>());
sl@0
   225
  CheckFullMoveSupport(list<int>());
sl@0
   226
  CheckFullMoveSupport(slist<int>());
sl@0
   227
  */
sl@0
   228
}
sl@0
   229
sl@0
   230
void MoveConstructorTest::deque_test()
sl@0
   231
{
sl@0
   232
  //Check the insert range method.
sl@0
   233
  //To the front:
sl@0
   234
  {
sl@0
   235
#  if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES)
sl@0
   236
    deque<vector<int> > vect_deque;
sl@0
   237
    vector<int*> bufs;
sl@0
   238
    vect_deque.assign(3, vector<int>(10));
sl@0
   239
    bufs.push_back(&vect_deque[0].front());
sl@0
   240
    bufs.push_back(&vect_deque[1].front());
sl@0
   241
    bufs.push_back(&vect_deque[2].front());
sl@0
   242
sl@0
   243
    int nb_insert = 5;
sl@0
   244
    //Initialize to 1 to generate a front insertion:
sl@0
   245
    int pos = 1;
sl@0
   246
    while (nb_insert--) {
sl@0
   247
      vector<vector<int> > vect_vect(2, vector<int>(10));
sl@0
   248
      vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end());
sl@0
   249
      bufs.insert(bufs.begin() + pos, &vect_deque[pos].front());
sl@0
   250
      bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front());
sl@0
   251
      ++pos;
sl@0
   252
    }
sl@0
   253
    CPPUNIT_ASSERT( vect_deque.size() == 13 );
sl@0
   254
#    if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   255
    for (int i = 0; i < 5; ++i) {
sl@0
   256
      CPPUNIT_ASSERT( bufs[i] == &vect_deque[i].front() );
sl@0
   257
      CPPUNIT_ASSERT( bufs[11 - i] == &vect_deque[11 - i].front() );
sl@0
   258
    }
sl@0
   259
#    endif
sl@0
   260
#  endif
sl@0
   261
  }
sl@0
   262
sl@0
   263
  //To the back
sl@0
   264
  {
sl@0
   265
#  if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES)
sl@0
   266
    deque<vector<int> > vect_deque;
sl@0
   267
    vector<int*> bufs;
sl@0
   268
    vect_deque.assign(3, vector<int>(10));
sl@0
   269
    bufs.push_back(&vect_deque[0].front());
sl@0
   270
    bufs.push_back(&vect_deque[1].front());
sl@0
   271
    bufs.push_back(&vect_deque[2].front());
sl@0
   272
sl@0
   273
    int nb_insert = 5;
sl@0
   274
    //Initialize to 2 to generate a back insertion:
sl@0
   275
    int pos = 2;
sl@0
   276
    while (nb_insert--) {
sl@0
   277
      vector<vector<int> > vect_vect(2, vector<int>(10));
sl@0
   278
      vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end());
sl@0
   279
      bufs.insert(bufs.begin() + pos, &vect_deque[pos].front());
sl@0
   280
      bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front());
sl@0
   281
      ++pos;
sl@0
   282
    }
sl@0
   283
    CPPUNIT_ASSERT( vect_deque.size() == 13 );
sl@0
   284
#    if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   285
    for (int i = 0; i < 5; ++i) {
sl@0
   286
      CPPUNIT_ASSERT( bufs[i + 1] == &vect_deque[i + 1].front() );
sl@0
   287
      CPPUNIT_ASSERT( bufs[12 - i] == &vect_deque[12 - i].front() );
sl@0
   288
    }
sl@0
   289
#    endif
sl@0
   290
#  endif
sl@0
   291
  }
sl@0
   292
sl@0
   293
  //Check the different erase methods.
sl@0
   294
  {
sl@0
   295
    deque<vector<int> > vect_deque;
sl@0
   296
    vect_deque.assign(20, vector<int>(10));
sl@0
   297
    deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end());
sl@0
   298
    vector<int*> bufs;
sl@0
   299
    for (; vdit != vditEnd; ++vdit) {
sl@0
   300
      bufs.push_back(&vdit->front());
sl@0
   301
    }
sl@0
   302
sl@0
   303
    {
sl@0
   304
      // This check, repeated after each operation, check the deque consistency:
sl@0
   305
      deque<vector<int> >::iterator it = vect_deque.end() - 5;
sl@0
   306
      int nb_incr = 0;
sl@0
   307
      for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
sl@0
   308
      CPPUNIT_ASSERT( nb_incr == 5 );
sl@0
   309
    }
sl@0
   310
sl@0
   311
    {
sl@0
   312
      //erase in front:
sl@0
   313
      vect_deque.erase(vect_deque.begin() + 2);
sl@0
   314
      bufs.erase(bufs.begin() + 2);
sl@0
   315
      CPPUNIT_ASSERT( vect_deque.size() == 19 );
sl@0
   316
      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
sl@0
   317
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   318
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   319
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   320
      }
sl@0
   321
#endif
sl@0
   322
    }
sl@0
   323
sl@0
   324
    {
sl@0
   325
      deque<vector<int> >::iterator it = vect_deque.end() - 5;
sl@0
   326
      int nb_incr = 0;
sl@0
   327
      for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
sl@0
   328
      CPPUNIT_ASSERT( nb_incr == 5 );
sl@0
   329
    }
sl@0
   330
sl@0
   331
    {
sl@0
   332
      //erase in the back:
sl@0
   333
      vect_deque.erase(vect_deque.end() - 2);
sl@0
   334
      bufs.erase(bufs.end() - 2);
sl@0
   335
      CPPUNIT_ASSERT( vect_deque.size() == 18 );
sl@0
   336
      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
sl@0
   337
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   338
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   339
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   340
      }
sl@0
   341
#endif
sl@0
   342
    }
sl@0
   343
sl@0
   344
    {
sl@0
   345
      deque<vector<int> >::iterator it = vect_deque.end() - 5;
sl@0
   346
      int nb_incr = 0;
sl@0
   347
      for (; it != vect_deque.end() && nb_incr < 6; ++nb_incr, ++it) {}
sl@0
   348
      CPPUNIT_ASSERT( nb_incr == 5 );
sl@0
   349
    }
sl@0
   350
sl@0
   351
    {
sl@0
   352
      //range erase in front
sl@0
   353
      vect_deque.erase(vect_deque.begin() + 3, vect_deque.begin() + 5);
sl@0
   354
      bufs.erase(bufs.begin() + 3, bufs.begin() + 5);
sl@0
   355
      CPPUNIT_ASSERT( vect_deque.size() == 16 );
sl@0
   356
      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
sl@0
   357
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   358
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   359
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   360
      }
sl@0
   361
#endif
sl@0
   362
    }
sl@0
   363
sl@0
   364
    {
sl@0
   365
      deque<vector<int> >::iterator it = vect_deque.end() - 5;
sl@0
   366
      int nb_incr = 0;
sl@0
   367
      for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
sl@0
   368
      CPPUNIT_ASSERT( nb_incr == 5 );
sl@0
   369
    }
sl@0
   370
sl@0
   371
    {
sl@0
   372
      //range erase in back
sl@0
   373
      vect_deque.erase(vect_deque.end() - 5, vect_deque.end() - 3);
sl@0
   374
      bufs.erase(bufs.end() - 5, bufs.end() - 3);
sl@0
   375
      CPPUNIT_ASSERT( vect_deque.size() == 14 );
sl@0
   376
      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
sl@0
   377
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   378
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   379
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   380
      }
sl@0
   381
#endif
sl@0
   382
    }
sl@0
   383
  }
sl@0
   384
sl@0
   385
  //Check the insert value(s)
sl@0
   386
  {
sl@0
   387
    deque<vector<int> > vect_deque;
sl@0
   388
    vect_deque.assign(20, vector<int>(10));
sl@0
   389
    deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end());
sl@0
   390
    vector<int*> bufs;
sl@0
   391
    for (; vdit != vditEnd; ++vdit) {
sl@0
   392
      bufs.push_back(&vdit->front());
sl@0
   393
    }
sl@0
   394
sl@0
   395
    {
sl@0
   396
      //2 values in front:
sl@0
   397
      vect_deque.insert(vect_deque.begin() + 2, 2, vector<int>(10));
sl@0
   398
      bufs.insert(bufs.begin() + 2, &vect_deque[2].front());
sl@0
   399
      bufs.insert(bufs.begin() + 3, &vect_deque[3].front());
sl@0
   400
      CPPUNIT_ASSERT( vect_deque.size() == 22 );
sl@0
   401
      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
sl@0
   402
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   403
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   404
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   405
      }
sl@0
   406
#endif
sl@0
   407
    }
sl@0
   408
sl@0
   409
    {
sl@0
   410
      //2 values in back:
sl@0
   411
      vect_deque.insert(vect_deque.end() - 2, 2, vector<int>(10));
sl@0
   412
      bufs.insert(bufs.end() - 2, &vect_deque[20].front());
sl@0
   413
      bufs.insert(bufs.end() - 2, &vect_deque[21].front());
sl@0
   414
      CPPUNIT_ASSERT( vect_deque.size() == 24 );
sl@0
   415
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   416
      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
sl@0
   417
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   418
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   419
      }
sl@0
   420
#endif
sl@0
   421
    }
sl@0
   422
sl@0
   423
    {
sl@0
   424
      //1 value in front:
sl@0
   425
      deque<vector<int> >::iterator ret;
sl@0
   426
      ret = vect_deque.insert(vect_deque.begin() + 2, vector<int>(10));
sl@0
   427
      bufs.insert(bufs.begin() + 2, &vect_deque[2].front());
sl@0
   428
      CPPUNIT_ASSERT( vect_deque.size() == 25 );
sl@0
   429
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   430
      CPPUNIT_ASSERT( &ret->front() == bufs[2] );
sl@0
   431
      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
sl@0
   432
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   433
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   434
      }
sl@0
   435
#endif
sl@0
   436
    }
sl@0
   437
sl@0
   438
    {
sl@0
   439
      //1 value in back:
sl@0
   440
      deque<vector<int> >::iterator ret;
sl@0
   441
      ret = vect_deque.insert(vect_deque.end() - 2, vector<int>(10));
sl@0
   442
      bufs.insert(bufs.end() - 2, &vect_deque[23].front());
sl@0
   443
      CPPUNIT_ASSERT( vect_deque.size() == 26 );
sl@0
   444
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   445
      CPPUNIT_ASSERT( &ret->front() == bufs[23] );
sl@0
   446
      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
sl@0
   447
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   448
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   449
      }
sl@0
   450
#endif
sl@0
   451
    }
sl@0
   452
  }
sl@0
   453
}
sl@0
   454
sl@0
   455
void MoveConstructorTest::vector_test()
sl@0
   456
{
sl@0
   457
#if !defined (__DMC__)
sl@0
   458
  //Check the insert range method.
sl@0
   459
  //To the front:
sl@0
   460
  {
sl@0
   461
    vector<vector<int> > vect_vector;
sl@0
   462
    vector<int*> bufs;
sl@0
   463
    vect_vector.assign(3, vector<int>(10));
sl@0
   464
    bufs.push_back(&vect_vector[0].front());
sl@0
   465
    bufs.push_back(&vect_vector[1].front());
sl@0
   466
    bufs.push_back(&vect_vector[2].front());
sl@0
   467
sl@0
   468
    int nb_insert = 5;
sl@0
   469
    int pos = 1;
sl@0
   470
    while (nb_insert--) {
sl@0
   471
      vector<vector<int> > vect_vect(2, vector<int>(10));
sl@0
   472
      vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end());
sl@0
   473
      bufs.insert(bufs.begin() + pos, &vect_vector[pos].front());
sl@0
   474
      bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front());
sl@0
   475
      ++pos;
sl@0
   476
    }
sl@0
   477
    CPPUNIT_ASSERT( vect_vector.size() == 13 );
sl@0
   478
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   479
    for (int i = 0; i < 5; ++i) {
sl@0
   480
      CPPUNIT_ASSERT( bufs[i] == &vect_vector[i].front() );
sl@0
   481
      CPPUNIT_ASSERT( bufs[11 - i] == &vect_vector[11 - i].front() );
sl@0
   482
    }
sl@0
   483
#endif
sl@0
   484
  }
sl@0
   485
sl@0
   486
  //To the back
sl@0
   487
  {
sl@0
   488
    vector<vector<int> > vect_vector;
sl@0
   489
    vector<int*> bufs;
sl@0
   490
    vect_vector.assign(3, vector<int>(10));
sl@0
   491
    bufs.push_back(&vect_vector[0].front());
sl@0
   492
    bufs.push_back(&vect_vector[1].front());
sl@0
   493
    bufs.push_back(&vect_vector[2].front());
sl@0
   494
sl@0
   495
    int nb_insert = 5;
sl@0
   496
    //Initialize to 2 to generate a back insertion:
sl@0
   497
    int pos = 2;
sl@0
   498
    while (nb_insert--) {
sl@0
   499
      vector<vector<int> > vect_vect(2, vector<int>(10));
sl@0
   500
      vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end());
sl@0
   501
      bufs.insert(bufs.begin() + pos, &vect_vector[pos].front());
sl@0
   502
      bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front());
sl@0
   503
      ++pos;
sl@0
   504
    }
sl@0
   505
    CPPUNIT_ASSERT( vect_vector.size() == 13 );
sl@0
   506
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   507
    for (int i = 0; i < 5; ++i) {
sl@0
   508
      CPPUNIT_ASSERT( bufs[i + 1] == &vect_vector[i + 1].front() );
sl@0
   509
      CPPUNIT_ASSERT( bufs[12 - i] == &vect_vector[12 - i].front() );
sl@0
   510
    }
sl@0
   511
#endif
sl@0
   512
  }
sl@0
   513
sl@0
   514
  //Check the different erase methods.
sl@0
   515
  {
sl@0
   516
    vector<vector<int> > vect_vector;
sl@0
   517
    vect_vector.assign(20, vector<int>(10));
sl@0
   518
    vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end());
sl@0
   519
    vector<int*> bufs;
sl@0
   520
    for (; vdit != vditEnd; ++vdit) {
sl@0
   521
      bufs.push_back(&vdit->front());
sl@0
   522
    }
sl@0
   523
sl@0
   524
    {
sl@0
   525
      // This check, repeated after each operation, check the vector consistency:
sl@0
   526
      vector<vector<int> >::iterator it = vect_vector.end() - 5;
sl@0
   527
      int nb_incr = 0;
sl@0
   528
      for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
sl@0
   529
      CPPUNIT_ASSERT( nb_incr == 5 );
sl@0
   530
    }
sl@0
   531
sl@0
   532
    {
sl@0
   533
      //erase in front:
sl@0
   534
      vect_vector.erase(vect_vector.begin() + 2);
sl@0
   535
      bufs.erase(bufs.begin() + 2);
sl@0
   536
      CPPUNIT_ASSERT( vect_vector.size() == 19 );
sl@0
   537
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   538
      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
sl@0
   539
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   540
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   541
      }
sl@0
   542
#endif
sl@0
   543
    }
sl@0
   544
sl@0
   545
    {
sl@0
   546
      vector<vector<int> >::iterator it = vect_vector.end() - 5;
sl@0
   547
      int nb_incr = 0;
sl@0
   548
      for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
sl@0
   549
      CPPUNIT_ASSERT( nb_incr == 5 );
sl@0
   550
    }
sl@0
   551
sl@0
   552
    {
sl@0
   553
      //erase in the back:
sl@0
   554
      vect_vector.erase(vect_vector.end() - 2);
sl@0
   555
      bufs.erase(bufs.end() - 2);
sl@0
   556
      CPPUNIT_ASSERT( vect_vector.size() == 18 );
sl@0
   557
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   558
      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
sl@0
   559
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   560
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   561
      }
sl@0
   562
#endif
sl@0
   563
    }
sl@0
   564
sl@0
   565
    {
sl@0
   566
      vector<vector<int> >::iterator it = vect_vector.end() - 5;
sl@0
   567
      int nb_incr = 0;
sl@0
   568
      for (; it != vect_vector.end() && nb_incr < 6; ++nb_incr, ++it) {}
sl@0
   569
      CPPUNIT_ASSERT( nb_incr == 5 );
sl@0
   570
    }
sl@0
   571
sl@0
   572
    {
sl@0
   573
      //range erase in front
sl@0
   574
      vect_vector.erase(vect_vector.begin() + 3, vect_vector.begin() + 5);
sl@0
   575
      bufs.erase(bufs.begin() + 3, bufs.begin() + 5);
sl@0
   576
      CPPUNIT_ASSERT( vect_vector.size() == 16 );
sl@0
   577
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   578
      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
sl@0
   579
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   580
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   581
      }
sl@0
   582
#endif
sl@0
   583
    }
sl@0
   584
sl@0
   585
    {
sl@0
   586
      vector<vector<int> >::iterator it = vect_vector.end() - 5;
sl@0
   587
      int nb_incr = 0;
sl@0
   588
      for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
sl@0
   589
      CPPUNIT_ASSERT( nb_incr == 5 );
sl@0
   590
    }
sl@0
   591
sl@0
   592
    {
sl@0
   593
      //range erase in back
sl@0
   594
      vect_vector.erase(vect_vector.end() - 5, vect_vector.end() - 3);
sl@0
   595
      bufs.erase(bufs.end() - 5, bufs.end() - 3);
sl@0
   596
      CPPUNIT_ASSERT( vect_vector.size() == 14 );
sl@0
   597
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   598
      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
sl@0
   599
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   600
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   601
      }
sl@0
   602
#endif
sl@0
   603
    }
sl@0
   604
  }
sl@0
   605
sl@0
   606
  //Check the insert value(s)
sl@0
   607
  {
sl@0
   608
    vector<vector<int> > vect_vector;
sl@0
   609
    vect_vector.assign(20, vector<int>(10));
sl@0
   610
    vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end());
sl@0
   611
    vector<int*> bufs;
sl@0
   612
    for (; vdit != vditEnd; ++vdit) {
sl@0
   613
      bufs.push_back(&vdit->front());
sl@0
   614
    }
sl@0
   615
sl@0
   616
    {
sl@0
   617
      //2 values in front:
sl@0
   618
      vect_vector.insert(vect_vector.begin() + 2, 2, vector<int>(10));
sl@0
   619
      bufs.insert(bufs.begin() + 2, &vect_vector[2].front());
sl@0
   620
      bufs.insert(bufs.begin() + 3, &vect_vector[3].front());
sl@0
   621
      CPPUNIT_ASSERT( vect_vector.size() == 22 );
sl@0
   622
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   623
      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
sl@0
   624
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   625
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   626
      }
sl@0
   627
#endif
sl@0
   628
    }
sl@0
   629
sl@0
   630
    {
sl@0
   631
      //2 values in back:
sl@0
   632
      vect_vector.insert(vect_vector.end() - 2, 2, vector<int>(10));
sl@0
   633
      bufs.insert(bufs.end() - 2, &vect_vector[20].front());
sl@0
   634
      bufs.insert(bufs.end() - 2, &vect_vector[21].front());
sl@0
   635
      CPPUNIT_ASSERT( vect_vector.size() == 24 );
sl@0
   636
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   637
      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
sl@0
   638
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   639
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   640
      }
sl@0
   641
#endif
sl@0
   642
    }
sl@0
   643
sl@0
   644
    {
sl@0
   645
      //1 value in front:
sl@0
   646
      vector<vector<int> >::iterator ret;
sl@0
   647
      ret = vect_vector.insert(vect_vector.begin() + 2, vector<int>(10));
sl@0
   648
      bufs.insert(bufs.begin() + 2, &vect_vector[2].front());
sl@0
   649
      CPPUNIT_ASSERT( vect_vector.size() == 25 );
sl@0
   650
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   651
      CPPUNIT_ASSERT( &ret->front() == bufs[2] );
sl@0
   652
      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
sl@0
   653
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   654
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   655
      }
sl@0
   656
#endif
sl@0
   657
    }
sl@0
   658
sl@0
   659
    {
sl@0
   660
      //1 value in back:
sl@0
   661
      vector<vector<int> >::iterator ret;
sl@0
   662
      ret = vect_vector.insert(vect_vector.end() - 2, vector<int>(10));
sl@0
   663
      bufs.insert(bufs.end() - 2, &vect_vector[23].front());
sl@0
   664
      CPPUNIT_ASSERT( vect_vector.size() == 26 );
sl@0
   665
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   666
      CPPUNIT_ASSERT( &ret->front() == bufs[23] );
sl@0
   667
      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
sl@0
   668
      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
sl@0
   669
        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
sl@0
   670
      }
sl@0
   671
#endif
sl@0
   672
    }
sl@0
   673
  }
sl@0
   674
sl@0
   675
  //The following tests are checking move contructor implementations:
sl@0
   676
  const string long_str("long enough string to force dynamic allocation");
sl@0
   677
  {
sl@0
   678
    //vector move contructor:
sl@0
   679
    vector<vector<string> > vect(10, vector<string>(10, long_str));
sl@0
   680
    vector<string> strs;
sl@0
   681
    size_t index = 0;
sl@0
   682
    while (true) {
sl@0
   683
      vector<vector<string> >::iterator it(vect.begin());
sl@0
   684
      advance(it, index % vect.size());
sl@0
   685
      strs.push_back(it->front());
sl@0
   686
      it->erase(it->begin());
sl@0
   687
      if (it->empty()) {
sl@0
   688
        vect.erase(it);
sl@0
   689
        if (vect.empty())
sl@0
   690
          break;
sl@0
   691
      }
sl@0
   692
      index += 3;
sl@0
   693
    }
sl@0
   694
    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
sl@0
   695
    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
sl@0
   696
    for (; it != itEnd; ++it) {
sl@0
   697
      CPPUNIT_ASSERT( *it == long_str );
sl@0
   698
    }
sl@0
   699
  }
sl@0
   700
sl@0
   701
  {
sl@0
   702
    //deque move contructor:
sl@0
   703
    vector<deque<string> > vect(10, deque<string>(10, long_str));
sl@0
   704
    vector<string> strs;
sl@0
   705
    size_t index = 0;
sl@0
   706
    while (true) {
sl@0
   707
      vector<deque<string> >::iterator it(vect.begin());
sl@0
   708
      advance(it, index % vect.size());
sl@0
   709
      strs.push_back(it->front());
sl@0
   710
      it->pop_front();
sl@0
   711
      if (it->empty()) {
sl@0
   712
        vect.erase(it);
sl@0
   713
        if (vect.empty())
sl@0
   714
          break;
sl@0
   715
      }
sl@0
   716
      index += 3;
sl@0
   717
    }
sl@0
   718
    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
sl@0
   719
    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
sl@0
   720
    for (; it != itEnd; ++it) {
sl@0
   721
      CPPUNIT_ASSERT( *it == long_str );
sl@0
   722
    }
sl@0
   723
  }
sl@0
   724
sl@0
   725
  {
sl@0
   726
    //list move contructor:
sl@0
   727
    vector<list<string> > vect(10, list<string>(10, long_str));
sl@0
   728
    vector<string> strs;
sl@0
   729
    size_t index = 0;
sl@0
   730
    while (true) {
sl@0
   731
      vector<list<string> >::iterator it(vect.begin());
sl@0
   732
      advance(it, index % vect.size());
sl@0
   733
      strs.push_back(it->front());
sl@0
   734
      it->pop_front();
sl@0
   735
      if (it->empty()) {
sl@0
   736
        vect.erase(it);
sl@0
   737
        if (vect.empty())
sl@0
   738
          break;
sl@0
   739
      }
sl@0
   740
      index += 3;
sl@0
   741
    }
sl@0
   742
    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
sl@0
   743
    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
sl@0
   744
    for (; it != itEnd; ++it) {
sl@0
   745
      CPPUNIT_ASSERT( *it == long_str );
sl@0
   746
    }
sl@0
   747
  }
sl@0
   748
sl@0
   749
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
sl@0
   750
  {
sl@0
   751
    //slist move contructor:
sl@0
   752
    vector<slist<string> > vect(10, slist<string>(10, long_str));
sl@0
   753
    vector<string> strs;
sl@0
   754
    size_t index = 0;
sl@0
   755
    while (true) {
sl@0
   756
      vector<slist<string> >::iterator it(vect.begin());
sl@0
   757
      advance(it, index % vect.size());
sl@0
   758
      strs.push_back(it->front());
sl@0
   759
      it->pop_front();
sl@0
   760
      if (it->empty()) {
sl@0
   761
        vect.erase(it);
sl@0
   762
        if (vect.empty())
sl@0
   763
          break;
sl@0
   764
      }
sl@0
   765
      index += 3;
sl@0
   766
    }
sl@0
   767
    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
sl@0
   768
    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
sl@0
   769
    for (; it != itEnd; ++it) {
sl@0
   770
      CPPUNIT_ASSERT( *it == long_str );
sl@0
   771
    }
sl@0
   772
  }
sl@0
   773
#endif
sl@0
   774
sl@0
   775
  {
sl@0
   776
    //binary tree move contructor:
sl@0
   777
    multiset<string> ref;
sl@0
   778
    for (size_t i = 0; i < 10; ++i) {
sl@0
   779
      ref.insert(long_str);
sl@0
   780
    }
sl@0
   781
    vector<multiset<string> > vect(10, ref);
sl@0
   782
    vector<string> strs;
sl@0
   783
    size_t index = 0;
sl@0
   784
    while (true) {
sl@0
   785
      vector<multiset<string> >::iterator it(vect.begin());
sl@0
   786
      advance(it, index % vect.size());
sl@0
   787
      strs.push_back(*it->begin());
sl@0
   788
      it->erase(it->begin());
sl@0
   789
      if (it->empty()) {
sl@0
   790
        vect.erase(it);
sl@0
   791
        if (vect.empty())
sl@0
   792
          break;
sl@0
   793
      }
sl@0
   794
      index += 3;
sl@0
   795
    }
sl@0
   796
    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
sl@0
   797
    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
sl@0
   798
    for (; it != itEnd; ++it) {
sl@0
   799
      CPPUNIT_ASSERT( *it == long_str );
sl@0
   800
    }
sl@0
   801
  }
sl@0
   802
#  endif /* __DMC__ */
sl@0
   803
sl@0
   804
#if defined (STLPORT)
sl@0
   805
#  if !defined (__BORLANDC__) && !defined (__DMC__)
sl@0
   806
  {
sl@0
   807
    //hash container move contructor:
sl@0
   808
    unordered_multiset<string> ref;
sl@0
   809
    for (size_t i = 0; i < 10; ++i) {
sl@0
   810
      ref.insert(long_str);
sl@0
   811
    }
sl@0
   812
    vector<unordered_multiset<string> > vect(10, ref);
sl@0
   813
    vector<string> strs;
sl@0
   814
    size_t index = 0;
sl@0
   815
    while (true) {
sl@0
   816
      vector<unordered_multiset<string> >::iterator it(vect.begin());
sl@0
   817
      advance(it, index % vect.size());
sl@0
   818
      strs.push_back(*it->begin());
sl@0
   819
      it->erase(it->begin());
sl@0
   820
      if (it->empty()) {
sl@0
   821
        vect.erase(it);
sl@0
   822
        if (vect.empty())
sl@0
   823
          break;
sl@0
   824
      }
sl@0
   825
      index += 3;
sl@0
   826
    }
sl@0
   827
    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
sl@0
   828
    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
sl@0
   829
    for (; it != itEnd; ++it) {
sl@0
   830
      CPPUNIT_ASSERT( *it == long_str );
sl@0
   831
    }
sl@0
   832
  }
sl@0
   833
#  endif
sl@0
   834
#endif
sl@0
   835
}
sl@0
   836
sl@0
   837
struct MovableStruct {
sl@0
   838
  MovableStruct() { ++nb_dft_construct_call; }
sl@0
   839
  MovableStruct(MovableStruct const&) { ++nb_cpy_construct_call; }
sl@0
   840
#  if defined (STLPORT)
sl@0
   841
  MovableStruct(__move_source<MovableStruct>) { ++nb_mv_construct_call; }
sl@0
   842
#  endif
sl@0
   843
  ~MovableStruct() { ++nb_destruct_call; }
sl@0
   844
sl@0
   845
  MovableStruct& operator = (const MovableStruct&) {
sl@0
   846
    ++nb_assignment_call;
sl@0
   847
    return *this;
sl@0
   848
  }
sl@0
   849
sl@0
   850
  static void reset() {
sl@0
   851
    nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
sl@0
   852
    nb_assignment_call = 0;
sl@0
   853
    nb_destruct_call = 0;
sl@0
   854
  }
sl@0
   855
sl@0
   856
  static size_t nb_dft_construct_call;
sl@0
   857
  static size_t nb_cpy_construct_call;
sl@0
   858
  static size_t nb_mv_construct_call;
sl@0
   859
  static size_t nb_assignment_call;
sl@0
   860
  static size_t nb_destruct_call;
sl@0
   861
sl@0
   862
  //Dummy data just to control struct sizeof
sl@0
   863
  //As node allocator implementation align memory blocks on 2 * sizeof(void*)
sl@0
   864
  //we give MovableStruct the same size in order to have expected allocation
sl@0
   865
  //and not more
sl@0
   866
  void* dummy_data[2];
sl@0
   867
};
sl@0
   868
sl@0
   869
size_t MovableStruct::nb_dft_construct_call = 0;
sl@0
   870
size_t MovableStruct::nb_cpy_construct_call = 0;
sl@0
   871
size_t MovableStruct::nb_mv_construct_call = 0;
sl@0
   872
size_t MovableStruct::nb_assignment_call = 0;
sl@0
   873
size_t MovableStruct::nb_destruct_call = 0;
sl@0
   874
sl@0
   875
#  if defined (STLPORT)
sl@0
   876
namespace std {
sl@0
   877
  _STLP_TEMPLATE_NULL
sl@0
   878
  struct __move_traits<MovableStruct> {
sl@0
   879
    typedef __true_type implemented;
sl@0
   880
    typedef __false_type complete;
sl@0
   881
  };
sl@0
   882
}
sl@0
   883
#  endif
sl@0
   884
sl@0
   885
struct CompleteMovableStruct {
sl@0
   886
  CompleteMovableStruct() { ++nb_dft_construct_call; }
sl@0
   887
  CompleteMovableStruct(CompleteMovableStruct const&) { ++nb_cpy_construct_call; }
sl@0
   888
#  if defined (STLPORT)
sl@0
   889
  CompleteMovableStruct(__move_source<CompleteMovableStruct>) { ++nb_mv_construct_call; }
sl@0
   890
#  endif
sl@0
   891
  ~CompleteMovableStruct() { ++nb_destruct_call; }
sl@0
   892
sl@0
   893
  CompleteMovableStruct& operator = (const CompleteMovableStruct&) {
sl@0
   894
    ++nb_assignment_call;
sl@0
   895
    return *this;
sl@0
   896
  }
sl@0
   897
  static void reset() {
sl@0
   898
    nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
sl@0
   899
    nb_assignment_call = 0;
sl@0
   900
    nb_destruct_call = 0;
sl@0
   901
  }
sl@0
   902
sl@0
   903
  static size_t nb_dft_construct_call;
sl@0
   904
  static size_t nb_cpy_construct_call;
sl@0
   905
  static size_t nb_mv_construct_call;
sl@0
   906
  static size_t nb_assignment_call;
sl@0
   907
  static size_t nb_destruct_call;
sl@0
   908
sl@0
   909
  //See MovableStruct
sl@0
   910
  void* dummy_data[2];
sl@0
   911
};
sl@0
   912
sl@0
   913
size_t CompleteMovableStruct::nb_dft_construct_call = 0;
sl@0
   914
size_t CompleteMovableStruct::nb_cpy_construct_call = 0;
sl@0
   915
size_t CompleteMovableStruct::nb_mv_construct_call = 0;
sl@0
   916
size_t CompleteMovableStruct::nb_assignment_call = 0;
sl@0
   917
size_t CompleteMovableStruct::nb_destruct_call = 0;
sl@0
   918
sl@0
   919
#  if defined (STLPORT)
sl@0
   920
namespace std {
sl@0
   921
  _STLP_TEMPLATE_NULL
sl@0
   922
  struct __move_traits<CompleteMovableStruct> {
sl@0
   923
    typedef __true_type implemented;
sl@0
   924
    typedef __true_type complete;
sl@0
   925
  };
sl@0
   926
}
sl@0
   927
#  endif
sl@0
   928
sl@0
   929
void MoveConstructorTest::move_traits()
sl@0
   930
{
sl@0
   931
  {
sl@0
   932
    {
sl@0
   933
      vector<MovableStruct> vect;
sl@0
   934
      vect.push_back(MovableStruct());
sl@0
   935
      vect.push_back(MovableStruct());
sl@0
   936
      vect.push_back(MovableStruct());
sl@0
   937
      vect.push_back(MovableStruct());
sl@0
   938
sl@0
   939
      // vect contains 4 elements
sl@0
   940
      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
sl@0
   941
#if defined (STLPORT)
sl@0
   942
#  if !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   943
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
sl@0
   944
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
sl@0
   945
#  else
sl@0
   946
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
sl@0
   947
#  endif
sl@0
   948
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
sl@0
   949
#elif !defined (_MSC_VER)
sl@0
   950
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
sl@0
   951
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
sl@0
   952
#else
sl@0
   953
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 14 );
sl@0
   954
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 14 );
sl@0
   955
#endif
sl@0
   956
      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
sl@0
   957
sl@0
   958
      // Following test violate requirements to sequiences (23.1.1 Table 67)
sl@0
   959
      /*
sl@0
   960
      vect.insert(vect.begin() + 2, vect.begin(), vect.end());
sl@0
   961
      // vect contains 8 elements
sl@0
   962
      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
sl@0
   963
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
sl@0
   964
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
sl@0
   965
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
sl@0
   966
      */
sl@0
   967
sl@0
   968
      MovableStruct::reset();
sl@0
   969
      vector<MovableStruct> v2 = vect;
sl@0
   970
      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
sl@0
   971
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
sl@0
   972
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
sl@0
   973
      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
sl@0
   974
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
sl@0
   975
sl@0
   976
      MovableStruct::reset();
sl@0
   977
      vect.insert(vect.begin() + 2, v2.begin(), v2.end() );
sl@0
   978
sl@0
   979
      // vect contains 8 elements
sl@0
   980
      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
sl@0
   981
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   982
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
sl@0
   983
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 4 );
sl@0
   984
#else
sl@0
   985
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
sl@0
   986
#endif
sl@0
   987
      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
sl@0
   988
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
sl@0
   989
sl@0
   990
      MovableStruct::reset();
sl@0
   991
      vect.erase(vect.begin(), vect.begin() + 2 );
sl@0
   992
sl@0
   993
      // vect contains 6 elements
sl@0
   994
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
   995
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 6 );
sl@0
   996
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 8 );
sl@0
   997
#else
sl@0
   998
      CPPUNIT_ASSERT_EQUAL( MovableStruct::nb_assignment_call, 6 );
sl@0
   999
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
sl@0
  1000
#endif
sl@0
  1001
sl@0
  1002
      MovableStruct::reset();
sl@0
  1003
      vect.erase(vect.end() - 2, vect.end());
sl@0
  1004
sl@0
  1005
      // vect contains 4 elements
sl@0
  1006
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
sl@0
  1007
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
sl@0
  1008
sl@0
  1009
      MovableStruct::reset();
sl@0
  1010
      vect.erase(vect.begin());
sl@0
  1011
sl@0
  1012
      // vect contains 3 elements
sl@0
  1013
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1014
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
sl@0
  1015
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
sl@0
  1016
#else
sl@0
  1017
      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 3 );
sl@0
  1018
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
sl@0
  1019
#endif
sl@0
  1020
sl@0
  1021
      MovableStruct::reset();
sl@0
  1022
    }
sl@0
  1023
    //vect with 3 elements and v2 with 4 elements are now out of scope
sl@0
  1024
    CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
sl@0
  1025
  }
sl@0
  1026
sl@0
  1027
  {
sl@0
  1028
    {
sl@0
  1029
      vector<CompleteMovableStruct> vect;
sl@0
  1030
      vect.push_back(CompleteMovableStruct());
sl@0
  1031
      vect.push_back(CompleteMovableStruct());
sl@0
  1032
      vect.push_back(CompleteMovableStruct());
sl@0
  1033
      vect.push_back(CompleteMovableStruct());
sl@0
  1034
sl@0
  1035
      // vect contains 4 elements
sl@0
  1036
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
sl@0
  1037
#if defined (STLPORT)
sl@0
  1038
#  if !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1039
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1040
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
sl@0
  1041
#  else
sl@0
  1042
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
sl@0
  1043
#  endif
sl@0
  1044
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
sl@0
  1045
#elif !defined (_MSC_VER)
sl@0
  1046
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
sl@0
  1047
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 7 );
sl@0
  1048
#else
sl@0
  1049
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 14 );
sl@0
  1050
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 14 );
sl@0
  1051
#endif
sl@0
  1052
sl@0
  1053
      // Following test violate requirements to sequiences (23.1.1 Table 67)
sl@0
  1054
      /*
sl@0
  1055
      vect.insert(vect.begin() + 2, vect.begin(), vect.end());
sl@0
  1056
sl@0
  1057
      // vect contains 8 elements
sl@0
  1058
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
sl@0
  1059
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
sl@0
  1060
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
sl@0
  1061
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
sl@0
  1062
      */
sl@0
  1063
sl@0
  1064
      CompleteMovableStruct::reset();
sl@0
  1065
      vector<CompleteMovableStruct> v2 = vect;
sl@0
  1066
sl@0
  1067
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
sl@0
  1068
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1069
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
sl@0
  1070
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
sl@0
  1071
sl@0
  1072
      CompleteMovableStruct::reset();
sl@0
  1073
      vect.insert(vect.begin() + 2, v2.begin(), v2.end());
sl@0
  1074
sl@0
  1075
      // vect contains 8 elements
sl@0
  1076
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
sl@0
  1077
#if defined (STLPORT)
sl@0
  1078
#  if !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1079
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1080
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 4 );
sl@0
  1081
#  else
sl@0
  1082
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
sl@0
  1083
#  endif
sl@0
  1084
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
sl@0
  1085
#else
sl@0
  1086
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
sl@0
  1087
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
sl@0
  1088
#endif
sl@0
  1089
sl@0
  1090
      CompleteMovableStruct::reset();
sl@0
  1091
      vect.erase(vect.begin(), vect.begin() + 2);
sl@0
  1092
sl@0
  1093
      // vect contains 6 elements
sl@0
  1094
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1095
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 6 );
sl@0
  1096
#else
sl@0
  1097
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 6 );
sl@0
  1098
#endif
sl@0
  1099
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
sl@0
  1100
sl@0
  1101
      CompleteMovableStruct::reset();
sl@0
  1102
      vect.erase(vect.end() - 2, vect.end());
sl@0
  1103
sl@0
  1104
      // vect contains 4 elements
sl@0
  1105
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
sl@0
  1106
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
sl@0
  1107
sl@0
  1108
      CompleteMovableStruct::reset();
sl@0
  1109
      vect.erase(vect.begin());
sl@0
  1110
sl@0
  1111
      // vect contains 3 elements
sl@0
  1112
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1113
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
sl@0
  1114
#else
sl@0
  1115
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 3 );
sl@0
  1116
#endif
sl@0
  1117
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
sl@0
  1118
sl@0
  1119
      CompleteMovableStruct::reset();
sl@0
  1120
    }
sl@0
  1121
    //vect with 3 elements and v2 with 4 elements are now out of scope
sl@0
  1122
    CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
sl@0
  1123
  }
sl@0
  1124
sl@0
  1125
  {
sl@0
  1126
    MovableStruct::reset();
sl@0
  1127
    {
sl@0
  1128
      deque<MovableStruct> deq;
sl@0
  1129
      deq.push_back(MovableStruct());
sl@0
  1130
      deq.push_back(MovableStruct());
sl@0
  1131
      deq.push_back(MovableStruct());
sl@0
  1132
      deq.push_back(MovableStruct());
sl@0
  1133
sl@0
  1134
      // deq contains 4 elements
sl@0
  1135
      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
sl@0
  1136
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1137
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
sl@0
  1138
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
sl@0
  1139
sl@0
  1140
      // Following test violate requirements to sequiences (23.1.1 Table 67)
sl@0
  1141
      /*
sl@0
  1142
      deq.insert(deq.begin() + 2, deq.begin(), deq.end());
sl@0
  1143
      // deq contains 8 elements
sl@0
  1144
      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
sl@0
  1145
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
sl@0
  1146
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
sl@0
  1147
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
sl@0
  1148
      */
sl@0
  1149
sl@0
  1150
      MovableStruct::reset();
sl@0
  1151
      deque<MovableStruct> d2 = deq;
sl@0
  1152
sl@0
  1153
      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
sl@0
  1154
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1155
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
sl@0
  1156
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
sl@0
  1157
sl@0
  1158
      MovableStruct::reset();
sl@0
  1159
      deq.insert(deq.begin() + 2, d2.begin(), d2.end() );
sl@0
  1160
sl@0
  1161
      // deq contains 8 elements
sl@0
  1162
      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
sl@0
  1163
      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1164
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1165
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 2 );
sl@0
  1166
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
sl@0
  1167
#else
sl@0
  1168
      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 2 );
sl@0
  1169
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
sl@0
  1170
#endif
sl@0
  1171
sl@0
  1172
      MovableStruct::reset();
sl@0
  1173
      deq.erase(deq.begin() + 1, deq.begin() + 3 );
sl@0
  1174
sl@0
  1175
      // deq contains 6 elements
sl@0
  1176
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1177
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
sl@0
  1178
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
sl@0
  1179
#else
sl@0
  1180
      //Following check is highly deque implementation dependant so
sl@0
  1181
      //it might not always work...
sl@0
  1182
      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
sl@0
  1183
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
sl@0
  1184
#endif
sl@0
  1185
sl@0
  1186
      MovableStruct::reset();
sl@0
  1187
      deq.erase(deq.end() - 3, deq.end() - 1);
sl@0
  1188
sl@0
  1189
      // deq contains 4 elements
sl@0
  1190
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1191
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
sl@0
  1192
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
sl@0
  1193
#else
sl@0
  1194
      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
sl@0
  1195
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
sl@0
  1196
#endif
sl@0
  1197
sl@0
  1198
      MovableStruct::reset();
sl@0
  1199
      deq.erase(deq.begin());
sl@0
  1200
sl@0
  1201
      // deq contains 3 elements
sl@0
  1202
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1203
      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
sl@0
  1204
#else
sl@0
  1205
      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
sl@0
  1206
#endif
sl@0
  1207
      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
sl@0
  1208
sl@0
  1209
      MovableStruct::reset();
sl@0
  1210
    }
sl@0
  1211
    //deq with 3 elements and d2 with 4 elements are now out of scope
sl@0
  1212
    CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
sl@0
  1213
  }
sl@0
  1214
sl@0
  1215
  {
sl@0
  1216
    CompleteMovableStruct::reset();
sl@0
  1217
    {
sl@0
  1218
      deque<CompleteMovableStruct> deq;
sl@0
  1219
      deq.push_back(CompleteMovableStruct());
sl@0
  1220
      deq.push_back(CompleteMovableStruct());
sl@0
  1221
      deq.push_back(CompleteMovableStruct());
sl@0
  1222
      deq.push_back(CompleteMovableStruct());
sl@0
  1223
sl@0
  1224
      // deq contains 4 elements
sl@0
  1225
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
sl@0
  1226
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1227
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
sl@0
  1228
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
sl@0
  1229
sl@0
  1230
      // Following test violate requirements to sequiences (23.1.1 Table 67)
sl@0
  1231
      /*
sl@0
  1232
      deq.insert(deq.begin() + 2, deq.begin(), deq.end());
sl@0
  1233
sl@0
  1234
      // deq contains 8 elements
sl@0
  1235
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
sl@0
  1236
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
sl@0
  1237
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
sl@0
  1238
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
sl@0
  1239
      */
sl@0
  1240
sl@0
  1241
      CompleteMovableStruct::reset();
sl@0
  1242
      deque<CompleteMovableStruct> d2 = deq;
sl@0
  1243
sl@0
  1244
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
sl@0
  1245
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1246
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
sl@0
  1247
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
sl@0
  1248
sl@0
  1249
      CompleteMovableStruct::reset();
sl@0
  1250
      deq.insert(deq.begin() + 2, d2.begin(), d2.end());
sl@0
  1251
sl@0
  1252
      // deq contains 8 elements
sl@0
  1253
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
sl@0
  1254
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
sl@0
  1255
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1256
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 2 );
sl@0
  1257
#else
sl@0
  1258
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 2 );
sl@0
  1259
#endif
sl@0
  1260
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
sl@0
  1261
sl@0
  1262
      CompleteMovableStruct::reset();
sl@0
  1263
      deq.erase(deq.begin() + 1, deq.begin() + 3);
sl@0
  1264
sl@0
  1265
      // deq contains 6 elements
sl@0
  1266
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1267
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
sl@0
  1268
#else
sl@0
  1269
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
sl@0
  1270
#endif
sl@0
  1271
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
sl@0
  1272
sl@0
  1273
      CompleteMovableStruct::reset();
sl@0
  1274
      deq.erase(deq.end() - 3, deq.end() - 1);
sl@0
  1275
sl@0
  1276
      // deq contains 4 elements
sl@0
  1277
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
sl@0
  1278
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
sl@0
  1279
#else
sl@0
  1280
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
sl@0
  1281
#endif
sl@0
  1282
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
sl@0
  1283
sl@0
  1284
      CompleteMovableStruct::reset();
sl@0
  1285
      deq.erase(deq.begin());
sl@0
  1286
sl@0
  1287
      // deq contains 3 elements
sl@0
  1288
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
sl@0
  1289
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 0 );
sl@0
  1290
      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
sl@0
  1291
sl@0
  1292
      CompleteMovableStruct::reset();
sl@0
  1293
    }
sl@0
  1294
    //deq with 3 elements and v2 with 4 elements are now out of scope
sl@0
  1295
    CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
sl@0
  1296
  }
sl@0
  1297
}
sl@0
  1298
sl@0
  1299
#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 
sl@0
  1300
sl@0
  1301
#  if defined (__GNUC__) && defined (_STLP_USE_NAMESPACES)
sl@0
  1302
// libstdc++ sometimes exposed its own __true_type in
sl@0
  1303
// global namespace resulting in an ambiguity.
sl@0
  1304
#    define __true_type std::__true_type
sl@0
  1305
#    define __false_type std::__false_type
sl@0
  1306
#  endif
sl@0
  1307
sl@0
  1308
static bool type_to_bool(__true_type)
sl@0
  1309
{ return true; }
sl@0
  1310
static bool type_to_bool(__false_type)
sl@0
  1311
{ return false; }
sl@0
  1312
sl@0
  1313
template <class _Tp>
sl@0
  1314
static bool is_movable(const _Tp&) {
sl@0
  1315
#if defined (__BORLANDC__) || defined (__SYMBIAN32__)
sl@0
  1316
  return __type2bool<typename __move_traits<_Tp>::implemented>::_Ret != 0;
sl@0
  1317
#else
sl@0
  1318
  typedef typename __move_traits<_Tp>::implemented _MovableTp;
sl@0
  1319
  return type_to_bool(_MovableTp());
sl@0
  1320
#endif
sl@0
  1321
}
sl@0
  1322
sl@0
  1323
template <class _Tp>
sl@0
  1324
static bool is_move_complete(const _Tp&) {
sl@0
  1325
  typedef __move_traits<_Tp> _TpMoveTraits;
sl@0
  1326
#if defined (__BORLANDC__) || defined (__SYMBIAN32__)
sl@0
  1327
  return __type2bool<typename __move_traits<_Tp>::complete>::_Ret != 0;
sl@0
  1328
#else
sl@0
  1329
  typedef typename _TpMoveTraits::complete _TpMoveComplete;
sl@0
  1330
  return type_to_bool(_TpMoveComplete());
sl@0
  1331
#endif
sl@0
  1332
}
sl@0
  1333
sl@0
  1334
struct specially_allocated_struct {
sl@0
  1335
  bool operator < (specially_allocated_struct) const;
sl@0
  1336
};
sl@0
  1337
sl@0
  1338
struct struct_with_specialized_less {};
sl@0
  1339
sl@0
  1340
namespace std
sl@0
  1341
{
sl@0
  1342
  _STLP_TEMPLATE_NULL
sl@0
  1343
  class allocator<specially_allocated_struct>
sl@0
  1344
  {
sl@0
  1345
    //This allocator just represent what a STLport could do and in this
sl@0
  1346
    //case the STL containers implemented with it should still be movable
sl@0
  1347
    //but not completely as we cannot do any hypothesis on what is in this
sl@0
  1348
    //allocator.
sl@0
  1349
  public:
sl@0
  1350
    typedef specially_allocated_struct value_type;
sl@0
  1351
    typedef value_type *       pointer;
sl@0
  1352
    typedef const value_type* const_pointer;
sl@0
  1353
    typedef value_type&       reference;
sl@0
  1354
    typedef const value_type& const_reference;
sl@0
  1355
    typedef size_t     size_type;
sl@0
  1356
    typedef ptrdiff_t  difference_type;
sl@0
  1357
#if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
sl@0
  1358
    template <class _Tp1> struct rebind {
sl@0
  1359
      typedef allocator<_Tp1> other;
sl@0
  1360
    };
sl@0
  1361
#endif
sl@0
  1362
    allocator() _STLP_NOTHROW {}
sl@0
  1363
#if defined (_STLP_MEMBER_TEMPLATES)
sl@0
  1364
    template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
sl@0
  1365
#endif
sl@0
  1366
    allocator(const allocator&) _STLP_NOTHROW {}
sl@0
  1367
    ~allocator() _STLP_NOTHROW {}
sl@0
  1368
    pointer address(reference __x) const { return &__x; }
sl@0
  1369
    const_pointer address(const_reference __x) const { return &__x; }
sl@0
  1370
    pointer allocate(size_type, const void* = 0) { return 0; }
sl@0
  1371
    void deallocate(pointer, size_type) {}
sl@0
  1372
    size_type max_size() const _STLP_NOTHROW  { return 0; }
sl@0
  1373
    void construct(pointer, const_reference) {}
sl@0
  1374
    void destroy(pointer) {}
sl@0
  1375
  };
sl@0
  1376
sl@0
  1377
  _STLP_TEMPLATE_NULL
sl@0
  1378
  struct less<struct_with_specialized_less> {
sl@0
  1379
    bool operator() (struct_with_specialized_less const&,
sl@0
  1380
                     struct_with_specialized_less const&) const;
sl@0
  1381
  };
sl@0
  1382
}
sl@0
  1383
#endif
sl@0
  1384
sl@0
  1385
void MoveConstructorTest::movable_declaration()
sl@0
  1386
{
sl@0
  1387
#if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
sl@0
  1388
                         !defined (_STLP_NO_MOVE_SEMANTIC) && \
sl@0
  1389
   !defined (__DMC__)
sl@0
  1390
  //This test purpose is to check correct detection of the STL movable
sl@0
  1391
  //traits declaration
sl@0
  1392
  {
sl@0
  1393
    //string, wstring:
sl@0
  1394
    CPPUNIT_ASSERT( is_movable(string()) );
sl@0
  1395
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1396
    CPPUNIT_ASSERT( is_move_complete(string()) );
sl@0
  1397
#    else
sl@0
  1398
    CPPUNIT_ASSERT( !is_move_complete(string()) );
sl@0
  1399
#    endif
sl@0
  1400
#    if defined (_STLP_HAS_WCHAR_T)
sl@0
  1401
    CPPUNIT_ASSERT( is_movable(wstring()) );
sl@0
  1402
#      if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1403
    CPPUNIT_ASSERT( is_move_complete(wstring()) );
sl@0
  1404
#      else
sl@0
  1405
    CPPUNIT_ASSERT( !is_move_complete(wstring()) );
sl@0
  1406
#      endif
sl@0
  1407
#    endif
sl@0
  1408
  }
sl@0
  1409
sl@0
  1410
#    if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
sl@0
  1411
  {
sl@0
  1412
    //crope, wrope:
sl@0
  1413
    CPPUNIT_ASSERT( is_movable(crope()) );
sl@0
  1414
#      if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1415
    CPPUNIT_ASSERT( is_move_complete(crope()) );
sl@0
  1416
#      else
sl@0
  1417
    CPPUNIT_ASSERT( !is_move_complete(crope()) );
sl@0
  1418
#      endif
sl@0
  1419
#      if defined (_STLP_HAS_WCHAR_T)
sl@0
  1420
    CPPUNIT_ASSERT( is_movable(wrope()) );
sl@0
  1421
#        if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1422
    CPPUNIT_ASSERT( is_move_complete(wrope()) );
sl@0
  1423
#        else
sl@0
  1424
    CPPUNIT_ASSERT( !is_move_complete(wrope()) );
sl@0
  1425
#        endif
sl@0
  1426
#      endif
sl@0
  1427
  }
sl@0
  1428
#    endif
sl@0
  1429
sl@0
  1430
  {
sl@0
  1431
    //vector:
sl@0
  1432
    CPPUNIT_ASSERT( is_movable(vector<char>()) );
sl@0
  1433
    CPPUNIT_ASSERT( is_movable(vector<specially_allocated_struct>()) );
sl@0
  1434
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1435
    CPPUNIT_ASSERT( is_move_complete(vector<char>()) );
sl@0
  1436
    CPPUNIT_ASSERT( !is_move_complete(vector<specially_allocated_struct>()) );
sl@0
  1437
#    else
sl@0
  1438
    CPPUNIT_ASSERT( !is_move_complete(vector<char>()) );
sl@0
  1439
#    endif
sl@0
  1440
  }
sl@0
  1441
sl@0
  1442
  {
sl@0
  1443
    //deque:
sl@0
  1444
    CPPUNIT_ASSERT( is_movable(deque<char>()) );
sl@0
  1445
    CPPUNIT_ASSERT( is_movable(deque<specially_allocated_struct>()) );
sl@0
  1446
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1447
    CPPUNIT_ASSERT( is_move_complete(deque<char>()) );
sl@0
  1448
    CPPUNIT_ASSERT( !is_move_complete(deque<specially_allocated_struct>()) );
sl@0
  1449
#    else
sl@0
  1450
    CPPUNIT_ASSERT( !is_move_complete(deque<char>()) );
sl@0
  1451
#    endif
sl@0
  1452
  }
sl@0
  1453
sl@0
  1454
  {
sl@0
  1455
    //list:
sl@0
  1456
    CPPUNIT_ASSERT( is_movable(list<char>()) );
sl@0
  1457
    CPPUNIT_ASSERT( is_movable(list<specially_allocated_struct>()) );
sl@0
  1458
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1459
    CPPUNIT_ASSERT( is_move_complete(list<char>()) );
sl@0
  1460
    CPPUNIT_ASSERT( !is_move_complete(list<specially_allocated_struct>()) );
sl@0
  1461
#    else
sl@0
  1462
    CPPUNIT_ASSERT( !is_move_complete(list<char>()) );
sl@0
  1463
#    endif
sl@0
  1464
  }
sl@0
  1465
sl@0
  1466
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
sl@0
  1467
  {
sl@0
  1468
    //slist:
sl@0
  1469
    CPPUNIT_ASSERT( is_movable(slist<char>()) );
sl@0
  1470
    CPPUNIT_ASSERT( is_movable(slist<specially_allocated_struct>()) );
sl@0
  1471
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1472
    CPPUNIT_ASSERT( is_move_complete(slist<char>()) );
sl@0
  1473
    CPPUNIT_ASSERT( !is_move_complete(slist<specially_allocated_struct>()) );
sl@0
  1474
#    else
sl@0
  1475
    CPPUNIT_ASSERT( !is_move_complete(slist<char>()) );
sl@0
  1476
#    endif
sl@0
  1477
  }
sl@0
  1478
#endif
sl@0
  1479
sl@0
  1480
  {
sl@0
  1481
    //queue:
sl@0
  1482
    CPPUNIT_ASSERT( is_movable(queue<char>()) );
sl@0
  1483
    CPPUNIT_ASSERT( is_movable(queue<specially_allocated_struct>()) );
sl@0
  1484
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1485
    CPPUNIT_ASSERT( is_move_complete(queue<char>()) );
sl@0
  1486
    CPPUNIT_ASSERT( !is_move_complete(queue<specially_allocated_struct>()) );
sl@0
  1487
#    else
sl@0
  1488
    CPPUNIT_ASSERT( !is_move_complete(queue<char>()) );
sl@0
  1489
#    endif
sl@0
  1490
  }
sl@0
  1491
sl@0
  1492
  {
sl@0
  1493
    //stack:
sl@0
  1494
    CPPUNIT_ASSERT( is_movable(stack<char>()) );
sl@0
  1495
    CPPUNIT_ASSERT( is_movable(stack<specially_allocated_struct>()) );
sl@0
  1496
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1497
    CPPUNIT_ASSERT( is_move_complete(stack<char>()) );
sl@0
  1498
    CPPUNIT_ASSERT( !is_move_complete(stack<specially_allocated_struct>()) );
sl@0
  1499
#    else
sl@0
  1500
    CPPUNIT_ASSERT( !is_move_complete(stack<char>()) );
sl@0
  1501
#    endif
sl@0
  1502
  }
sl@0
  1503
sl@0
  1504
  {
sl@0
  1505
    //associative containers, set multiset, map, multimap:
sl@0
  1506
sl@0
  1507
    //For associative containers it is important that less is correctly recognize as
sl@0
  1508
    //the STLport less or a user specialized less:
sl@0
  1509
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1510
    CPPUNIT_ASSERT( is_move_complete(less<char>()) );
sl@0
  1511
#    endif
sl@0
  1512
    CPPUNIT_ASSERT( !is_move_complete(less<struct_with_specialized_less>()) );
sl@0
  1513
sl@0
  1514
    //set
sl@0
  1515
    CPPUNIT_ASSERT( is_movable(set<char>()) );
sl@0
  1516
    CPPUNIT_ASSERT( is_movable(set<specially_allocated_struct>()) );
sl@0
  1517
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1518
    CPPUNIT_ASSERT( is_move_complete(set<char>()) );
sl@0
  1519
    CPPUNIT_ASSERT( !is_move_complete(set<specially_allocated_struct>()) );
sl@0
  1520
#    else
sl@0
  1521
    CPPUNIT_ASSERT( !is_move_complete(set<char>()) );
sl@0
  1522
#    endif
sl@0
  1523
sl@0
  1524
    //multiset
sl@0
  1525
    CPPUNIT_ASSERT( is_movable(multiset<char>()) );
sl@0
  1526
    CPPUNIT_ASSERT( is_movable(multiset<specially_allocated_struct>()) );
sl@0
  1527
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1528
    CPPUNIT_ASSERT( is_move_complete(multiset<char>()) );
sl@0
  1529
    CPPUNIT_ASSERT( !is_move_complete(multiset<specially_allocated_struct>()) );
sl@0
  1530
#    else
sl@0
  1531
    CPPUNIT_ASSERT( !is_move_complete(multiset<char>()) );
sl@0
  1532
#    endif
sl@0
  1533
sl@0
  1534
    //map
sl@0
  1535
    CPPUNIT_ASSERT( is_movable(map<char, char>()) );
sl@0
  1536
    CPPUNIT_ASSERT( is_movable(map<specially_allocated_struct, char>()) );
sl@0
  1537
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1538
    CPPUNIT_ASSERT( is_move_complete(map<char, char>()) );
sl@0
  1539
    //Here even if allocator has been specialized for specially_allocated_struct
sl@0
  1540
    //this pecialization won't be used in default map instanciation as the default
sl@0
  1541
    //allocator is allocator<pair<specially_allocated_struct, char> >
sl@0
  1542
    CPPUNIT_ASSERT( is_move_complete(map<specially_allocated_struct, char>()) );
sl@0
  1543
#    else
sl@0
  1544
    CPPUNIT_ASSERT( !is_move_complete(map<char, char>()) );
sl@0
  1545
#    endif
sl@0
  1546
sl@0
  1547
    //multimap
sl@0
  1548
    CPPUNIT_ASSERT( is_movable(multimap<char, char>()) );
sl@0
  1549
    CPPUNIT_ASSERT( is_movable(multimap<specially_allocated_struct, char>()) );
sl@0
  1550
#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
sl@0
  1551
    CPPUNIT_ASSERT( is_move_complete(multimap<char, char>()) );
sl@0
  1552
    //Idem map remark
sl@0
  1553
    CPPUNIT_ASSERT( is_move_complete(multimap<specially_allocated_struct, char>()) );
sl@0
  1554
#    else
sl@0
  1555
    CPPUNIT_ASSERT( !is_move_complete(multimap<char, char>()) );
sl@0
  1556
#    endif
sl@0
  1557
  }
sl@0
  1558
sl@0
  1559
#    if defined (STLPORT)
sl@0
  1560
  {
sl@0
  1561
    //hashed containers, unordered_set unordered_multiset, unordered_map, unordered_multimap,
sl@0
  1562
    //                   hash_set, hash_multiset, hash_map, hash_multimap:
sl@0
  1563
sl@0
  1564
    //We only check that they are movable, completness is not yet supported
sl@0
  1565
    CPPUNIT_ASSERT( is_movable(unordered_set<char>()) );
sl@0
  1566
    CPPUNIT_ASSERT( is_movable(unordered_multiset<char>()) );
sl@0
  1567
    CPPUNIT_ASSERT( is_movable(unordered_map<char, char>()) );
sl@0
  1568
    CPPUNIT_ASSERT( is_movable(unordered_multimap<char, char>()) );
sl@0
  1569
#      if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
sl@0
  1570
    CPPUNIT_ASSERT( is_movable(hash_set<char>()) );
sl@0
  1571
    CPPUNIT_ASSERT( is_movable(hash_multiset<char>()) );
sl@0
  1572
    CPPUNIT_ASSERT( is_movable(hash_map<char, char>()) );
sl@0
  1573
    CPPUNIT_ASSERT( is_movable(hash_multimap<char, char>()) );
sl@0
  1574
#      endif
sl@0
  1575
  }
sl@0
  1576
#    endif
sl@0
  1577
#  endif
sl@0
  1578
}
sl@0
  1579
sl@0
  1580
#if defined (__BORLANDC__)
sl@0
  1581
/* Specific Borland test case to show a really weird compiler behavior.
sl@0
  1582
 */
sl@0
  1583
class Standalone
sl@0
  1584
{
sl@0
  1585
public:
sl@0
  1586
  //Uncomment following to pass the test
sl@0
  1587
  //Standalone() {}
sl@0
  1588
  ~Standalone() {}
sl@0
  1589
sl@0
  1590
  MovableStruct movableStruct;
sl@0
  1591
  vector<int> intVector;
sl@0
  1592
};
sl@0
  1593
sl@0
  1594
void MoveConstructorTest::nb_destructor_calls()
sl@0
  1595
{
sl@0
  1596
  MovableStruct::reset();
sl@0
  1597
sl@0
  1598
  try
sl@0
  1599
  {
sl@0
  1600
    Standalone standalone;
sl@0
  1601
    throw "some exception";
sl@0
  1602
    MovableStruct movableStruct;
sl@0
  1603
  }
sl@0
  1604
  catch (const char*)
sl@0
  1605
  {
sl@0
  1606
    CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 1 );
sl@0
  1607
    CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
sl@0
  1608
  }
sl@0
  1609
}
sl@0
  1610
#endif