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