1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/test/unit/mvctor_test.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1610 @@
1.4 +/*
1.5 +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 + */
1.8 +
1.9 +#include <vector>
1.10 +#include <algorithm>
1.11 +#include <vector>
1.12 +#include <string>
1.13 +#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1.14 +# include <rope>
1.15 +#endif
1.16 +#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1.17 +# include <slist>
1.18 +#endif
1.19 +#include <list>
1.20 +#include <deque>
1.21 +#include <set>
1.22 +#include <map>
1.23 +#if defined (STLPORT)
1.24 +# include <unordered_set>
1.25 +# include <unordered_map>
1.26 +#endif
1.27 +#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1.28 +# include <hash_set>
1.29 +# include <hash_map>
1.30 +#endif
1.31 +#include <queue>
1.32 +#include <stack>
1.33 +//#include <iostream>
1.34 +
1.35 +#include "cppunit/cppunit_proxy.h"
1.36 +
1.37 +#if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
1.38 +using namespace std;
1.39 +#endif
1.40 +
1.41 +//
1.42 +// TestCase class
1.43 +//
1.44 +class MoveConstructorTest : public CPPUNIT_NS::TestCase
1.45 +{
1.46 + CPPUNIT_TEST_SUITE(MoveConstructorTest);
1.47 + CPPUNIT_TEST(move_construct_test);
1.48 + CPPUNIT_TEST(deque_test);
1.49 +#if defined (__DMC__)
1.50 + CPPUNIT_IGNORE;
1.51 +#endif
1.52 + CPPUNIT_TEST(vector_test);
1.53 + CPPUNIT_STOP_IGNORE;
1.54 + CPPUNIT_TEST(move_traits);
1.55 +#if !defined (STLPORT) || defined (_STLP_NO_MOVE_SEMANTIC) || \
1.56 + defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) || \
1.57 + defined (__BORLANDC__) || defined (__DMC__)
1.58 + CPPUNIT_IGNORE;
1.59 +# endif
1.60 + CPPUNIT_TEST(movable_declaration)
1.61 +#if defined (__BORLANDC__)
1.62 + CPPUNIT_STOP_IGNORE;
1.63 + CPPUNIT_TEST(nb_destructor_calls);
1.64 +#endif
1.65 + CPPUNIT_TEST_SUITE_END();
1.66 +
1.67 +protected:
1.68 + void move_construct_test();
1.69 + void deque_test();
1.70 + void vector_test();
1.71 + void move_traits();
1.72 + void movable_declaration();
1.73 + void nb_destructor_calls();
1.74 +
1.75 + /*
1.76 + template <class _Container>
1.77 + void standard_test1(_Container const& ref_cont) {
1.78 + vector<_Container> vec_cont(1, ref_cont);
1.79 + typedef typename _Container::value_type value_type;
1.80 + value_type *pvalue = &(*vec_cont.front().begin());
1.81 + size_t cur_capacity= vec_cont.capacity();
1.82 + //force reallocation
1.83 + while (cur_capacity == vec_cont.capacity()) {
1.84 + vec_cont.push_back(ref_cont);
1.85 + }
1.86 + bool b=( (pvalue==(&(*vec_cont.front().begin()))) );
1.87 + CPPUNIT_ASSERT(b);
1.88 + }
1.89 + */
1.90 +};
1.91 +
1.92 +CPPUNIT_TEST_SUITE_REGISTRATION(MoveConstructorTest);
1.93 +
1.94 +//
1.95 +// tests implementation
1.96 +//
1.97 +void MoveConstructorTest::move_construct_test()
1.98 +{
1.99 + //cout << "vector<vector<int>>";
1.100 + vector<int> const ref_vec(10, 0);
1.101 + vector<vector<int> > v_v_ints(1, ref_vec);
1.102 +
1.103 + int *pint = &(v_v_ints.front().front());
1.104 +
1.105 + size_t cur_capacity = v_v_ints.capacity();
1.106 + while (v_v_ints.capacity() <= cur_capacity) {
1.107 + v_v_ints.push_back(ref_vec);
1.108 + }
1.109 +
1.110 + //v_v_ints has been resized
1.111 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.112 + CPPUNIT_ASSERT((pint == &v_v_ints.front().front()));
1.113 +#endif
1.114 +
1.115 + //cout << "vector<vector<int>>::erase";
1.116 + //We need at least 3 elements:
1.117 + while (v_v_ints.size() < 3) {
1.118 + v_v_ints.push_back(ref_vec);
1.119 + }
1.120 +
1.121 + //We erase the 2nd
1.122 + pint = &v_v_ints[2].front();
1.123 + v_v_ints.erase(v_v_ints.begin() + 1);
1.124 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.125 + CPPUNIT_ASSERT((pint == &v_v_ints[1].front()));
1.126 +#endif
1.127 +
1.128 + //cout << "vector<string>";
1.129 + string const ref_str("ref string, big enough to be a dynamic one");
1.130 + vector<string> vec_strs(1, ref_str);
1.131 +
1.132 + char const* pstr = vec_strs.front().c_str();
1.133 + cur_capacity = vec_strs.capacity();
1.134 + while (vec_strs.capacity() <= cur_capacity) {
1.135 + vec_strs.push_back(ref_str);
1.136 + }
1.137 +
1.138 + //vec_str has been resized
1.139 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.140 + CPPUNIT_ASSERT((pstr == vec_strs.front().c_str()));
1.141 +#endif
1.142 +
1.143 + //cout << "vector<string>::erase";
1.144 + //We need at least 3 elements:
1.145 + while (vec_strs.size() < 3) {
1.146 + vec_strs.push_back(ref_str);
1.147 + }
1.148 +
1.149 + //We erase the 2nd
1.150 + pstr = vec_strs[2].c_str();
1.151 + vec_strs.erase(vec_strs.begin() + 1);
1.152 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.153 + CPPUNIT_ASSERT((pstr == vec_strs[1].c_str()));
1.154 +#endif
1.155 +
1.156 + //cout << "swap(vector<int>, vector<int>)";
1.157 + vector<int> elem1(10, 0), elem2(10, 0);
1.158 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.159 + int *p1 = &elem1.front();
1.160 + int *p2 = &elem2.front();
1.161 +#endif
1.162 + swap(elem1, elem2);
1.163 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.164 + CPPUNIT_ASSERT(((p1 == &elem2.front()) && (p2 == &elem1.front())));
1.165 +#endif
1.166 +
1.167 + {
1.168 + vector<bool> bit_vec(5, true);
1.169 + bit_vec.insert(bit_vec.end(), 5, false);
1.170 + vector<vector<bool> > v_v_bits(1, bit_vec);
1.171 +
1.172 + /*
1.173 + * This is a STLport specific test as we are using internal implementation
1.174 + * details to check that the move has been correctly handled. For other
1.175 + * STL implementation it is only a compile check.
1.176 + */
1.177 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.178 +# if defined (_STLP_DEBUG)
1.179 + unsigned int *punit = v_v_bits.front().begin()._M_iterator._M_p;
1.180 +# else
1.181 + unsigned int *punit = v_v_bits.front().begin()._M_p;
1.182 +# endif
1.183 +#endif
1.184 +
1.185 + cur_capacity = v_v_bits.capacity();
1.186 + while (v_v_bits.capacity() <= cur_capacity) {
1.187 + v_v_bits.push_back(bit_vec);
1.188 + }
1.189 +
1.190 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.191 + //v_v_bits has been resized
1.192 +# if defined (_STLP_DEBUG)
1.193 + CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_iterator._M_p );
1.194 +# else
1.195 + CPPUNIT_ASSERT( punit == v_v_bits.front().begin()._M_p );
1.196 +# endif
1.197 +#endif
1.198 + }
1.199 +
1.200 + // zero: don't like this kind of tests
1.201 + // because of template test function
1.202 + // we should find another way to provide
1.203 + // move constructor testing...
1.204 +
1.205 +/*
1.206 + standard_test1(list<int>(10));
1.207 +
1.208 +
1.209 + standard_test1(slist<int>(10));
1.210 +
1.211 + standard_test1(deque<int>(10));
1.212 +*/
1.213 +
1.214 + /*
1.215 + int int_values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1.216 +
1.217 + set<int> int_set(int_values, int_values + sizeof(in_values) / sizeof(int));
1.218 + standard_test1(int_set);
1.219 +
1.220 + multiset<int> int_multiset(int_values, int_values + sizeof(in_values) / sizeof(int));
1.221 + standard_test1(int_multiset);
1.222 + */
1.223 +
1.224 + /*
1.225 + CheckFullMoveSupport(string());
1.226 + CheckFullMoveSupport(vector<int>());
1.227 + CheckFullMoveSupport(deque<int>());
1.228 + CheckFullMoveSupport(list<int>());
1.229 + CheckFullMoveSupport(slist<int>());
1.230 + */
1.231 +}
1.232 +
1.233 +void MoveConstructorTest::deque_test()
1.234 +{
1.235 + //Check the insert range method.
1.236 + //To the front:
1.237 + {
1.238 +# if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES)
1.239 + deque<vector<int> > vect_deque;
1.240 + vector<int*> bufs;
1.241 + vect_deque.assign(3, vector<int>(10));
1.242 + bufs.push_back(&vect_deque[0].front());
1.243 + bufs.push_back(&vect_deque[1].front());
1.244 + bufs.push_back(&vect_deque[2].front());
1.245 +
1.246 + int nb_insert = 5;
1.247 + //Initialize to 1 to generate a front insertion:
1.248 + int pos = 1;
1.249 + while (nb_insert--) {
1.250 + vector<vector<int> > vect_vect(2, vector<int>(10));
1.251 + vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end());
1.252 + bufs.insert(bufs.begin() + pos, &vect_deque[pos].front());
1.253 + bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front());
1.254 + ++pos;
1.255 + }
1.256 + CPPUNIT_ASSERT( vect_deque.size() == 13 );
1.257 +# if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.258 + for (int i = 0; i < 5; ++i) {
1.259 + CPPUNIT_ASSERT( bufs[i] == &vect_deque[i].front() );
1.260 + CPPUNIT_ASSERT( bufs[11 - i] == &vect_deque[11 - i].front() );
1.261 + }
1.262 +# endif
1.263 +# endif
1.264 + }
1.265 +
1.266 + //To the back
1.267 + {
1.268 +# if !defined (STLPORT) || !defined (_STLP_DEBUG) || !defined (_STLP_NO_MEMBER_TEMPLATES)
1.269 + deque<vector<int> > vect_deque;
1.270 + vector<int*> bufs;
1.271 + vect_deque.assign(3, vector<int>(10));
1.272 + bufs.push_back(&vect_deque[0].front());
1.273 + bufs.push_back(&vect_deque[1].front());
1.274 + bufs.push_back(&vect_deque[2].front());
1.275 +
1.276 + int nb_insert = 5;
1.277 + //Initialize to 2 to generate a back insertion:
1.278 + int pos = 2;
1.279 + while (nb_insert--) {
1.280 + vector<vector<int> > vect_vect(2, vector<int>(10));
1.281 + vect_deque.insert(vect_deque.begin() + pos, vect_vect.begin(), vect_vect.end());
1.282 + bufs.insert(bufs.begin() + pos, &vect_deque[pos].front());
1.283 + bufs.insert(bufs.begin() + pos + 1, &vect_deque[pos + 1].front());
1.284 + ++pos;
1.285 + }
1.286 + CPPUNIT_ASSERT( vect_deque.size() == 13 );
1.287 +# if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.288 + for (int i = 0; i < 5; ++i) {
1.289 + CPPUNIT_ASSERT( bufs[i + 1] == &vect_deque[i + 1].front() );
1.290 + CPPUNIT_ASSERT( bufs[12 - i] == &vect_deque[12 - i].front() );
1.291 + }
1.292 +# endif
1.293 +# endif
1.294 + }
1.295 +
1.296 + //Check the different erase methods.
1.297 + {
1.298 + deque<vector<int> > vect_deque;
1.299 + vect_deque.assign(20, vector<int>(10));
1.300 + deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end());
1.301 + vector<int*> bufs;
1.302 + for (; vdit != vditEnd; ++vdit) {
1.303 + bufs.push_back(&vdit->front());
1.304 + }
1.305 +
1.306 + {
1.307 + // This check, repeated after each operation, check the deque consistency:
1.308 + deque<vector<int> >::iterator it = vect_deque.end() - 5;
1.309 + int nb_incr = 0;
1.310 + for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
1.311 + CPPUNIT_ASSERT( nb_incr == 5 );
1.312 + }
1.313 +
1.314 + {
1.315 + //erase in front:
1.316 + vect_deque.erase(vect_deque.begin() + 2);
1.317 + bufs.erase(bufs.begin() + 2);
1.318 + CPPUNIT_ASSERT( vect_deque.size() == 19 );
1.319 + deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
1.320 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.321 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.322 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.323 + }
1.324 +#endif
1.325 + }
1.326 +
1.327 + {
1.328 + deque<vector<int> >::iterator it = vect_deque.end() - 5;
1.329 + int nb_incr = 0;
1.330 + for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
1.331 + CPPUNIT_ASSERT( nb_incr == 5 );
1.332 + }
1.333 +
1.334 + {
1.335 + //erase in the back:
1.336 + vect_deque.erase(vect_deque.end() - 2);
1.337 + bufs.erase(bufs.end() - 2);
1.338 + CPPUNIT_ASSERT( vect_deque.size() == 18 );
1.339 + deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
1.340 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.341 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.342 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.343 + }
1.344 +#endif
1.345 + }
1.346 +
1.347 + {
1.348 + deque<vector<int> >::iterator it = vect_deque.end() - 5;
1.349 + int nb_incr = 0;
1.350 + for (; it != vect_deque.end() && nb_incr < 6; ++nb_incr, ++it) {}
1.351 + CPPUNIT_ASSERT( nb_incr == 5 );
1.352 + }
1.353 +
1.354 + {
1.355 + //range erase in front
1.356 + vect_deque.erase(vect_deque.begin() + 3, vect_deque.begin() + 5);
1.357 + bufs.erase(bufs.begin() + 3, bufs.begin() + 5);
1.358 + CPPUNIT_ASSERT( vect_deque.size() == 16 );
1.359 + deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
1.360 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.361 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.362 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.363 + }
1.364 +#endif
1.365 + }
1.366 +
1.367 + {
1.368 + deque<vector<int> >::iterator it = vect_deque.end() - 5;
1.369 + int nb_incr = 0;
1.370 + for (; it != vect_deque.end() && nb_incr <= 6; ++nb_incr, ++it) {}
1.371 + CPPUNIT_ASSERT( nb_incr == 5 );
1.372 + }
1.373 +
1.374 + {
1.375 + //range erase in back
1.376 + vect_deque.erase(vect_deque.end() - 5, vect_deque.end() - 3);
1.377 + bufs.erase(bufs.end() - 5, bufs.end() - 3);
1.378 + CPPUNIT_ASSERT( vect_deque.size() == 14 );
1.379 + deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
1.380 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.381 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.382 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.383 + }
1.384 +#endif
1.385 + }
1.386 + }
1.387 +
1.388 + //Check the insert value(s)
1.389 + {
1.390 + deque<vector<int> > vect_deque;
1.391 + vect_deque.assign(20, vector<int>(10));
1.392 + deque<vector<int> >::iterator vdit(vect_deque.begin()), vditEnd(vect_deque.end());
1.393 + vector<int*> bufs;
1.394 + for (; vdit != vditEnd; ++vdit) {
1.395 + bufs.push_back(&vdit->front());
1.396 + }
1.397 +
1.398 + {
1.399 + //2 values in front:
1.400 + vect_deque.insert(vect_deque.begin() + 2, 2, vector<int>(10));
1.401 + bufs.insert(bufs.begin() + 2, &vect_deque[2].front());
1.402 + bufs.insert(bufs.begin() + 3, &vect_deque[3].front());
1.403 + CPPUNIT_ASSERT( vect_deque.size() == 22 );
1.404 + deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
1.405 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.406 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.407 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.408 + }
1.409 +#endif
1.410 + }
1.411 +
1.412 + {
1.413 + //2 values in back:
1.414 + vect_deque.insert(vect_deque.end() - 2, 2, vector<int>(10));
1.415 + bufs.insert(bufs.end() - 2, &vect_deque[20].front());
1.416 + bufs.insert(bufs.end() - 2, &vect_deque[21].front());
1.417 + CPPUNIT_ASSERT( vect_deque.size() == 24 );
1.418 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.419 + deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
1.420 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.421 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.422 + }
1.423 +#endif
1.424 + }
1.425 +
1.426 + {
1.427 + //1 value in front:
1.428 + deque<vector<int> >::iterator ret;
1.429 + ret = vect_deque.insert(vect_deque.begin() + 2, vector<int>(10));
1.430 + bufs.insert(bufs.begin() + 2, &vect_deque[2].front());
1.431 + CPPUNIT_ASSERT( vect_deque.size() == 25 );
1.432 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.433 + CPPUNIT_ASSERT( &ret->front() == bufs[2] );
1.434 + deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
1.435 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.436 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.437 + }
1.438 +#endif
1.439 + }
1.440 +
1.441 + {
1.442 + //1 value in back:
1.443 + deque<vector<int> >::iterator ret;
1.444 + ret = vect_deque.insert(vect_deque.end() - 2, vector<int>(10));
1.445 + bufs.insert(bufs.end() - 2, &vect_deque[23].front());
1.446 + CPPUNIT_ASSERT( vect_deque.size() == 26 );
1.447 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.448 + CPPUNIT_ASSERT( &ret->front() == bufs[23] );
1.449 + deque<vector<int> >::iterator dit(vect_deque.begin()), ditEnd(vect_deque.end());
1.450 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.451 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.452 + }
1.453 +#endif
1.454 + }
1.455 + }
1.456 +}
1.457 +
1.458 +void MoveConstructorTest::vector_test()
1.459 +{
1.460 +#if !defined (__DMC__)
1.461 + //Check the insert range method.
1.462 + //To the front:
1.463 + {
1.464 + vector<vector<int> > vect_vector;
1.465 + vector<int*> bufs;
1.466 + vect_vector.assign(3, vector<int>(10));
1.467 + bufs.push_back(&vect_vector[0].front());
1.468 + bufs.push_back(&vect_vector[1].front());
1.469 + bufs.push_back(&vect_vector[2].front());
1.470 +
1.471 + int nb_insert = 5;
1.472 + int pos = 1;
1.473 + while (nb_insert--) {
1.474 + vector<vector<int> > vect_vect(2, vector<int>(10));
1.475 + vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end());
1.476 + bufs.insert(bufs.begin() + pos, &vect_vector[pos].front());
1.477 + bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front());
1.478 + ++pos;
1.479 + }
1.480 + CPPUNIT_ASSERT( vect_vector.size() == 13 );
1.481 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.482 + for (int i = 0; i < 5; ++i) {
1.483 + CPPUNIT_ASSERT( bufs[i] == &vect_vector[i].front() );
1.484 + CPPUNIT_ASSERT( bufs[11 - i] == &vect_vector[11 - i].front() );
1.485 + }
1.486 +#endif
1.487 + }
1.488 +
1.489 + //To the back
1.490 + {
1.491 + vector<vector<int> > vect_vector;
1.492 + vector<int*> bufs;
1.493 + vect_vector.assign(3, vector<int>(10));
1.494 + bufs.push_back(&vect_vector[0].front());
1.495 + bufs.push_back(&vect_vector[1].front());
1.496 + bufs.push_back(&vect_vector[2].front());
1.497 +
1.498 + int nb_insert = 5;
1.499 + //Initialize to 2 to generate a back insertion:
1.500 + int pos = 2;
1.501 + while (nb_insert--) {
1.502 + vector<vector<int> > vect_vect(2, vector<int>(10));
1.503 + vect_vector.insert(vect_vector.begin() + pos, vect_vect.begin(), vect_vect.end());
1.504 + bufs.insert(bufs.begin() + pos, &vect_vector[pos].front());
1.505 + bufs.insert(bufs.begin() + pos + 1, &vect_vector[pos + 1].front());
1.506 + ++pos;
1.507 + }
1.508 + CPPUNIT_ASSERT( vect_vector.size() == 13 );
1.509 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.510 + for (int i = 0; i < 5; ++i) {
1.511 + CPPUNIT_ASSERT( bufs[i + 1] == &vect_vector[i + 1].front() );
1.512 + CPPUNIT_ASSERT( bufs[12 - i] == &vect_vector[12 - i].front() );
1.513 + }
1.514 +#endif
1.515 + }
1.516 +
1.517 + //Check the different erase methods.
1.518 + {
1.519 + vector<vector<int> > vect_vector;
1.520 + vect_vector.assign(20, vector<int>(10));
1.521 + vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end());
1.522 + vector<int*> bufs;
1.523 + for (; vdit != vditEnd; ++vdit) {
1.524 + bufs.push_back(&vdit->front());
1.525 + }
1.526 +
1.527 + {
1.528 + // This check, repeated after each operation, check the vector consistency:
1.529 + vector<vector<int> >::iterator it = vect_vector.end() - 5;
1.530 + int nb_incr = 0;
1.531 + for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
1.532 + CPPUNIT_ASSERT( nb_incr == 5 );
1.533 + }
1.534 +
1.535 + {
1.536 + //erase in front:
1.537 + vect_vector.erase(vect_vector.begin() + 2);
1.538 + bufs.erase(bufs.begin() + 2);
1.539 + CPPUNIT_ASSERT( vect_vector.size() == 19 );
1.540 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.541 + vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
1.542 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.543 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.544 + }
1.545 +#endif
1.546 + }
1.547 +
1.548 + {
1.549 + vector<vector<int> >::iterator it = vect_vector.end() - 5;
1.550 + int nb_incr = 0;
1.551 + for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
1.552 + CPPUNIT_ASSERT( nb_incr == 5 );
1.553 + }
1.554 +
1.555 + {
1.556 + //erase in the back:
1.557 + vect_vector.erase(vect_vector.end() - 2);
1.558 + bufs.erase(bufs.end() - 2);
1.559 + CPPUNIT_ASSERT( vect_vector.size() == 18 );
1.560 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.561 + vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
1.562 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.563 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.564 + }
1.565 +#endif
1.566 + }
1.567 +
1.568 + {
1.569 + vector<vector<int> >::iterator it = vect_vector.end() - 5;
1.570 + int nb_incr = 0;
1.571 + for (; it != vect_vector.end() && nb_incr < 6; ++nb_incr, ++it) {}
1.572 + CPPUNIT_ASSERT( nb_incr == 5 );
1.573 + }
1.574 +
1.575 + {
1.576 + //range erase in front
1.577 + vect_vector.erase(vect_vector.begin() + 3, vect_vector.begin() + 5);
1.578 + bufs.erase(bufs.begin() + 3, bufs.begin() + 5);
1.579 + CPPUNIT_ASSERT( vect_vector.size() == 16 );
1.580 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.581 + vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
1.582 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.583 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.584 + }
1.585 +#endif
1.586 + }
1.587 +
1.588 + {
1.589 + vector<vector<int> >::iterator it = vect_vector.end() - 5;
1.590 + int nb_incr = 0;
1.591 + for (; it != vect_vector.end() && nb_incr <= 6; ++nb_incr, ++it) {}
1.592 + CPPUNIT_ASSERT( nb_incr == 5 );
1.593 + }
1.594 +
1.595 + {
1.596 + //range erase in back
1.597 + vect_vector.erase(vect_vector.end() - 5, vect_vector.end() - 3);
1.598 + bufs.erase(bufs.end() - 5, bufs.end() - 3);
1.599 + CPPUNIT_ASSERT( vect_vector.size() == 14 );
1.600 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.601 + vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
1.602 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.603 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.604 + }
1.605 +#endif
1.606 + }
1.607 + }
1.608 +
1.609 + //Check the insert value(s)
1.610 + {
1.611 + vector<vector<int> > vect_vector;
1.612 + vect_vector.assign(20, vector<int>(10));
1.613 + vector<vector<int> >::iterator vdit(vect_vector.begin()), vditEnd(vect_vector.end());
1.614 + vector<int*> bufs;
1.615 + for (; vdit != vditEnd; ++vdit) {
1.616 + bufs.push_back(&vdit->front());
1.617 + }
1.618 +
1.619 + {
1.620 + //2 values in front:
1.621 + vect_vector.insert(vect_vector.begin() + 2, 2, vector<int>(10));
1.622 + bufs.insert(bufs.begin() + 2, &vect_vector[2].front());
1.623 + bufs.insert(bufs.begin() + 3, &vect_vector[3].front());
1.624 + CPPUNIT_ASSERT( vect_vector.size() == 22 );
1.625 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.626 + vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
1.627 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.628 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.629 + }
1.630 +#endif
1.631 + }
1.632 +
1.633 + {
1.634 + //2 values in back:
1.635 + vect_vector.insert(vect_vector.end() - 2, 2, vector<int>(10));
1.636 + bufs.insert(bufs.end() - 2, &vect_vector[20].front());
1.637 + bufs.insert(bufs.end() - 2, &vect_vector[21].front());
1.638 + CPPUNIT_ASSERT( vect_vector.size() == 24 );
1.639 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.640 + vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
1.641 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.642 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.643 + }
1.644 +#endif
1.645 + }
1.646 +
1.647 + {
1.648 + //1 value in front:
1.649 + vector<vector<int> >::iterator ret;
1.650 + ret = vect_vector.insert(vect_vector.begin() + 2, vector<int>(10));
1.651 + bufs.insert(bufs.begin() + 2, &vect_vector[2].front());
1.652 + CPPUNIT_ASSERT( vect_vector.size() == 25 );
1.653 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.654 + CPPUNIT_ASSERT( &ret->front() == bufs[2] );
1.655 + vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
1.656 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.657 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.658 + }
1.659 +#endif
1.660 + }
1.661 +
1.662 + {
1.663 + //1 value in back:
1.664 + vector<vector<int> >::iterator ret;
1.665 + ret = vect_vector.insert(vect_vector.end() - 2, vector<int>(10));
1.666 + bufs.insert(bufs.end() - 2, &vect_vector[23].front());
1.667 + CPPUNIT_ASSERT( vect_vector.size() == 26 );
1.668 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.669 + CPPUNIT_ASSERT( &ret->front() == bufs[23] );
1.670 + vector<vector<int> >::iterator dit(vect_vector.begin()), ditEnd(vect_vector.end());
1.671 + for (size_t i = 0; dit != ditEnd; ++dit, ++i) {
1.672 + CPPUNIT_ASSERT( bufs[i] == &dit->front() );
1.673 + }
1.674 +#endif
1.675 + }
1.676 + }
1.677 +
1.678 + //The following tests are checking move contructor implementations:
1.679 + const string long_str("long enough string to force dynamic allocation");
1.680 + {
1.681 + //vector move contructor:
1.682 + vector<vector<string> > vect(10, vector<string>(10, long_str));
1.683 + vector<string> strs;
1.684 + size_t index = 0;
1.685 + while (true) {
1.686 + vector<vector<string> >::iterator it(vect.begin());
1.687 + advance(it, index % vect.size());
1.688 + strs.push_back(it->front());
1.689 + it->erase(it->begin());
1.690 + if (it->empty()) {
1.691 + vect.erase(it);
1.692 + if (vect.empty())
1.693 + break;
1.694 + }
1.695 + index += 3;
1.696 + }
1.697 + CPPUNIT_ASSERT( strs.size() == 10 * 10 );
1.698 + vector<string>::iterator it(strs.begin()), itEnd(strs.end());
1.699 + for (; it != itEnd; ++it) {
1.700 + CPPUNIT_ASSERT( *it == long_str );
1.701 + }
1.702 + }
1.703 +
1.704 + {
1.705 + //deque move contructor:
1.706 + vector<deque<string> > vect(10, deque<string>(10, long_str));
1.707 + vector<string> strs;
1.708 + size_t index = 0;
1.709 + while (true) {
1.710 + vector<deque<string> >::iterator it(vect.begin());
1.711 + advance(it, index % vect.size());
1.712 + strs.push_back(it->front());
1.713 + it->pop_front();
1.714 + if (it->empty()) {
1.715 + vect.erase(it);
1.716 + if (vect.empty())
1.717 + break;
1.718 + }
1.719 + index += 3;
1.720 + }
1.721 + CPPUNIT_ASSERT( strs.size() == 10 * 10 );
1.722 + vector<string>::iterator it(strs.begin()), itEnd(strs.end());
1.723 + for (; it != itEnd; ++it) {
1.724 + CPPUNIT_ASSERT( *it == long_str );
1.725 + }
1.726 + }
1.727 +
1.728 + {
1.729 + //list move contructor:
1.730 + vector<list<string> > vect(10, list<string>(10, long_str));
1.731 + vector<string> strs;
1.732 + size_t index = 0;
1.733 + while (true) {
1.734 + vector<list<string> >::iterator it(vect.begin());
1.735 + advance(it, index % vect.size());
1.736 + strs.push_back(it->front());
1.737 + it->pop_front();
1.738 + if (it->empty()) {
1.739 + vect.erase(it);
1.740 + if (vect.empty())
1.741 + break;
1.742 + }
1.743 + index += 3;
1.744 + }
1.745 + CPPUNIT_ASSERT( strs.size() == 10 * 10 );
1.746 + vector<string>::iterator it(strs.begin()), itEnd(strs.end());
1.747 + for (; it != itEnd; ++it) {
1.748 + CPPUNIT_ASSERT( *it == long_str );
1.749 + }
1.750 + }
1.751 +
1.752 +#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1.753 + {
1.754 + //slist move contructor:
1.755 + vector<slist<string> > vect(10, slist<string>(10, long_str));
1.756 + vector<string> strs;
1.757 + size_t index = 0;
1.758 + while (true) {
1.759 + vector<slist<string> >::iterator it(vect.begin());
1.760 + advance(it, index % vect.size());
1.761 + strs.push_back(it->front());
1.762 + it->pop_front();
1.763 + if (it->empty()) {
1.764 + vect.erase(it);
1.765 + if (vect.empty())
1.766 + break;
1.767 + }
1.768 + index += 3;
1.769 + }
1.770 + CPPUNIT_ASSERT( strs.size() == 10 * 10 );
1.771 + vector<string>::iterator it(strs.begin()), itEnd(strs.end());
1.772 + for (; it != itEnd; ++it) {
1.773 + CPPUNIT_ASSERT( *it == long_str );
1.774 + }
1.775 + }
1.776 +#endif
1.777 +
1.778 + {
1.779 + //binary tree move contructor:
1.780 + multiset<string> ref;
1.781 + for (size_t i = 0; i < 10; ++i) {
1.782 + ref.insert(long_str);
1.783 + }
1.784 + vector<multiset<string> > vect(10, ref);
1.785 + vector<string> strs;
1.786 + size_t index = 0;
1.787 + while (true) {
1.788 + vector<multiset<string> >::iterator it(vect.begin());
1.789 + advance(it, index % vect.size());
1.790 + strs.push_back(*it->begin());
1.791 + it->erase(it->begin());
1.792 + if (it->empty()) {
1.793 + vect.erase(it);
1.794 + if (vect.empty())
1.795 + break;
1.796 + }
1.797 + index += 3;
1.798 + }
1.799 + CPPUNIT_ASSERT( strs.size() == 10 * 10 );
1.800 + vector<string>::iterator it(strs.begin()), itEnd(strs.end());
1.801 + for (; it != itEnd; ++it) {
1.802 + CPPUNIT_ASSERT( *it == long_str );
1.803 + }
1.804 + }
1.805 +# endif /* __DMC__ */
1.806 +
1.807 +#if defined (STLPORT)
1.808 +# if !defined (__BORLANDC__) && !defined (__DMC__)
1.809 + {
1.810 + //hash container move contructor:
1.811 + unordered_multiset<string> ref;
1.812 + for (size_t i = 0; i < 10; ++i) {
1.813 + ref.insert(long_str);
1.814 + }
1.815 + vector<unordered_multiset<string> > vect(10, ref);
1.816 + vector<string> strs;
1.817 + size_t index = 0;
1.818 + while (true) {
1.819 + vector<unordered_multiset<string> >::iterator it(vect.begin());
1.820 + advance(it, index % vect.size());
1.821 + strs.push_back(*it->begin());
1.822 + it->erase(it->begin());
1.823 + if (it->empty()) {
1.824 + vect.erase(it);
1.825 + if (vect.empty())
1.826 + break;
1.827 + }
1.828 + index += 3;
1.829 + }
1.830 + CPPUNIT_ASSERT( strs.size() == 10 * 10 );
1.831 + vector<string>::iterator it(strs.begin()), itEnd(strs.end());
1.832 + for (; it != itEnd; ++it) {
1.833 + CPPUNIT_ASSERT( *it == long_str );
1.834 + }
1.835 + }
1.836 +# endif
1.837 +#endif
1.838 +}
1.839 +
1.840 +struct MovableStruct {
1.841 + MovableStruct() { ++nb_dft_construct_call; }
1.842 + MovableStruct(MovableStruct const&) { ++nb_cpy_construct_call; }
1.843 +# if defined (STLPORT)
1.844 + MovableStruct(__move_source<MovableStruct>) { ++nb_mv_construct_call; }
1.845 +# endif
1.846 + ~MovableStruct() { ++nb_destruct_call; }
1.847 +
1.848 + MovableStruct& operator = (const MovableStruct&) {
1.849 + ++nb_assignment_call;
1.850 + return *this;
1.851 + }
1.852 +
1.853 + static void reset() {
1.854 + nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
1.855 + nb_assignment_call = 0;
1.856 + nb_destruct_call = 0;
1.857 + }
1.858 +
1.859 + static size_t nb_dft_construct_call;
1.860 + static size_t nb_cpy_construct_call;
1.861 + static size_t nb_mv_construct_call;
1.862 + static size_t nb_assignment_call;
1.863 + static size_t nb_destruct_call;
1.864 +
1.865 + //Dummy data just to control struct sizeof
1.866 + //As node allocator implementation align memory blocks on 2 * sizeof(void*)
1.867 + //we give MovableStruct the same size in order to have expected allocation
1.868 + //and not more
1.869 + void* dummy_data[2];
1.870 +};
1.871 +
1.872 +size_t MovableStruct::nb_dft_construct_call = 0;
1.873 +size_t MovableStruct::nb_cpy_construct_call = 0;
1.874 +size_t MovableStruct::nb_mv_construct_call = 0;
1.875 +size_t MovableStruct::nb_assignment_call = 0;
1.876 +size_t MovableStruct::nb_destruct_call = 0;
1.877 +
1.878 +# if defined (STLPORT)
1.879 +namespace std {
1.880 + _STLP_TEMPLATE_NULL
1.881 + struct __move_traits<MovableStruct> {
1.882 + typedef __true_type implemented;
1.883 + typedef __false_type complete;
1.884 + };
1.885 +}
1.886 +# endif
1.887 +
1.888 +struct CompleteMovableStruct {
1.889 + CompleteMovableStruct() { ++nb_dft_construct_call; }
1.890 + CompleteMovableStruct(CompleteMovableStruct const&) { ++nb_cpy_construct_call; }
1.891 +# if defined (STLPORT)
1.892 + CompleteMovableStruct(__move_source<CompleteMovableStruct>) { ++nb_mv_construct_call; }
1.893 +# endif
1.894 + ~CompleteMovableStruct() { ++nb_destruct_call; }
1.895 +
1.896 + CompleteMovableStruct& operator = (const CompleteMovableStruct&) {
1.897 + ++nb_assignment_call;
1.898 + return *this;
1.899 + }
1.900 + static void reset() {
1.901 + nb_dft_construct_call = nb_cpy_construct_call = nb_mv_construct_call = 0;
1.902 + nb_assignment_call = 0;
1.903 + nb_destruct_call = 0;
1.904 + }
1.905 +
1.906 + static size_t nb_dft_construct_call;
1.907 + static size_t nb_cpy_construct_call;
1.908 + static size_t nb_mv_construct_call;
1.909 + static size_t nb_assignment_call;
1.910 + static size_t nb_destruct_call;
1.911 +
1.912 + //See MovableStruct
1.913 + void* dummy_data[2];
1.914 +};
1.915 +
1.916 +size_t CompleteMovableStruct::nb_dft_construct_call = 0;
1.917 +size_t CompleteMovableStruct::nb_cpy_construct_call = 0;
1.918 +size_t CompleteMovableStruct::nb_mv_construct_call = 0;
1.919 +size_t CompleteMovableStruct::nb_assignment_call = 0;
1.920 +size_t CompleteMovableStruct::nb_destruct_call = 0;
1.921 +
1.922 +# if defined (STLPORT)
1.923 +namespace std {
1.924 + _STLP_TEMPLATE_NULL
1.925 + struct __move_traits<CompleteMovableStruct> {
1.926 + typedef __true_type implemented;
1.927 + typedef __true_type complete;
1.928 + };
1.929 +}
1.930 +# endif
1.931 +
1.932 +void MoveConstructorTest::move_traits()
1.933 +{
1.934 + {
1.935 + {
1.936 + vector<MovableStruct> vect;
1.937 + vect.push_back(MovableStruct());
1.938 + vect.push_back(MovableStruct());
1.939 + vect.push_back(MovableStruct());
1.940 + vect.push_back(MovableStruct());
1.941 +
1.942 + // vect contains 4 elements
1.943 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
1.944 +#if defined (STLPORT)
1.945 +# if !defined (_STLP_NO_MOVE_SEMANTIC)
1.946 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1.947 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
1.948 +# else
1.949 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
1.950 +# endif
1.951 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
1.952 +#elif !defined (_MSC_VER)
1.953 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 7 );
1.954 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 7 );
1.955 +#else
1.956 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 14 );
1.957 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 14 );
1.958 +#endif
1.959 + CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
1.960 +
1.961 + // Following test violate requirements to sequiences (23.1.1 Table 67)
1.962 + /*
1.963 + vect.insert(vect.begin() + 2, vect.begin(), vect.end());
1.964 + // vect contains 8 elements
1.965 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
1.966 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
1.967 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
1.968 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
1.969 + */
1.970 +
1.971 + MovableStruct::reset();
1.972 + vector<MovableStruct> v2 = vect;
1.973 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
1.974 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1.975 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1.976 + CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
1.977 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
1.978 +
1.979 + MovableStruct::reset();
1.980 + vect.insert(vect.begin() + 2, v2.begin(), v2.end() );
1.981 +
1.982 + // vect contains 8 elements
1.983 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
1.984 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.985 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1.986 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 4 );
1.987 +#else
1.988 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
1.989 +#endif
1.990 + CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
1.991 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
1.992 +
1.993 + MovableStruct::reset();
1.994 + vect.erase(vect.begin(), vect.begin() + 2 );
1.995 +
1.996 + // vect contains 6 elements
1.997 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.998 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 6 );
1.999 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 8 );
1.1000 +#else
1.1001 + CPPUNIT_ASSERT_EQUAL( MovableStruct::nb_assignment_call, 6 );
1.1002 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1.1003 +#endif
1.1004 +
1.1005 + MovableStruct::reset();
1.1006 + vect.erase(vect.end() - 2, vect.end());
1.1007 +
1.1008 + // vect contains 4 elements
1.1009 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1.1010 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1.1011 +
1.1012 + MovableStruct::reset();
1.1013 + vect.erase(vect.begin());
1.1014 +
1.1015 + // vect contains 3 elements
1.1016 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1017 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 3 );
1.1018 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
1.1019 +#else
1.1020 + CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 3 );
1.1021 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
1.1022 +#endif
1.1023 +
1.1024 + MovableStruct::reset();
1.1025 + }
1.1026 + //vect with 3 elements and v2 with 4 elements are now out of scope
1.1027 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
1.1028 + }
1.1029 +
1.1030 + {
1.1031 + {
1.1032 + vector<CompleteMovableStruct> vect;
1.1033 + vect.push_back(CompleteMovableStruct());
1.1034 + vect.push_back(CompleteMovableStruct());
1.1035 + vect.push_back(CompleteMovableStruct());
1.1036 + vect.push_back(CompleteMovableStruct());
1.1037 +
1.1038 + // vect contains 4 elements
1.1039 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
1.1040 +#if defined (STLPORT)
1.1041 +# if !defined (_STLP_NO_MOVE_SEMANTIC)
1.1042 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1.1043 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
1.1044 +# else
1.1045 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
1.1046 +# endif
1.1047 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1.1048 +#elif !defined (_MSC_VER)
1.1049 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 7 );
1.1050 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 7 );
1.1051 +#else
1.1052 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 14 );
1.1053 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 14 );
1.1054 +#endif
1.1055 +
1.1056 + // Following test violate requirements to sequiences (23.1.1 Table 67)
1.1057 + /*
1.1058 + vect.insert(vect.begin() + 2, vect.begin(), vect.end());
1.1059 +
1.1060 + // vect contains 8 elements
1.1061 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
1.1062 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
1.1063 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
1.1064 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1.1065 + */
1.1066 +
1.1067 + CompleteMovableStruct::reset();
1.1068 + vector<CompleteMovableStruct> v2 = vect;
1.1069 +
1.1070 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
1.1071 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1.1072 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1.1073 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
1.1074 +
1.1075 + CompleteMovableStruct::reset();
1.1076 + vect.insert(vect.begin() + 2, v2.begin(), v2.end());
1.1077 +
1.1078 + // vect contains 8 elements
1.1079 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
1.1080 +#if defined (STLPORT)
1.1081 +# if !defined (_STLP_NO_MOVE_SEMANTIC)
1.1082 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1.1083 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 4 );
1.1084 +# else
1.1085 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
1.1086 +# endif
1.1087 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
1.1088 +#else
1.1089 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
1.1090 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1.1091 +#endif
1.1092 +
1.1093 + CompleteMovableStruct::reset();
1.1094 + vect.erase(vect.begin(), vect.begin() + 2);
1.1095 +
1.1096 + // vect contains 6 elements
1.1097 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1098 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 6 );
1.1099 +#else
1.1100 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 6 );
1.1101 +#endif
1.1102 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
1.1103 +
1.1104 + CompleteMovableStruct::reset();
1.1105 + vect.erase(vect.end() - 2, vect.end());
1.1106 +
1.1107 + // vect contains 4 elements
1.1108 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1.1109 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
1.1110 +
1.1111 + CompleteMovableStruct::reset();
1.1112 + vect.erase(vect.begin());
1.1113 +
1.1114 + // vect contains 3 elements
1.1115 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1116 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 3 );
1.1117 +#else
1.1118 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 3 );
1.1119 +#endif
1.1120 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
1.1121 +
1.1122 + CompleteMovableStruct::reset();
1.1123 + }
1.1124 + //vect with 3 elements and v2 with 4 elements are now out of scope
1.1125 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
1.1126 + }
1.1127 +
1.1128 + {
1.1129 + MovableStruct::reset();
1.1130 + {
1.1131 + deque<MovableStruct> deq;
1.1132 + deq.push_back(MovableStruct());
1.1133 + deq.push_back(MovableStruct());
1.1134 + deq.push_back(MovableStruct());
1.1135 + deq.push_back(MovableStruct());
1.1136 +
1.1137 + // deq contains 4 elements
1.1138 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
1.1139 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1.1140 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1.1141 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 4 );
1.1142 +
1.1143 + // Following test violate requirements to sequiences (23.1.1 Table 67)
1.1144 + /*
1.1145 + deq.insert(deq.begin() + 2, deq.begin(), deq.end());
1.1146 + // deq contains 8 elements
1.1147 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 4 );
1.1148 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 8 );
1.1149 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 7 );
1.1150 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 11 );
1.1151 + */
1.1152 +
1.1153 + MovableStruct::reset();
1.1154 + deque<MovableStruct> d2 = deq;
1.1155 +
1.1156 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
1.1157 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1.1158 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1.1159 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
1.1160 +
1.1161 + MovableStruct::reset();
1.1162 + deq.insert(deq.begin() + 2, d2.begin(), d2.end() );
1.1163 +
1.1164 + // deq contains 8 elements
1.1165 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 0 );
1.1166 + CPPUNIT_ASSERT( MovableStruct::nb_cpy_construct_call == 4 );
1.1167 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1168 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 2 );
1.1169 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1.1170 +#else
1.1171 + CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 2 );
1.1172 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 0 );
1.1173 +#endif
1.1174 +
1.1175 + MovableStruct::reset();
1.1176 + deq.erase(deq.begin() + 1, deq.begin() + 3 );
1.1177 +
1.1178 + // deq contains 6 elements
1.1179 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1180 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
1.1181 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
1.1182 +#else
1.1183 + //Following check is highly deque implementation dependant so
1.1184 + //it might not always work...
1.1185 + CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
1.1186 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1.1187 +#endif
1.1188 +
1.1189 + MovableStruct::reset();
1.1190 + deq.erase(deq.end() - 3, deq.end() - 1);
1.1191 +
1.1192 + // deq contains 4 elements
1.1193 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1194 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 1 );
1.1195 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 );
1.1196 +#else
1.1197 + CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 1 );
1.1198 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 2 );
1.1199 +#endif
1.1200 +
1.1201 + MovableStruct::reset();
1.1202 + deq.erase(deq.begin());
1.1203 +
1.1204 + // deq contains 3 elements
1.1205 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1206 + CPPUNIT_ASSERT( MovableStruct::nb_mv_construct_call == 0 );
1.1207 +#else
1.1208 + CPPUNIT_ASSERT( MovableStruct::nb_assignment_call == 0 );
1.1209 +#endif
1.1210 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
1.1211 +
1.1212 + MovableStruct::reset();
1.1213 + }
1.1214 + //deq with 3 elements and d2 with 4 elements are now out of scope
1.1215 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 3 + 4 );
1.1216 + }
1.1217 +
1.1218 + {
1.1219 + CompleteMovableStruct::reset();
1.1220 + {
1.1221 + deque<CompleteMovableStruct> deq;
1.1222 + deq.push_back(CompleteMovableStruct());
1.1223 + deq.push_back(CompleteMovableStruct());
1.1224 + deq.push_back(CompleteMovableStruct());
1.1225 + deq.push_back(CompleteMovableStruct());
1.1226 +
1.1227 + // deq contains 4 elements
1.1228 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
1.1229 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1.1230 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1.1231 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1.1232 +
1.1233 + // Following test violate requirements to sequiences (23.1.1 Table 67)
1.1234 + /*
1.1235 + deq.insert(deq.begin() + 2, deq.begin(), deq.end());
1.1236 +
1.1237 + // deq contains 8 elements
1.1238 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 4 );
1.1239 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 8 );
1.1240 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 7 );
1.1241 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 4 );
1.1242 + */
1.1243 +
1.1244 + CompleteMovableStruct::reset();
1.1245 + deque<CompleteMovableStruct> d2 = deq;
1.1246 +
1.1247 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
1.1248 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1.1249 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1.1250 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
1.1251 +
1.1252 + CompleteMovableStruct::reset();
1.1253 + deq.insert(deq.begin() + 2, d2.begin(), d2.end());
1.1254 +
1.1255 + // deq contains 8 elements
1.1256 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_dft_construct_call == 0 );
1.1257 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_cpy_construct_call == 4 );
1.1258 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1259 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 2 );
1.1260 +#else
1.1261 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 2 );
1.1262 +#endif
1.1263 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 0 );
1.1264 +
1.1265 + CompleteMovableStruct::reset();
1.1266 + deq.erase(deq.begin() + 1, deq.begin() + 3);
1.1267 +
1.1268 + // deq contains 6 elements
1.1269 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1270 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
1.1271 +#else
1.1272 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
1.1273 +#endif
1.1274 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
1.1275 +
1.1276 + CompleteMovableStruct::reset();
1.1277 + deq.erase(deq.end() - 3, deq.end() - 1);
1.1278 +
1.1279 + // deq contains 4 elements
1.1280 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1281 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 1 );
1.1282 +#else
1.1283 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 1 );
1.1284 +#endif
1.1285 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 2 );
1.1286 +
1.1287 + CompleteMovableStruct::reset();
1.1288 + deq.erase(deq.begin());
1.1289 +
1.1290 + // deq contains 3 elements
1.1291 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_mv_construct_call == 0 );
1.1292 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_assignment_call == 0 );
1.1293 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 1 );
1.1294 +
1.1295 + CompleteMovableStruct::reset();
1.1296 + }
1.1297 + //deq with 3 elements and v2 with 4 elements are now out of scope
1.1298 + CPPUNIT_ASSERT( CompleteMovableStruct::nb_destruct_call == 3 + 4 );
1.1299 + }
1.1300 +}
1.1301 +
1.1302 +#if defined (STLPORT) && !defined (_STLP_NO_MOVE_SEMANTIC)
1.1303 +
1.1304 +# if defined (__GNUC__) && defined (_STLP_USE_NAMESPACES)
1.1305 +// libstdc++ sometimes exposed its own __true_type in
1.1306 +// global namespace resulting in an ambiguity.
1.1307 +# define __true_type std::__true_type
1.1308 +# define __false_type std::__false_type
1.1309 +# endif
1.1310 +
1.1311 +static bool type_to_bool(__true_type)
1.1312 +{ return true; }
1.1313 +static bool type_to_bool(__false_type)
1.1314 +{ return false; }
1.1315 +
1.1316 +template <class _Tp>
1.1317 +static bool is_movable(const _Tp&) {
1.1318 +#if defined (__BORLANDC__) || defined (__SYMBIAN32__)
1.1319 + return __type2bool<typename __move_traits<_Tp>::implemented>::_Ret != 0;
1.1320 +#else
1.1321 + typedef typename __move_traits<_Tp>::implemented _MovableTp;
1.1322 + return type_to_bool(_MovableTp());
1.1323 +#endif
1.1324 +}
1.1325 +
1.1326 +template <class _Tp>
1.1327 +static bool is_move_complete(const _Tp&) {
1.1328 + typedef __move_traits<_Tp> _TpMoveTraits;
1.1329 +#if defined (__BORLANDC__) || defined (__SYMBIAN32__)
1.1330 + return __type2bool<typename __move_traits<_Tp>::complete>::_Ret != 0;
1.1331 +#else
1.1332 + typedef typename _TpMoveTraits::complete _TpMoveComplete;
1.1333 + return type_to_bool(_TpMoveComplete());
1.1334 +#endif
1.1335 +}
1.1336 +
1.1337 +struct specially_allocated_struct {
1.1338 + bool operator < (specially_allocated_struct) const;
1.1339 +};
1.1340 +
1.1341 +struct struct_with_specialized_less {};
1.1342 +
1.1343 +namespace std
1.1344 +{
1.1345 + _STLP_TEMPLATE_NULL
1.1346 + class allocator<specially_allocated_struct>
1.1347 + {
1.1348 + //This allocator just represent what a STLport could do and in this
1.1349 + //case the STL containers implemented with it should still be movable
1.1350 + //but not completely as we cannot do any hypothesis on what is in this
1.1351 + //allocator.
1.1352 + public:
1.1353 + typedef specially_allocated_struct value_type;
1.1354 + typedef value_type * pointer;
1.1355 + typedef const value_type* const_pointer;
1.1356 + typedef value_type& reference;
1.1357 + typedef const value_type& const_reference;
1.1358 + typedef size_t size_type;
1.1359 + typedef ptrdiff_t difference_type;
1.1360 +#if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
1.1361 + template <class _Tp1> struct rebind {
1.1362 + typedef allocator<_Tp1> other;
1.1363 + };
1.1364 +#endif
1.1365 + allocator() _STLP_NOTHROW {}
1.1366 +#if defined (_STLP_MEMBER_TEMPLATES)
1.1367 + template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
1.1368 +#endif
1.1369 + allocator(const allocator&) _STLP_NOTHROW {}
1.1370 + ~allocator() _STLP_NOTHROW {}
1.1371 + pointer address(reference __x) const { return &__x; }
1.1372 + const_pointer address(const_reference __x) const { return &__x; }
1.1373 + pointer allocate(size_type, const void* = 0) { return 0; }
1.1374 + void deallocate(pointer, size_type) {}
1.1375 + size_type max_size() const _STLP_NOTHROW { return 0; }
1.1376 + void construct(pointer, const_reference) {}
1.1377 + void destroy(pointer) {}
1.1378 + };
1.1379 +
1.1380 + _STLP_TEMPLATE_NULL
1.1381 + struct less<struct_with_specialized_less> {
1.1382 + bool operator() (struct_with_specialized_less const&,
1.1383 + struct_with_specialized_less const&) const;
1.1384 + };
1.1385 +}
1.1386 +#endif
1.1387 +
1.1388 +void MoveConstructorTest::movable_declaration()
1.1389 +{
1.1390 +#if defined (STLPORT) && !defined (_STLP_DONT_SIMULATE_PARTIAL_SPEC_FOR_TYPE_TRAITS) && \
1.1391 + !defined (_STLP_NO_MOVE_SEMANTIC) && \
1.1392 + !defined (__DMC__)
1.1393 + //This test purpose is to check correct detection of the STL movable
1.1394 + //traits declaration
1.1395 + {
1.1396 + //string, wstring:
1.1397 + CPPUNIT_ASSERT( is_movable(string()) );
1.1398 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1399 + CPPUNIT_ASSERT( is_move_complete(string()) );
1.1400 +# else
1.1401 + CPPUNIT_ASSERT( !is_move_complete(string()) );
1.1402 +# endif
1.1403 +# if defined (_STLP_HAS_WCHAR_T)
1.1404 + CPPUNIT_ASSERT( is_movable(wstring()) );
1.1405 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1406 + CPPUNIT_ASSERT( is_move_complete(wstring()) );
1.1407 +# else
1.1408 + CPPUNIT_ASSERT( !is_move_complete(wstring()) );
1.1409 +# endif
1.1410 +# endif
1.1411 + }
1.1412 +
1.1413 +# if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1.1414 + {
1.1415 + //crope, wrope:
1.1416 + CPPUNIT_ASSERT( is_movable(crope()) );
1.1417 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1418 + CPPUNIT_ASSERT( is_move_complete(crope()) );
1.1419 +# else
1.1420 + CPPUNIT_ASSERT( !is_move_complete(crope()) );
1.1421 +# endif
1.1422 +# if defined (_STLP_HAS_WCHAR_T)
1.1423 + CPPUNIT_ASSERT( is_movable(wrope()) );
1.1424 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1425 + CPPUNIT_ASSERT( is_move_complete(wrope()) );
1.1426 +# else
1.1427 + CPPUNIT_ASSERT( !is_move_complete(wrope()) );
1.1428 +# endif
1.1429 +# endif
1.1430 + }
1.1431 +# endif
1.1432 +
1.1433 + {
1.1434 + //vector:
1.1435 + CPPUNIT_ASSERT( is_movable(vector<char>()) );
1.1436 + CPPUNIT_ASSERT( is_movable(vector<specially_allocated_struct>()) );
1.1437 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1438 + CPPUNIT_ASSERT( is_move_complete(vector<char>()) );
1.1439 + CPPUNIT_ASSERT( !is_move_complete(vector<specially_allocated_struct>()) );
1.1440 +# else
1.1441 + CPPUNIT_ASSERT( !is_move_complete(vector<char>()) );
1.1442 +# endif
1.1443 + }
1.1444 +
1.1445 + {
1.1446 + //deque:
1.1447 + CPPUNIT_ASSERT( is_movable(deque<char>()) );
1.1448 + CPPUNIT_ASSERT( is_movable(deque<specially_allocated_struct>()) );
1.1449 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1450 + CPPUNIT_ASSERT( is_move_complete(deque<char>()) );
1.1451 + CPPUNIT_ASSERT( !is_move_complete(deque<specially_allocated_struct>()) );
1.1452 +# else
1.1453 + CPPUNIT_ASSERT( !is_move_complete(deque<char>()) );
1.1454 +# endif
1.1455 + }
1.1456 +
1.1457 + {
1.1458 + //list:
1.1459 + CPPUNIT_ASSERT( is_movable(list<char>()) );
1.1460 + CPPUNIT_ASSERT( is_movable(list<specially_allocated_struct>()) );
1.1461 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1462 + CPPUNIT_ASSERT( is_move_complete(list<char>()) );
1.1463 + CPPUNIT_ASSERT( !is_move_complete(list<specially_allocated_struct>()) );
1.1464 +# else
1.1465 + CPPUNIT_ASSERT( !is_move_complete(list<char>()) );
1.1466 +# endif
1.1467 + }
1.1468 +
1.1469 +#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1.1470 + {
1.1471 + //slist:
1.1472 + CPPUNIT_ASSERT( is_movable(slist<char>()) );
1.1473 + CPPUNIT_ASSERT( is_movable(slist<specially_allocated_struct>()) );
1.1474 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1475 + CPPUNIT_ASSERT( is_move_complete(slist<char>()) );
1.1476 + CPPUNIT_ASSERT( !is_move_complete(slist<specially_allocated_struct>()) );
1.1477 +# else
1.1478 + CPPUNIT_ASSERT( !is_move_complete(slist<char>()) );
1.1479 +# endif
1.1480 + }
1.1481 +#endif
1.1482 +
1.1483 + {
1.1484 + //queue:
1.1485 + CPPUNIT_ASSERT( is_movable(queue<char>()) );
1.1486 + CPPUNIT_ASSERT( is_movable(queue<specially_allocated_struct>()) );
1.1487 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1488 + CPPUNIT_ASSERT( is_move_complete(queue<char>()) );
1.1489 + CPPUNIT_ASSERT( !is_move_complete(queue<specially_allocated_struct>()) );
1.1490 +# else
1.1491 + CPPUNIT_ASSERT( !is_move_complete(queue<char>()) );
1.1492 +# endif
1.1493 + }
1.1494 +
1.1495 + {
1.1496 + //stack:
1.1497 + CPPUNIT_ASSERT( is_movable(stack<char>()) );
1.1498 + CPPUNIT_ASSERT( is_movable(stack<specially_allocated_struct>()) );
1.1499 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1500 + CPPUNIT_ASSERT( is_move_complete(stack<char>()) );
1.1501 + CPPUNIT_ASSERT( !is_move_complete(stack<specially_allocated_struct>()) );
1.1502 +# else
1.1503 + CPPUNIT_ASSERT( !is_move_complete(stack<char>()) );
1.1504 +# endif
1.1505 + }
1.1506 +
1.1507 + {
1.1508 + //associative containers, set multiset, map, multimap:
1.1509 +
1.1510 + //For associative containers it is important that less is correctly recognize as
1.1511 + //the STLport less or a user specialized less:
1.1512 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1513 + CPPUNIT_ASSERT( is_move_complete(less<char>()) );
1.1514 +# endif
1.1515 + CPPUNIT_ASSERT( !is_move_complete(less<struct_with_specialized_less>()) );
1.1516 +
1.1517 + //set
1.1518 + CPPUNIT_ASSERT( is_movable(set<char>()) );
1.1519 + CPPUNIT_ASSERT( is_movable(set<specially_allocated_struct>()) );
1.1520 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1521 + CPPUNIT_ASSERT( is_move_complete(set<char>()) );
1.1522 + CPPUNIT_ASSERT( !is_move_complete(set<specially_allocated_struct>()) );
1.1523 +# else
1.1524 + CPPUNIT_ASSERT( !is_move_complete(set<char>()) );
1.1525 +# endif
1.1526 +
1.1527 + //multiset
1.1528 + CPPUNIT_ASSERT( is_movable(multiset<char>()) );
1.1529 + CPPUNIT_ASSERT( is_movable(multiset<specially_allocated_struct>()) );
1.1530 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1531 + CPPUNIT_ASSERT( is_move_complete(multiset<char>()) );
1.1532 + CPPUNIT_ASSERT( !is_move_complete(multiset<specially_allocated_struct>()) );
1.1533 +# else
1.1534 + CPPUNIT_ASSERT( !is_move_complete(multiset<char>()) );
1.1535 +# endif
1.1536 +
1.1537 + //map
1.1538 + CPPUNIT_ASSERT( is_movable(map<char, char>()) );
1.1539 + CPPUNIT_ASSERT( is_movable(map<specially_allocated_struct, char>()) );
1.1540 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1541 + CPPUNIT_ASSERT( is_move_complete(map<char, char>()) );
1.1542 + //Here even if allocator has been specialized for specially_allocated_struct
1.1543 + //this pecialization won't be used in default map instanciation as the default
1.1544 + //allocator is allocator<pair<specially_allocated_struct, char> >
1.1545 + CPPUNIT_ASSERT( is_move_complete(map<specially_allocated_struct, char>()) );
1.1546 +# else
1.1547 + CPPUNIT_ASSERT( !is_move_complete(map<char, char>()) );
1.1548 +# endif
1.1549 +
1.1550 + //multimap
1.1551 + CPPUNIT_ASSERT( is_movable(multimap<char, char>()) );
1.1552 + CPPUNIT_ASSERT( is_movable(multimap<specially_allocated_struct, char>()) );
1.1553 +# if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
1.1554 + CPPUNIT_ASSERT( is_move_complete(multimap<char, char>()) );
1.1555 + //Idem map remark
1.1556 + CPPUNIT_ASSERT( is_move_complete(multimap<specially_allocated_struct, char>()) );
1.1557 +# else
1.1558 + CPPUNIT_ASSERT( !is_move_complete(multimap<char, char>()) );
1.1559 +# endif
1.1560 + }
1.1561 +
1.1562 +# if defined (STLPORT)
1.1563 + {
1.1564 + //hashed containers, unordered_set unordered_multiset, unordered_map, unordered_multimap,
1.1565 + // hash_set, hash_multiset, hash_map, hash_multimap:
1.1566 +
1.1567 + //We only check that they are movable, completness is not yet supported
1.1568 + CPPUNIT_ASSERT( is_movable(unordered_set<char>()) );
1.1569 + CPPUNIT_ASSERT( is_movable(unordered_multiset<char>()) );
1.1570 + CPPUNIT_ASSERT( is_movable(unordered_map<char, char>()) );
1.1571 + CPPUNIT_ASSERT( is_movable(unordered_multimap<char, char>()) );
1.1572 +# if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
1.1573 + CPPUNIT_ASSERT( is_movable(hash_set<char>()) );
1.1574 + CPPUNIT_ASSERT( is_movable(hash_multiset<char>()) );
1.1575 + CPPUNIT_ASSERT( is_movable(hash_map<char, char>()) );
1.1576 + CPPUNIT_ASSERT( is_movable(hash_multimap<char, char>()) );
1.1577 +# endif
1.1578 + }
1.1579 +# endif
1.1580 +# endif
1.1581 +}
1.1582 +
1.1583 +#if defined (__BORLANDC__)
1.1584 +/* Specific Borland test case to show a really weird compiler behavior.
1.1585 + */
1.1586 +class Standalone
1.1587 +{
1.1588 +public:
1.1589 + //Uncomment following to pass the test
1.1590 + //Standalone() {}
1.1591 + ~Standalone() {}
1.1592 +
1.1593 + MovableStruct movableStruct;
1.1594 + vector<int> intVector;
1.1595 +};
1.1596 +
1.1597 +void MoveConstructorTest::nb_destructor_calls()
1.1598 +{
1.1599 + MovableStruct::reset();
1.1600 +
1.1601 + try
1.1602 + {
1.1603 + Standalone standalone;
1.1604 + throw "some exception";
1.1605 + MovableStruct movableStruct;
1.1606 + }
1.1607 + catch (const char*)
1.1608 + {
1.1609 + CPPUNIT_ASSERT( MovableStruct::nb_dft_construct_call == 1 );
1.1610 + CPPUNIT_ASSERT( MovableStruct::nb_destruct_call == 1 );
1.1611 + }
1.1612 +}
1.1613 +#endif