genericopenlibs/cppstdlib/stl/test/unit/mvctor_test.cpp
changeset 31 ce057bb09d0b
child 34 5fae379060a7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/cppstdlib/stl/test/unit/mvctor_test.cpp	Fri Jun 04 16:20:51 2010 +0100
@@ -0,0 +1,1623 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include <vector>
+#include <algorithm>
+#include <vector>
+#include <string>
+#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
+#  include <rope>
+#endif
+#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
+#  include <slist>
+#endif
+#include <list>
+#include <deque>
+#include <set>
+#include <map>
+#if defined (STLPORT)
+#  include <unordered_set>
+#  include <unordered_map>
+#endif
+#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
+#  include <hash_set>
+#  include <hash_map>
+#endif
+#include <queue>
+#include <stack>
+//#include <iostream>
+
+#include "cppunit/cppunit_proxy.h"
+
+#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
+using namespace std;
+#endif
+
+//
+// TestCase class
+//
+class MoveConstructorTest : public CPPUNIT_NS::TestCase
+{
+  CPPUNIT_TEST_SUITE(MoveConstructorTest);
+  CPPUNIT_TEST(move_construct_test);
+  CPPUNIT_TEST(deque_test);
+#if defined (__DMC__)
+  CPPUNIT_IGNORE;
+#endif
+  CPPUNIT_TEST(vector_test);
+  CPPUNIT_STOP_IGNORE;
+  CPPUNIT_TEST(move_traits);
+#if !defined (STLPORT) || defined (_STLP_NO_MOVE_SEMANTIC) || \
+    defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) || \
+    defined (__BORLANDC__) || defined (__DMC__)
+  CPPUNIT_IGNORE;
+#  endif
+  CPPUNIT_TEST(movable_declaration)
+#if defined (__BORLANDC__)
+  CPPUNIT_STOP_IGNORE;
+  CPPUNIT_TEST(nb_destructor_calls);
+#endif
+  CPPUNIT_TEST_SUITE_END();
+
+protected:
+  void move_construct_test();
+  void deque_test();
+  void vector_test();
+  void move_traits();
+  void movable_declaration();
+  void nb_destructor_calls();
+
+  /*
+  template <class _Container>
+  void standard_test1(_Container const& ref_cont) {
+    vector<_Container> vec_cont(1, ref_cont);
+    typedef typename _Container::value_type value_type;
+    value_type *pvalue = &(*vec_cont.front().begin());
+    size_t cur_capacity= vec_cont.capacity();
+    //force reallocation
+    while (cur_capacity == vec_cont.capacity()) {
+      vec_cont.push_back(ref_cont);
+    }
+    bool b=( (pvalue==(&(*vec_cont.front().begin()))) );
+    CPPUNIT_ASSERT(b);
+  }
+  */
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(MoveConstructorTest);
+
+//
+// tests implementation
+//
+void MoveConstructorTest::move_construct_test()
+{
+  //cout << "vector<vector<int>>";
+  vector<int> const ref_vec(10, 0);
+  vector<vector<int> > v_v_ints(1, ref_vec);
+
+  int *pint = &(v_v_ints.front().front());
+
+  size_t cur_capacity = v_v_ints.capacity();
+  while (v_v_ints.capacity() <= cur_capacity) {
+    v_v_ints.push_back(ref_vec);
+  }
+
+  //v_v_ints has been resized
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+  CPPUNIT_ASSERT((pint == &v_v_ints.front().front()));
+#endif
+
+  //cout << "vector<vector<int>>::erase";
+  //We need at least 3 elements:
+  while (v_v_ints.size() < 3) {
+    v_v_ints.push_back(ref_vec);
+  }
+
+  //We erase the 2nd
+  pint = &v_v_ints[2].front();
+  v_v_ints.erase(v_v_ints.begin() + 1);
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+  CPPUNIT_ASSERT((pint == &v_v_ints[1].front()));
+#endif
+
+  //cout << "vector<string>";
+  string const ref_str("ref string, big enough to be a dynamic one");
+  vector<string> vec_strs(1, ref_str);
+
+  char const* pstr = vec_strs.front().c_str();
+  cur_capacity = vec_strs.capacity();
+  while (vec_strs.capacity() <= cur_capacity) {
+    vec_strs.push_back(ref_str);
+  }
+
+  //vec_str has been resized
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+  CPPUNIT_ASSERT((pstr == vec_strs.front().c_str()));
+#endif
+
+  //cout << "vector<string>::erase";
+  //We need at least 3 elements:
+  while (vec_strs.size() < 3) {
+    vec_strs.push_back(ref_str);
+  }
+
+  //We erase the 2nd
+  pstr = vec_strs[2].c_str();
+  vec_strs.erase(vec_strs.begin() + 1);
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+  CPPUNIT_ASSERT((pstr == vec_strs[1].c_str()));
+#endif
+
+  //cout << "swap(vector<int>, vector<int>)";
+  vector<int> elem1(10, 0), elem2(10, 0);
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+  int *p1 = &elem1.front();
+  int *p2 = &elem2.front();
+#endif
+  swap(elem1, elem2);
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+  CPPUNIT_ASSERT(((p1 == &elem2.front()) && (p2 == &elem1.front())));
+#endif
+
+  {
+    vector<bool> bit_vec(5, true);
+    bit_vec.insert(bit_vec.end(), 5, false);
+    vector<vector<bool> > v_v_bits(1, bit_vec);
+
+    /*
+     * This is a STLport specific test as we are using internal implementation
+     * details to check that the move has been correctly handled. For other
+     * STL implementation it is only a compile check.
+     */
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+#  if defined (_STLP_DEBUG)
+    unsigned int *punit = v_v_bits.front().begin()._M_iterator._M_p;
+#  else
+    unsigned int *punit = v_v_bits.front().begin()._M_p;
+#  endif
+#endif
+
+    cur_capacity = v_v_bits.capacity();
+    while (v_v_bits.capacity() <= cur_capacity) {
+      v_v_bits.push_back(bit_vec);
+    }
+
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+    //v_v_bits has been resized
+#  if defined (_STLP_DEBUG)
+    CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_iterator._M_p );
+#  else
+    CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_p );
+#  endif
+#endif
+  }
+
+  // zero: don't like this kind of tests
+  // because of template test function
+  // we should find another way to provide
+  // move constructor testing...
+
+/*
+  standard_test1(list<int>(10));
+
+
+  standard_test1(slist<int>(10));
+
+  standard_test1(deque<int>(10));
+*/
+
+  /*
+  int int_values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+  set<int> int_set(int_values, int_values + sizeof(in_values) / sizeof(int));
+  standard_test1(int_set);
+
+  multiset<int> int_multiset(int_values, int_values + sizeof(in_values) / sizeof(int));
+  standard_test1(int_multiset);
+  */
+
+  /*
+  CheckFullMoveSupport(string());
+  CheckFullMoveSupport(vector<int>());
+  CheckFullMoveSupport(deque<int>());
+  CheckFullMoveSupport(list<int>());
+  CheckFullMoveSupport(slist<int>());
+  */
+}
+
+void MoveConstructorTest::deque_test()
+{
+  //Check the insert range method.
+  //To the front:
+  {
+#  if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES)
+    deque<vector<int> > vect_deque;
+    vector<int*> bufs;
+    vect_deque.assign(3, vector<int>(10));
+    bufs.push_back(&vect_deque[0].front());
+    bufs.push_back(&vect_deque[1].front());
+    bufs.push_back(&vect_deque[2].front());
+
+    int nb_insert = 5;
+    //Initialize to 1 to generate a front insertion:
+    int pos = 1;
+    while (nb_insert--) {
+      vector<vector<int> > vect_vect(2, vector<int>(10));
+      vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end());
+      bufs.insert(bufs.begin() + pos, &vect_deque[pos].front());
+      bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front());
+      ++pos;
+    }
+    CPPUNIT_ASSERT( vect_deque.size() == 13 );
+#    if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+    for (int i = 0; i < 5; ++i) {
+      CPPUNIT_ASSERT( bufs[i] == &vect_deque[i].front() );
+      CPPUNIT_ASSERT( bufs[11 - i] == &vect_deque[11 - i].front() );
+    }
+#    endif
+#  endif
+  }
+
+  //To the back
+  {
+#  if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES)
+    deque<vector<int> > vect_deque;
+    vector<int*> bufs;
+    vect_deque.assign(3, vector<int>(10));
+    bufs.push_back(&vect_deque[0].front());
+    bufs.push_back(&vect_deque[1].front());
+    bufs.push_back(&vect_deque[2].front());
+
+    int nb_insert = 5;
+    //Initialize to 2 to generate a back insertion:
+    int pos = 2;
+    while (nb_insert--) {
+      vector<vector<int> > vect_vect(2, vector<int>(10));
+      vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end());
+      bufs.insert(bufs.begin() + pos, &vect_deque[pos].front());
+      bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front());
+      ++pos;
+    }
+    CPPUNIT_ASSERT( vect_deque.size() == 13 );
+#    if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+    for (int i = 0; i < 5; ++i) {
+      CPPUNIT_ASSERT( bufs[i + 1] == &vect_deque[i + 1].front() );
+      CPPUNIT_ASSERT( bufs[12 - i] == &vect_deque[12 - i].front() );
+    }
+#    endif
+#  endif
+  }
+
+  //Check the different erase methods.
+  {
+    deque<vector<int> > vect_deque;
+    vect_deque.assign(20, vector<int>(10));
+    deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end());
+    vector<int*> bufs;
+    for (; vdit != vditEnd; ++vdit) {
+      bufs.push_back(&vdit->front());
+    }
+
+    {
+      // This check, repeated after each operation, check the deque consistency:
+      deque<vector<int> >::iterator it = vect_deque.end() - 5;
+      int nb_incr = 0;
+      for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
+      CPPUNIT_ASSERT( nb_incr == 5 );
+    }
+
+    {
+      //erase in front:
+      vect_deque.erase(vect_deque.begin() + 2);
+      bufs.erase(bufs.begin() + 2);
+      CPPUNIT_ASSERT( vect_deque.size() == 19 );
+      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      deque<vector<int> >::iterator it = vect_deque.end() - 5;
+      int nb_incr = 0;
+      for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
+      CPPUNIT_ASSERT( nb_incr == 5 );
+    }
+
+    {
+      //erase in the back:
+      vect_deque.erase(vect_deque.end() - 2);
+      bufs.erase(bufs.end() - 2);
+      CPPUNIT_ASSERT( vect_deque.size() == 18 );
+      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      deque<vector<int> >::iterator it = vect_deque.end() - 5;
+      int nb_incr = 0;
+      for (; it != vect_deque.end() && nb_incr < 6; ++nb_incr, ++it) {}
+      CPPUNIT_ASSERT( nb_incr == 5 );
+    }
+
+    {
+      //range erase in front
+      vect_deque.erase(vect_deque.begin() + 3, vect_deque.begin() + 5);
+      bufs.erase(bufs.begin() + 3, bufs.begin() + 5);
+      CPPUNIT_ASSERT( vect_deque.size() == 16 );
+      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      deque<vector<int> >::iterator it = vect_deque.end() - 5;
+      int nb_incr = 0;
+      for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
+      CPPUNIT_ASSERT( nb_incr == 5 );
+    }
+
+    {
+      //range erase in back
+      vect_deque.erase(vect_deque.end() - 5, vect_deque.end() - 3);
+      bufs.erase(bufs.end() - 5, bufs.end() - 3);
+      CPPUNIT_ASSERT( vect_deque.size() == 14 );
+      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+  }
+
+  //Check the insert value(s)
+  {
+    deque<vector<int> > vect_deque;
+    vect_deque.assign(20, vector<int>(10));
+    deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end());
+    vector<int*> bufs;
+    for (; vdit != vditEnd; ++vdit) {
+      bufs.push_back(&vdit->front());
+    }
+
+    {
+      //2 values in front:
+      vect_deque.insert(vect_deque.begin() + 2, 2, vector<int>(10));
+      bufs.insert(bufs.begin() + 2, &vect_deque[2].front());
+      bufs.insert(bufs.begin() + 3, &vect_deque[3].front());
+      CPPUNIT_ASSERT( vect_deque.size() == 22 );
+      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      //2 values in back:
+      vect_deque.insert(vect_deque.end() - 2, 2, vector<int>(10));
+      bufs.insert(bufs.end() - 2, &vect_deque[20].front());
+      bufs.insert(bufs.end() - 2, &vect_deque[21].front());
+      CPPUNIT_ASSERT( vect_deque.size() == 24 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      //1 value in front:
+      deque<vector<int> >::iterator ret;
+      ret = vect_deque.insert(vect_deque.begin() + 2, vector<int>(10));
+      bufs.insert(bufs.begin() + 2, &vect_deque[2].front());
+      CPPUNIT_ASSERT( vect_deque.size() == 25 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( &ret->front() == bufs[2] );
+      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      //1 value in back:
+      deque<vector<int> >::iterator ret;
+      ret = vect_deque.insert(vect_deque.end() - 2, vector<int>(10));
+      bufs.insert(bufs.end() - 2, &vect_deque[23].front());
+      CPPUNIT_ASSERT( vect_deque.size() == 26 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( &ret->front() == bufs[23] );
+      deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+  }
+}
+
+void MoveConstructorTest::vector_test()
+{
+#if !defined (__DMC__)
+  //Check the insert range method.
+  //To the front:
+  {
+    vector<vector<int> > vect_vector;
+    vector<int*> bufs;
+    vect_vector.assign(3, vector<int>(10));
+    bufs.push_back(&vect_vector[0].front());
+    bufs.push_back(&vect_vector[1].front());
+    bufs.push_back(&vect_vector[2].front());
+
+    int nb_insert = 5;
+    int pos = 1;
+    while (nb_insert--) {
+      vector<vector<int> > vect_vect(2, vector<int>(10));
+      vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end());
+      bufs.insert(bufs.begin() + pos, &vect_vector[pos].front());
+      bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front());
+      ++pos;
+    }
+    CPPUNIT_ASSERT( vect_vector.size() == 13 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+    for (int i = 0; i < 5; ++i) {
+      CPPUNIT_ASSERT( bufs[i] == &vect_vector[i].front() );
+      CPPUNIT_ASSERT( bufs[11 - i] == &vect_vector[11 - i].front() );
+    }
+#endif
+  }
+
+  //To the back
+  {
+    vector<vector<int> > vect_vector;
+    vector<int*> bufs;
+    vect_vector.assign(3, vector<int>(10));
+    bufs.push_back(&vect_vector[0].front());
+    bufs.push_back(&vect_vector[1].front());
+    bufs.push_back(&vect_vector[2].front());
+
+    int nb_insert = 5;
+    //Initialize to 2 to generate a back insertion:
+    int pos = 2;
+    while (nb_insert--) {
+      vector<vector<int> > vect_vect(2, vector<int>(10));
+      vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end());
+      bufs.insert(bufs.begin() + pos, &vect_vector[pos].front());
+      bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front());
+      ++pos;
+    }
+    CPPUNIT_ASSERT( vect_vector.size() == 13 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+    for (int i = 0; i < 5; ++i) {
+      CPPUNIT_ASSERT( bufs[i + 1] == &vect_vector[i + 1].front() );
+      CPPUNIT_ASSERT( bufs[12 - i] == &vect_vector[12 - i].front() );
+    }
+#endif
+  }
+
+  //Check the different erase methods.
+  {
+    vector<vector<int> > vect_vector;
+    vect_vector.assign(20, vector<int>(10));
+    vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end());
+    vector<int*> bufs;
+    for (; vdit != vditEnd; ++vdit) {
+      bufs.push_back(&vdit->front());
+    }
+
+    {
+      // This check, repeated after each operation, check the vector consistency:
+      vector<vector<int> >::iterator it = vect_vector.end() - 5;
+      int nb_incr = 0;
+      for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
+      CPPUNIT_ASSERT( nb_incr == 5 );
+    }
+
+    {
+      //erase in front:
+      vect_vector.erase(vect_vector.begin() + 2);
+      bufs.erase(bufs.begin() + 2);
+      CPPUNIT_ASSERT( vect_vector.size() == 19 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      vector<vector<int> >::iterator it = vect_vector.end() - 5;
+      int nb_incr = 0;
+      for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
+      CPPUNIT_ASSERT( nb_incr == 5 );
+    }
+
+    {
+      //erase in the back:
+      vect_vector.erase(vect_vector.end() - 2);
+      bufs.erase(bufs.end() - 2);
+      CPPUNIT_ASSERT( vect_vector.size() == 18 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      vector<vector<int> >::iterator it = vect_vector.end() - 5;
+      int nb_incr = 0;
+      for (; it != vect_vector.end() && nb_incr < 6; ++nb_incr, ++it) {}
+      CPPUNIT_ASSERT( nb_incr == 5 );
+    }
+
+    {
+      //range erase in front
+      vect_vector.erase(vect_vector.begin() + 3, vect_vector.begin() + 5);
+      bufs.erase(bufs.begin() + 3, bufs.begin() + 5);
+      CPPUNIT_ASSERT( vect_vector.size() == 16 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      vector<vector<int> >::iterator it = vect_vector.end() - 5;
+      int nb_incr = 0;
+      for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
+      CPPUNIT_ASSERT( nb_incr == 5 );
+    }
+
+    {
+      //range erase in back
+      vect_vector.erase(vect_vector.end() - 5, vect_vector.end() - 3);
+      bufs.erase(bufs.end() - 5, bufs.end() - 3);
+      CPPUNIT_ASSERT( vect_vector.size() == 14 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+  }
+
+  //Check the insert value(s)
+  {
+    vector<vector<int> > vect_vector;
+    vect_vector.assign(20, vector<int>(10));
+    vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end());
+    vector<int*> bufs;
+    for (; vdit != vditEnd; ++vdit) {
+      bufs.push_back(&vdit->front());
+    }
+
+    {
+      //2 values in front:
+      vect_vector.insert(vect_vector.begin() + 2, 2, vector<int>(10));
+      bufs.insert(bufs.begin() + 2, &vect_vector[2].front());
+      bufs.insert(bufs.begin() + 3, &vect_vector[3].front());
+      CPPUNIT_ASSERT( vect_vector.size() == 22 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      //2 values in back:
+      vect_vector.insert(vect_vector.end() - 2, 2, vector<int>(10));
+      bufs.insert(bufs.end() - 2, &vect_vector[20].front());
+      bufs.insert(bufs.end() - 2, &vect_vector[21].front());
+      CPPUNIT_ASSERT( vect_vector.size() == 24 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      //1 value in front:
+      vector<vector<int> >::iterator ret;
+      ret = vect_vector.insert(vect_vector.begin() + 2, vector<int>(10));
+      bufs.insert(bufs.begin() + 2, &vect_vector[2].front());
+      CPPUNIT_ASSERT( vect_vector.size() == 25 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( &ret->front() == bufs[2] );
+      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+
+    {
+      //1 value in back:
+      vector<vector<int> >::iterator ret;
+      ret = vect_vector.insert(vect_vector.end() - 2, vector<int>(10));
+      bufs.insert(bufs.end() - 2, &vect_vector[23].front());
+      CPPUNIT_ASSERT( vect_vector.size() == 26 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( &ret->front() == bufs[23] );
+      vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
+      for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
+        CPPUNIT_ASSERT( bufs[i] == &dit->front() );
+      }
+#endif
+    }
+  }
+
+  //The following tests are checking move contructor implementations:
+  const string long_str("long enough string to force dynamic allocation");
+  {
+    //vector move contructor:
+    vector<vector<string> > vect(10, vector<string>(10, long_str));
+    vector<string> strs;
+    size_t index = 0;
+    while (true) {
+      vector<vector<string> >::iterator it(vect.begin());
+      advance(it, index % vect.size());
+      strs.push_back(it->front());
+      it->erase(it->begin());
+      if (it->empty()) {
+        vect.erase(it);
+        if (vect.empty())
+          break;
+      }
+      index += 3;
+    }
+    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
+    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
+    for (; it != itEnd; ++it) {
+      CPPUNIT_ASSERT( *it == long_str );
+    }
+  }
+
+  {
+    //deque move contructor:
+    vector<deque<string> > vect(10, deque<string>(10, long_str));
+    vector<string> strs;
+    size_t index = 0;
+    while (true) {
+      vector<deque<string> >::iterator it(vect.begin());
+      advance(it, index % vect.size());
+      strs.push_back(it->front());
+      it->pop_front();
+      if (it->empty()) {
+        vect.erase(it);
+        if (vect.empty())
+          break;
+      }
+      index += 3;
+    }
+    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
+    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
+    for (; it != itEnd; ++it) {
+      CPPUNIT_ASSERT( *it == long_str );
+    }
+  }
+
+  {
+    //list move contructor:
+    vector<list<string> > vect(10, list<string>(10, long_str));
+    vector<string> strs;
+    size_t index = 0;
+    while (true) {
+      vector<list<string> >::iterator it(vect.begin());
+      advance(it, index % vect.size());
+      strs.push_back(it->front());
+      it->pop_front();
+      if (it->empty()) {
+        vect.erase(it);
+        if (vect.empty())
+          break;
+      }
+      index += 3;
+    }
+    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
+    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
+    for (; it != itEnd; ++it) {
+      CPPUNIT_ASSERT( *it == long_str );
+    }
+  }
+
+#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
+  {
+    //slist move contructor:
+    vector<slist<string> > vect(10, slist<string>(10, long_str));
+    vector<string> strs;
+    size_t index = 0;
+    while (true) {
+      vector<slist<string> >::iterator it(vect.begin());
+      advance(it, index % vect.size());
+      strs.push_back(it->front());
+      it->pop_front();
+      if (it->empty()) {
+        vect.erase(it);
+        if (vect.empty())
+          break;
+      }
+      index += 3;
+    }
+    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
+    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
+    for (; it != itEnd; ++it) {
+      CPPUNIT_ASSERT( *it == long_str );
+    }
+  }
+#endif
+
+  {
+    //binary tree move contructor:
+    multiset<string> ref;
+    for (size_t i = 0; i < 10; ++i) {
+      ref.insert(long_str);
+    }
+    vector<multiset<string> > vect(10, ref);
+    vector<string> strs;
+    size_t index = 0;
+    while (true) {
+      vector<multiset<string> >::iterator it(vect.begin());
+      advance(it, index % vect.size());
+      strs.push_back(*it->begin());
+      it->erase(it->begin());
+      if (it->empty()) {
+        vect.erase(it);
+        if (vect.empty())
+          break;
+      }
+      index += 3;
+    }
+    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
+    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
+    for (; it != itEnd; ++it) {
+      CPPUNIT_ASSERT( *it == long_str );
+    }
+  }
+#  endif /* __DMC__ */
+
+#if defined (STLPORT)
+#  if !defined (__BORLANDC__) && !defined (__DMC__)
+  {
+    //hash container move contructor:
+    unordered_multiset<string> ref;
+    for (size_t i = 0; i < 10; ++i) {
+      ref.insert(long_str);
+    }
+    vector<unordered_multiset<string> > vect(10, ref);
+    vector<string> strs;
+    size_t index = 0;
+    while (true) {
+      vector<unordered_multiset<string> >::iterator it(vect.begin());
+      advance(it, index % vect.size());
+      strs.push_back(*it->begin());
+      it->erase(it->begin());
+      if (it->empty()) {
+        vect.erase(it);
+        if (vect.empty())
+          break;
+      }
+      index += 3;
+    }
+    CPPUNIT_ASSERT( strs.size() == 10 * 10 );
+    vector<string>::iterator it(strs.begin()), itEnd(strs.end());
+    for (; it != itEnd; ++it) {
+      CPPUNIT_ASSERT( *it == long_str );
+    }
+  }
+#  endif
+#endif
+}
+
+struct MovableStruct {
+  MovableStruct() { ++nb_dft_construct_call; }
+  MovableStruct(MovableStruct const&) { ++nb_cpy_construct_call; }
+#  if defined (STLPORT)
+  MovableStruct(__move_source<MovableStruct>) { ++nb_mv_construct_call; }
+#  endif
+  ~MovableStruct() { ++nb_destruct_call; }
+
+  MovableStruct& operator = (const MovableStruct&) {
+    ++nb_assignment_call;
+    return *this;
+  }
+
+  static void reset() {
+    nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
+    nb_assignment_call = 0;
+    nb_destruct_call = 0;
+  }
+
+  static size_t nb_dft_construct_call;
+  static size_t nb_cpy_construct_call;
+  static size_t nb_mv_construct_call;
+  static size_t nb_assignment_call;
+  static size_t nb_destruct_call;
+
+  //Dummy data just to control struct sizeof
+  //As node allocator implementation align memory blocks on 2 * sizeof(void*)
+  //we give MovableStruct the same size in order to have expected allocation
+  //and not more
+  void* dummy_data[2];
+};
+
+size_t MovableStruct::nb_dft_construct_call = 0;
+size_t MovableStruct::nb_cpy_construct_call = 0;
+size_t MovableStruct::nb_mv_construct_call = 0;
+size_t MovableStruct::nb_assignment_call = 0;
+size_t MovableStruct::nb_destruct_call = 0;
+
+#  if defined (STLPORT)
+namespace std {
+  _STLP_TEMPLATE_NULL
+  struct __move_traits<MovableStruct> {
+    typedef __true_type implemented;
+    typedef __false_type complete;
+  };
+}
+#  endif
+
+struct CompleteMovableStruct {
+  CompleteMovableStruct() { ++nb_dft_construct_call; }
+  CompleteMovableStruct(CompleteMovableStruct const&) { ++nb_cpy_construct_call; }
+#  if defined (STLPORT)
+  CompleteMovableStruct(__move_source<CompleteMovableStruct>) { ++nb_mv_construct_call; }
+#  endif
+  ~CompleteMovableStruct() { ++nb_destruct_call; }
+
+  CompleteMovableStruct& operator = (const CompleteMovableStruct&) {
+    ++nb_assignment_call;
+    return *this;
+  }
+  static void reset() {
+    nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
+    nb_assignment_call = 0;
+    nb_destruct_call = 0;
+  }
+
+  static size_t nb_dft_construct_call;
+  static size_t nb_cpy_construct_call;
+  static size_t nb_mv_construct_call;
+  static size_t nb_assignment_call;
+  static size_t nb_destruct_call;
+
+  //See MovableStruct
+  void* dummy_data[2];
+};
+
+size_t CompleteMovableStruct::nb_dft_construct_call = 0;
+size_t CompleteMovableStruct::nb_cpy_construct_call = 0;
+size_t CompleteMovableStruct::nb_mv_construct_call = 0;
+size_t CompleteMovableStruct::nb_assignment_call = 0;
+size_t CompleteMovableStruct::nb_destruct_call = 0;
+
+#  if defined (STLPORT)
+namespace std {
+  _STLP_TEMPLATE_NULL
+  struct __move_traits<CompleteMovableStruct> {
+    typedef __true_type implemented;
+    typedef __true_type complete;
+  };
+}
+#  endif
+
+void MoveConstructorTest::move_traits()
+{
+  {
+    {
+      vector<MovableStruct> vect;
+      vect.push_back(MovableStruct());
+      vect.push_back(MovableStruct());
+      vect.push_back(MovableStruct());
+      vect.push_back(MovableStruct());
+
+      // vect contains 4 elements
+      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
+#if defined (STLPORT)
+#  if !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
+#  else
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
+#  endif
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
+#elif !defined (_MSC_VER)
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
+#else
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 14 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 14 );
+#endif
+      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
+
+      // Following test violate requirements to sequiences (23.1.1 Table 67)
+      /*
+      vect.insert(vect.begin() + 2, vect.begin(), vect.end());
+      // vect contains 8 elements
+      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
+      */
+
+      MovableStruct::reset();
+      vector<MovableStruct> v2 = vect;
+      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
+
+      MovableStruct::reset();
+      vect.insert(vect.begin() + 2, v2.begin(), v2.end() );
+
+      // vect contains 8 elements
+      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 4 );
+#else
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
+#endif
+      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
+
+      MovableStruct::reset();
+      vect.erase(vect.begin(), vect.begin() + 2 );
+
+      // vect contains 6 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 6 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 8 );
+#else
+      CPPUNIT_ASSERT_EQUAL( MovableStruct::nb_assignment_call, 6 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
+#endif
+
+      MovableStruct::reset();
+      vect.erase(vect.end() - 2, vect.end());
+
+      // vect contains 4 elements
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
+
+      MovableStruct::reset();
+      vect.erase(vect.begin());
+
+      // vect contains 3 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
+#else
+      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 3 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
+#endif
+
+      MovableStruct::reset();
+    }
+    //vect with 3 elements and v2 with 4 elements are now out of scope
+    CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
+  }
+
+  {
+    {
+      vector<CompleteMovableStruct> vect;
+      vect.push_back(CompleteMovableStruct());
+      vect.push_back(CompleteMovableStruct());
+      vect.push_back(CompleteMovableStruct());
+      vect.push_back(CompleteMovableStruct());
+
+      // vect contains 4 elements
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
+#if defined (STLPORT)
+#  if !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
+#  else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
+#  endif
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
+#elif !defined (_MSC_VER)
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 7 );
+#else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 14 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 14 );
+#endif
+
+      // Following test violate requirements to sequiences (23.1.1 Table 67)
+      /*
+      vect.insert(vect.begin() + 2, vect.begin(), vect.end());
+
+      // vect contains 8 elements
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
+      */
+
+      CompleteMovableStruct::reset();
+      vector<CompleteMovableStruct> v2 = vect;
+
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
+
+      CompleteMovableStruct::reset();
+      vect.insert(vect.begin() + 2, v2.begin(), v2.end());
+
+      // vect contains 8 elements
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
+#if defined (STLPORT)
+#  if !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 4 );
+#  else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
+#  endif
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
+#else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
+#endif
+
+      CompleteMovableStruct::reset();
+      vect.erase(vect.begin(), vect.begin() + 2);
+
+      // vect contains 6 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 6 );
+#else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 6 );
+#endif
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
+
+      CompleteMovableStruct::reset();
+      vect.erase(vect.end() - 2, vect.end());
+
+      // vect contains 4 elements
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
+
+      CompleteMovableStruct::reset();
+      vect.erase(vect.begin());
+
+      // vect contains 3 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
+#else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 3 );
+#endif
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
+
+      CompleteMovableStruct::reset();
+    }
+    //vect with 3 elements and v2 with 4 elements are now out of scope
+    CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
+  }
+
+  {
+    MovableStruct::reset();
+    {
+      deque<MovableStruct> deq;
+      deq.push_back(MovableStruct());
+      deq.push_back(MovableStruct());
+      deq.push_back(MovableStruct());
+      deq.push_back(MovableStruct());
+
+      // deq contains 4 elements
+      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
+
+      // Following test violate requirements to sequiences (23.1.1 Table 67)
+      /*
+      deq.insert(deq.begin() + 2, deq.begin(), deq.end());
+      // deq contains 8 elements
+      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
+      */
+
+      MovableStruct::reset();
+      deque<MovableStruct> d2 = deq;
+
+      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
+
+      MovableStruct::reset();
+      deq.insert(deq.begin() + 2, d2.begin(), d2.end() );
+
+      // deq contains 8 elements
+      CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
+      CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 2 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
+#else
+      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 2 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
+#endif
+
+      MovableStruct::reset();
+      deq.erase(deq.begin() + 1, deq.begin() + 3 );
+
+      // deq contains 6 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
+#else
+      //Following check is highly deque implementation dependant so
+      //it might not always work...
+      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
+#endif
+
+      MovableStruct::reset();
+      deq.erase(deq.end() - 3, deq.end() - 1);
+
+      // deq contains 4 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
+#else
+      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
+#endif
+
+      MovableStruct::reset();
+      deq.erase(deq.begin());
+
+      // deq contains 3 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
+#else
+      CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
+#endif
+      CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
+
+      MovableStruct::reset();
+    }
+    //deq with 3 elements and d2 with 4 elements are now out of scope
+    CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
+  }
+
+  {
+    CompleteMovableStruct::reset();
+    {
+      deque<CompleteMovableStruct> deq;
+      deq.push_back(CompleteMovableStruct());
+      deq.push_back(CompleteMovableStruct());
+      deq.push_back(CompleteMovableStruct());
+      deq.push_back(CompleteMovableStruct());
+
+      // deq contains 4 elements
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
+
+      // Following test violate requirements to sequiences (23.1.1 Table 67)
+      /*
+      deq.insert(deq.begin() + 2, deq.begin(), deq.end());
+
+      // deq contains 8 elements
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
+      */
+
+      CompleteMovableStruct::reset();
+      deque<CompleteMovableStruct> d2 = deq;
+
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
+
+      CompleteMovableStruct::reset();
+      deq.insert(deq.begin() + 2, d2.begin(), d2.end());
+
+      // deq contains 8 elements
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 2 );
+#else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 2 );
+#endif
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
+
+      CompleteMovableStruct::reset();
+      deq.erase(deq.begin() + 1, deq.begin() + 3);
+
+      // deq contains 6 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
+#else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
+#endif
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
+
+      CompleteMovableStruct::reset();
+      deq.erase(deq.end() - 3, deq.end() - 1);
+
+      // deq contains 4 elements
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
+#else
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
+#endif
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
+
+      CompleteMovableStruct::reset();
+      deq.erase(deq.begin());
+
+      // deq contains 3 elements
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 0 );
+      CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
+
+      CompleteMovableStruct::reset();
+    }
+    //deq with 3 elements and v2 with 4 elements are now out of scope
+    CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
+  }
+}
+
+#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC) 
+
+#  if defined (__GNUC__) && defined (_STLP_USE_NAMESPACES)
+// libstdc++ sometimes exposed its own __true_type in
+// global namespace resulting in an ambiguity.
+#    define __true_type std::__true_type
+#    define __false_type std::__false_type
+#  endif
+
+static bool type_to_bool(__true_type)
+{ return true; }
+static bool type_to_bool(__false_type)
+{ return false; }
+
+template <class _Tp>
+static bool is_movable(const _Tp&) {
+#if defined (__BORLANDC__) || defined (__SYMBIAN32__)
+  return __type2bool<typename __move_traits<_Tp>::implemented>::_Ret != 0;
+#else
+  typedef typename __move_traits<_Tp>::implemented _MovableTp;
+  return type_to_bool(_MovableTp());
+#endif
+}
+
+template <class _Tp>
+static bool is_move_complete(const _Tp&) {
+  typedef __move_traits<_Tp> _TpMoveTraits;
+#if defined (__BORLANDC__) || defined (__SYMBIAN32__)
+  return __type2bool<typename __move_traits<_Tp>::complete>::_Ret != 0;
+#else
+  typedef typename _TpMoveTraits::complete _TpMoveComplete;
+  return type_to_bool(_TpMoveComplete());
+#endif
+}
+
+struct specially_allocated_struct {
+  bool operator < (specially_allocated_struct) const;
+};
+
+struct struct_with_specialized_less {};
+
+namespace std
+{
+  _STLP_TEMPLATE_NULL
+  class allocator<specially_allocated_struct>
+  {
+    //This allocator just represent what a STLport could do and in this
+    //case the STL containers implemented with it should still be movable
+    //but not completely as we cannot do any hypothesis on what is in this
+    //allocator.
+  public:
+    typedef specially_allocated_struct value_type;
+    typedef value_type *       pointer;
+    typedef const value_type* const_pointer;
+    typedef value_type&       reference;
+    typedef const value_type& const_reference;
+    typedef size_t     size_type;
+    typedef ptrdiff_t  difference_type;
+#if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
+    template <class _Tp1> struct rebind {
+      typedef allocator<_Tp1> other;
+    };
+#endif
+    allocator() _STLP_NOTHROW {}
+#if defined (_STLP_MEMBER_TEMPLATES)
+    template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
+#endif
+    allocator(const allocator&) _STLP_NOTHROW {}
+    ~allocator() _STLP_NOTHROW {}
+    pointer address(reference __x) const { return &__x; }
+    const_pointer address(const_reference __x) const { return &__x; }
+    pointer allocate(size_type, const void* = 0) { return 0; }
+    void deallocate(pointer, size_type) {}
+    size_type max_size() const _STLP_NOTHROW  { return 0; }
+    void construct(pointer, const_reference) {}
+    void destroy(pointer) {}
+  };
+
+  _STLP_TEMPLATE_NULL
+  struct less<struct_with_specialized_less> {
+    bool operator() (struct_with_specialized_less const&,
+                     struct_with_specialized_less const&) const;
+  };
+}
+#endif
+
+void MoveConstructorTest::movable_declaration()
+{
+#if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
+                         !defined (_STLP_NO_MOVE_SEMANTIC) && \
+   !defined (__DMC__)
+  //This test purpose is to check correct detection of the STL movable
+  //traits declaration
+  {
+    //string, wstring:
+    CPPUNIT_ASSERT( is_movable(string()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(string()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(string()) );
+#    endif
+#    if defined (_STLP_HAS_WCHAR_T)
+    CPPUNIT_ASSERT( is_movable(wstring()) );
+#      if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(wstring()) );
+#      else
+    CPPUNIT_ASSERT( !is_move_complete(wstring()) );
+#      endif
+#    endif
+  }
+
+#    if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
+  {
+    //crope, wrope:
+    CPPUNIT_ASSERT( is_movable(crope()) );
+#      if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(crope()) );
+#      else
+    CPPUNIT_ASSERT( !is_move_complete(crope()) );
+#      endif
+#      if defined (_STLP_HAS_WCHAR_T)
+    CPPUNIT_ASSERT( is_movable(wrope()) );
+#        if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(wrope()) );
+#        else
+    CPPUNIT_ASSERT( !is_move_complete(wrope()) );
+#        endif
+#      endif
+  }
+#    endif
+
+  {
+    //vector:
+    CPPUNIT_ASSERT( is_movable(vector<char>()) );
+    CPPUNIT_ASSERT( is_movable(vector<specially_allocated_struct>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(vector<char>()) );
+    CPPUNIT_ASSERT( !is_move_complete(vector<specially_allocated_struct>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(vector<char>()) );
+#    endif
+  }
+
+  {
+    //deque:
+    CPPUNIT_ASSERT( is_movable(deque<char>()) );
+    CPPUNIT_ASSERT( is_movable(deque<specially_allocated_struct>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(deque<char>()) );
+    CPPUNIT_ASSERT( !is_move_complete(deque<specially_allocated_struct>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(deque<char>()) );
+#    endif
+  }
+
+  {
+    //list:
+    CPPUNIT_ASSERT( is_movable(list<char>()) );
+    CPPUNIT_ASSERT( is_movable(list<specially_allocated_struct>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(list<char>()) );
+    CPPUNIT_ASSERT( !is_move_complete(list<specially_allocated_struct>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(list<char>()) );
+#    endif
+  }
+
+#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
+  {
+    //slist:
+    CPPUNIT_ASSERT( is_movable(slist<char>()) );
+    CPPUNIT_ASSERT( is_movable(slist<specially_allocated_struct>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(slist<char>()) );
+    CPPUNIT_ASSERT( !is_move_complete(slist<specially_allocated_struct>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(slist<char>()) );
+#    endif
+  }
+#endif
+
+  {
+    //queue:
+    CPPUNIT_ASSERT( is_movable(queue<char>()) );
+    CPPUNIT_ASSERT( is_movable(queue<specially_allocated_struct>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(queue<char>()) );
+    CPPUNIT_ASSERT( !is_move_complete(queue<specially_allocated_struct>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(queue<char>()) );
+#    endif
+  }
+
+  {
+    //stack:
+    CPPUNIT_ASSERT( is_movable(stack<char>()) );
+    CPPUNIT_ASSERT( is_movable(stack<specially_allocated_struct>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(stack<char>()) );
+    CPPUNIT_ASSERT( !is_move_complete(stack<specially_allocated_struct>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(stack<char>()) );
+#    endif
+  }
+
+  {
+    //associative containers, set multiset, map, multimap:
+
+    //For associative containers it is important that less is correctly recognize as
+    //the STLport less or a user specialized less:
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(less<char>()) );
+#    endif
+    CPPUNIT_ASSERT( !is_move_complete(less<struct_with_specialized_less>()) );
+
+    //set
+    CPPUNIT_ASSERT( is_movable(set<char>()) );
+    CPPUNIT_ASSERT( is_movable(set<specially_allocated_struct>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(set<char>()) );
+    CPPUNIT_ASSERT( !is_move_complete(set<specially_allocated_struct>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(set<char>()) );
+#    endif
+
+    //multiset
+    CPPUNIT_ASSERT( is_movable(multiset<char>()) );
+    CPPUNIT_ASSERT( is_movable(multiset<specially_allocated_struct>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(multiset<char>()) );
+    CPPUNIT_ASSERT( !is_move_complete(multiset<specially_allocated_struct>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(multiset<char>()) );
+#    endif
+
+    //map
+    CPPUNIT_ASSERT( is_movable(map<char, char>()) );
+    CPPUNIT_ASSERT( is_movable(map<specially_allocated_struct, char>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(map<char, char>()) );
+    //Here even if allocator has been specialized for specially_allocated_struct
+    //this pecialization won't be used in default map instanciation as the default
+    //allocator is allocator<pair<specially_allocated_struct, char> >
+    CPPUNIT_ASSERT( is_move_complete(map<specially_allocated_struct, char>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(map<char, char>()) );
+#    endif
+
+    //multimap
+    CPPUNIT_ASSERT( is_movable(multimap<char, char>()) );
+    CPPUNIT_ASSERT( is_movable(multimap<specially_allocated_struct, char>()) );
+#    if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
+    CPPUNIT_ASSERT( is_move_complete(multimap<char, char>()) );
+    //Idem map remark
+    CPPUNIT_ASSERT( is_move_complete(multimap<specially_allocated_struct, char>()) );
+#    else
+    CPPUNIT_ASSERT( !is_move_complete(multimap<char, char>()) );
+#    endif
+  }
+
+#    if defined (STLPORT)
+  {
+    //hashed containers, unordered_set unordered_multiset, unordered_map, unordered_multimap,
+    //                   hash_set, hash_multiset, hash_map, hash_multimap:
+
+    //We only check that they are movable, completness is not yet supported
+    CPPUNIT_ASSERT( is_movable(unordered_set<char>()) );
+    CPPUNIT_ASSERT( is_movable(unordered_multiset<char>()) );
+    CPPUNIT_ASSERT( is_movable(unordered_map<char, char>()) );
+    CPPUNIT_ASSERT( is_movable(unordered_multimap<char, char>()) );
+#      if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
+    CPPUNIT_ASSERT( is_movable(hash_set<char>()) );
+    CPPUNIT_ASSERT( is_movable(hash_multiset<char>()) );
+    CPPUNIT_ASSERT( is_movable(hash_map<char, char>()) );
+    CPPUNIT_ASSERT( is_movable(hash_multimap<char, char>()) );
+#      endif
+  }
+#    endif
+#  endif
+}
+
+#if defined (__BORLANDC__)
+/* Specific Borland test case to show a really weird compiler behavior.
+ */
+class Standalone
+{
+public:
+  //Uncomment following to pass the test
+  //Standalone() {}
+  ~Standalone() {}
+
+  MovableStruct movableStruct;
+  vector<int> intVector;
+};
+
+void MoveConstructorTest::nb_destructor_calls()
+{
+  MovableStruct::reset();
+
+  try
+  {
+    Standalone standalone;
+    throw "some exception";
+    MovableStruct movableStruct;
+  }
+  catch (const char*)
+  {
+    CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 1 );
+    CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
+  }
+}
+#endif