1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
12 #define BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
14 #include <boost/container/detail/config_begin.hpp>
20 #include <boost/move/utility_core.hpp>
21 #include <boost/container/detail/mpl.hpp>
22 #include <boost/move/utility_core.hpp>
23 #include <boost/move/iterator.hpp>
24 #include <boost/move/make_unique.hpp>
25 #include <boost/core/no_exceptions_support.hpp>
26 #include <boost/static_assert.hpp>
28 #include "print_container.hpp"
29 #include "check_equal_containers.hpp"
30 #include "movable_int.hpp"
31 #include "emplace_test.hpp"
32 #include "input_from_forward_iterator.hpp"
33 #include "insert_test.hpp"
34 #include "container_common_tests.hpp"
45 template<class Vector>
46 struct vector_hash_function_capacity
48 typedef typename Vector::size_type size_type;
49 template <typename U, size_type (U::*)() const> struct Check;
50 template <typename U> static char func(Check<U, &U::capacity> *);
51 template <typename U> static int func(...);
54 static const bool value = sizeof(func<Vector>(0)) == sizeof(char);
57 template<class V1, class V2>
58 bool vector_vector_hash_function_capacity_only(V1&, V2&, boost::container::dtl::false_type)
63 template<class MyBoostVector, class MyStdVector>
64 bool vector_vector_hash_function_capacity_only(MyBoostVector&boostvector, MyStdVector&stdvector, boost::container::dtl::true_type)
66 //deque has no reserve
67 boostvector.reserve(boostvector.size()*2);
68 stdvector.reserve(stdvector.size()*2);
69 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
71 std::size_t cap = boostvector.capacity();
72 boostvector.reserve(cap*2);
73 stdvector.reserve(cap*2);
74 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
75 boostvector.resize(0);
77 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
79 boostvector.resize(cap*2);
80 stdvector.resize(cap*2);
81 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
83 boostvector.resize(cap*2);
84 stdvector.resize(cap*2);
85 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
91 template<class V1, class V2>
92 bool vector_copyable_only(V1&, V2&, boost::container::dtl::false_type)
97 //Function to check if both sets are equal
98 template<class MyBoostVector, class MyStdVector>
99 bool vector_copyable_only(MyBoostVector &boostvector, MyStdVector &stdvector, boost::container::dtl::true_type)
101 typedef typename MyBoostVector::value_type IntType;
102 std::size_t size = boostvector.size();
103 boostvector.insert(boostvector.end(), 50, IntType(1));
104 stdvector.insert(stdvector.end(), 50, 1);
105 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
109 boostvector.insert(boostvector.begin()+size/2, 50, boost::move(move_me));
110 stdvector.insert(stdvector.begin()+size/2, 50, 1);
111 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
115 boostvector.assign(boostvector.size()/2, boost::move(move_me));
116 stdvector.assign(stdvector.size()/2, 2);
117 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
121 boostvector.assign(boostvector.size()*3-1, boost::move(move_me));
122 stdvector.assign(stdvector.size()*3-1, 3);
123 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
128 const IntType ccopy_me(3);
129 boostvector.push_back(copy_me);
130 stdvector.push_back(int(3));
131 boostvector.push_back(ccopy_me);
132 stdvector.push_back(int(3));
133 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
135 { //Vector(const Vector &)
136 ::boost::movelib::unique_ptr<MyBoostVector> const pv1 =
137 ::boost::movelib::make_unique<MyBoostVector>(boostvector);
138 ::boost::movelib::unique_ptr<MyStdVector> const pv2 =
139 ::boost::movelib::make_unique<MyStdVector>(stdvector);
141 MyBoostVector &v1 = *pv1;
142 MyStdVector &v2 = *pv2;
146 boostvector.assign(v1.begin(), v1.end());
147 stdvector.assign(v2.begin(), v2.end());
148 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
150 { //Vector(const Vector &, alloc)
151 ::boost::movelib::unique_ptr<MyBoostVector> const pv1 =
152 ::boost::movelib::make_unique<MyBoostVector>(boostvector, typename MyBoostVector::allocator_type());
153 ::boost::movelib::unique_ptr<MyStdVector> const pv2 =
154 ::boost::movelib::make_unique<MyStdVector>(stdvector);
156 MyBoostVector &v1 = *pv1;
157 MyStdVector &v2 = *pv2;
161 boostvector.assign(v1.begin(), v1.end());
162 stdvector.assign(v2.begin(), v2.end());
163 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
166 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
167 ::boost::movelib::make_unique<MyStdVector>(100, int(5));
168 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
169 ::boost::movelib::make_unique<MyBoostVector>(100, IntType(5));
170 if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
172 { //Vector(n, T, alloc)
173 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
174 ::boost::movelib::make_unique<MyStdVector>(100, int(5));
175 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
176 ::boost::movelib::make_unique<MyBoostVector>(100, IntType(5), typename MyBoostVector::allocator_type());
177 if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
180 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
181 ::boost::movelib::make_unique<MyStdVector>(100);
182 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
183 ::boost::movelib::make_unique<MyBoostVector>(100);
184 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
185 ::boost::movelib::make_unique<MyBoostVector>(boostvectorp->begin(), boostvectorp->end());
186 if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
188 { //Vector(It, It, alloc)
189 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
190 ::boost::movelib::make_unique<MyStdVector>(100);
191 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
192 ::boost::movelib::make_unique<MyBoostVector>(100);
193 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
194 ::boost::movelib::make_unique<MyBoostVector>(boostvectorp->begin(), boostvectorp->end(), typename MyBoostVector::allocator_type());
195 if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
198 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
199 ::boost::movelib::make_unique<MyStdVector>();
200 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
201 ::boost::movelib::make_unique<MyBoostVector>();
202 stdvectorp->resize(100, int(9));
203 boostvectorp->resize(100, IntType(9));
204 if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
208 //Copy constructor test
209 MyBoostVector bcopy((const MyBoostVector&) boostvector);
210 MyStdVector scopy((const MyStdVector&) stdvector);
211 MyBoostVector bcopy2(boostvector);
212 MyStdVector scopy2(stdvector);
214 if(!test::CheckEqualContainers(bcopy, scopy)) return false;
215 if(!test::CheckEqualContainers(bcopy2, scopy2)) return false;
217 //Assignment from a smaller vector
218 bcopy2.erase(bcopy2.begin() + bcopy2.size()/2, bcopy2.end());
219 scopy2.erase(scopy2.begin() + scopy2.size()/2, scopy2.end());
222 if(!test::CheckEqualContainers(bcopy, scopy)) return false;
224 //Assignment from a bigger vector with capacity
225 bcopy2 = boostvector;
227 if(!test::CheckEqualContainers(bcopy2, scopy2)) return false;
229 //Assignment from bigger vector with no capacity
230 bcopy2.erase(bcopy2.begin() + bcopy2.size()/2, bcopy2.end());
231 scopy2.erase(scopy2.begin() + scopy2.size()/2, scopy2.end());
232 bcopy2.shrink_to_fit();
233 MyStdVector(scopy2).swap(scopy2);
235 bcopy2 = boostvector;
237 if(!test::CheckEqualContainers(bcopy, scopy)) return false;
239 //Assignment with equal capacity
240 bcopy2 = boostvector;
242 if(!test::CheckEqualContainers(bcopy2, scopy2)) return false;
248 template<class MyBoostVector>
251 typedef std::vector<int> MyStdVector;
252 typedef typename MyBoostVector::value_type IntType;
255 if(!test_range_insertion<MyBoostVector>()){
259 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
260 ::boost::movelib::make_unique<MyBoostVector>(100);
261 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
262 ::boost::movelib::make_unique<MyStdVector>(100);
263 if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
266 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
267 ::boost::movelib::make_unique<MyBoostVector>(100, typename MyBoostVector::allocator_type());
268 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
269 ::boost::movelib::make_unique<MyStdVector>(100);
270 if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
272 { //Vector(Vector &&)
273 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
274 ::boost::movelib::make_unique<MyStdVector>(100);
275 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
276 ::boost::movelib::make_unique<MyBoostVector>(100);
277 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
278 ::boost::movelib::make_unique<MyBoostVector>(::boost::move(*boostvectorp));
279 if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
281 { //Vector(Vector &&, alloc)
282 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
283 ::boost::movelib::make_unique<MyStdVector>(100);
284 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
285 ::boost::movelib::make_unique<MyBoostVector>(100);
286 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
287 ::boost::movelib::make_unique<MyBoostVector>
288 (::boost::move(*boostvectorp), typename MyBoostVector::allocator_type());
289 if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
291 { //Vector operator=(Vector &&)
292 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
293 ::boost::movelib::make_unique<MyStdVector>(100);
294 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
295 ::boost::movelib::make_unique<MyBoostVector>(100);
296 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
297 ::boost::movelib::make_unique<MyBoostVector>();
298 *boostvectorp2 = ::boost::move(*boostvectorp);
299 if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
302 ::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp = ::boost::movelib::make_unique<MyBoostVector>();
303 ::boost::movelib::unique_ptr<MyStdVector> const stdvectorp = ::boost::movelib::make_unique<MyStdVector>();
305 MyBoostVector & boostvector = *boostvectorp;
306 MyStdVector & stdvector = *stdvectorp;
308 boostvector.resize(100);
309 stdvector.resize(100);
310 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
312 boostvector.resize(200);
313 stdvector.resize(200);
314 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
316 boostvector.resize(0);
318 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
320 for(int i = 0; i < max; ++i){
322 boostvector.insert(boostvector.end(), boost::move(new_int));
323 stdvector.insert(stdvector.end(), i);
324 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
326 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
328 typename MyBoostVector::iterator boostit(boostvector.begin());
329 typename MyStdVector::iterator stdit(stdvector.begin());
330 typename MyBoostVector::const_iterator cboostit = boostit;
333 boostvector.erase(boostit);
334 stdvector.erase(stdit);
335 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
337 boostvector.erase(boostvector.begin());
338 stdvector.erase(stdvector.begin());
339 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
341 boostvector.erase(boostvector.end()-1);
342 stdvector.erase(stdvector.end()-1);
343 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
347 IntType aux_vect[50];
348 for(int i = 0; i < 50; ++i){
350 BOOST_STATIC_ASSERT((boost::container::test::is_copyable<boost::container::test::movable_int>::value == false));
351 aux_vect[i] = boost::move(new_int);
354 for(int i = 0; i < 50; ++i){
357 typename MyBoostVector::iterator insert_it =
358 boostvector.insert(boostvector.end()
359 ,boost::make_move_iterator(&aux_vect[0])
360 ,boost::make_move_iterator(aux_vect + 50));
361 if(std::size_t(boost::container::iterator_distance(insert_it, boostvector.end())) != 50) return 1;
362 stdvector.insert(stdvector.end(), aux_vect2, aux_vect2 + 50);
363 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
365 for(int i = 0, j = static_cast<int>(boostvector.size()); i < j; ++i){
366 boostvector.erase(boostvector.begin());
367 stdvector.erase(stdvector.begin());
369 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
372 boostvector.resize(100);
373 stdvector.resize(100);
374 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
376 IntType aux_vect[50];
377 for(int i = 0; i < 50; ++i){
379 aux_vect[i] = boost::move(new_int);
382 for(int i = 0; i < 50; ++i){
385 typename MyBoostVector::size_type old_size = boostvector.size();
386 typename MyBoostVector::iterator insert_it =
387 boostvector.insert(boostvector.begin() + old_size/2
388 ,boost::make_move_iterator(&aux_vect[0])
389 ,boost::make_move_iterator(aux_vect + 50));
390 if(boostvector.begin() + old_size/2 != insert_it) return 1;
391 stdvector.insert(stdvector.begin() + old_size/2, aux_vect2, aux_vect2 + 50);
392 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
394 for(int i = 0; i < 50; ++i){
396 aux_vect[i] = boost::move(new_int);
399 for(int i = 0; i < 50; ++i){
402 old_size = boostvector.size();
403 //Now try with input iterators instead
404 insert_it = boostvector.insert(boostvector.begin() + old_size/2
405 ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
406 ,boost::make_move_iterator(make_input_from_forward_iterator(aux_vect + 50))
408 if(boostvector.begin() + old_size/2 != insert_it) return 1;
409 stdvector.insert(stdvector.begin() + old_size/2, aux_vect2, aux_vect2 + 50);
410 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
413 boostvector.shrink_to_fit();
414 MyStdVector(stdvector).swap(stdvector);
415 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
417 boostvector.shrink_to_fit();
418 MyStdVector(stdvector).swap(stdvector);
419 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
421 { //push_back with not enough capacity
422 IntType push_back_this(1);
423 boostvector.push_back(boost::move(push_back_this));
424 stdvector.push_back(int(1));
425 boostvector.push_back(IntType(1));
426 stdvector.push_back(int(1));
427 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
431 const IntType test_this(1);
432 if(test_this != boostvector.back()) return 1;
434 { //pop_back with enough capacity
435 boostvector.pop_back();
436 boostvector.pop_back();
437 stdvector.pop_back();
438 stdvector.pop_back();
440 IntType push_back_this(1);
441 boostvector.push_back(boost::move(push_back_this));
442 stdvector.push_back(int(1));
443 boostvector.push_back(IntType(1));
444 stdvector.push_back(int(1));
445 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
448 if(!vector_copyable_only(boostvector, stdvector
449 ,dtl::bool_<boost::container::test::is_copyable<IntType>::value>())){
453 boostvector.erase(boostvector.begin());
454 stdvector.erase(stdvector.begin());
455 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
457 for(int i = 0; i < max; ++i){
458 IntType insert_this(i);
459 boostvector.insert(boostvector.begin(), boost::move(insert_this));
460 stdvector.insert(stdvector.begin(), i);
461 boostvector.insert(boostvector.begin(), IntType(i));
462 stdvector.insert(stdvector.begin(), int(i));
464 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
466 //some comparison operators
467 if(!(boostvector == boostvector))
469 if(boostvector != boostvector)
471 if(boostvector < boostvector)
473 if(boostvector > boostvector)
475 if(!(boostvector <= boostvector))
477 if(!(boostvector >= boostvector))
480 //Test insertion from list
482 std::list<int> l(50, int(1));
483 typename MyBoostVector::iterator it_insert =
484 boostvector.insert(boostvector.begin(), l.begin(), l.end());
485 if(boostvector.begin() != it_insert) return 1;
486 stdvector.insert(stdvector.begin(), l.begin(), l.end());
487 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
488 boostvector.assign(l.begin(), l.end());
489 stdvector.assign(l.begin(), l.end());
490 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
494 boostvector.assign(make_input_from_forward_iterator(l.begin()), make_input_from_forward_iterator(l.end()));
495 stdvector.assign(l.begin(), l.end());
496 if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
499 if(!vector_vector_hash_function_capacity_only(boostvector, stdvector, dtl::bool_<vector_hash_function_capacity<MyBoostVector>::value>()))
504 boostvector.shrink_to_fit();
505 MyStdVector(stdvector).swap(stdvector);
506 if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
508 boostvector.resize(100);
509 if(!test_nth_index_of(boostvector))
513 std::cout << std::endl << "Test OK!" << std::endl;
517 template<typename VectorContainerType>
518 bool test_vector_methods_with_initializer_list_as_argument_for()
520 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
521 typedef typename VectorContainerType::allocator_type allocator_type;
523 const VectorContainerType testedVector = {1, 2, 3};
524 const std::vector<int> expectedVector = {1, 2, 3};
525 if(!test::CheckEqualContainers(testedVector, expectedVector)) return false;
528 const VectorContainerType testedVector( { 1, 2, 3 }, allocator_type() );
529 const std::vector<int> expectedVector = {1, 2, 3};
530 if(!test::CheckEqualContainers(testedVector, expectedVector)) return false;
533 VectorContainerType testedVector = {1, 2, 3};
534 testedVector = {11, 12, 13};
536 const std::vector<int> expectedVector = {11, 12, 13};
537 if(!test::CheckEqualContainers(testedVector, expectedVector)) return false;
541 VectorContainerType testedVector = {1, 2, 3};
542 testedVector.assign({5, 6, 7});
544 const std::vector<int> expectedVector = {5, 6, 7};
545 if(!test::CheckEqualContainers(testedVector, expectedVector)) return false;
549 VectorContainerType testedVector = {1, 2, 3};
550 testedVector.insert(testedVector.cend(), {5, 6, 7});
552 const std::vector<int> expectedVector = {1, 2, 3, 5, 6, 7};
553 if(!test::CheckEqualContainers(testedVector, expectedVector)) return false;
562 } //namespace container {
565 #include <boost/container/detail/config_end.hpp>
567 #endif //BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER