1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2006. 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)
6//
7// See http://www.boost.org/libs/container for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#ifndef BOOST_CONTAINER_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
12#define BOOST_CONTAINER_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
13
14#include <boost/container/detail/config_begin.hpp>
15#include <vector>
16#include <typeinfo>
17#include <iostream>
18#include "expand_bwd_test_allocator.hpp"
19#include <boost/container/detail/algorithm.hpp> //equal()
20#include "movable_int.hpp"
21#include <boost/move/make_unique.hpp>
22#include <boost/move/detail/force_ptr.hpp>
23
24namespace boost { namespace container { namespace test {
25
26//Function to check if both sets are equal
27template <class Vector1, class Vector2>
28bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2)
29{
30 if(vector1.size() != vector2.size())
31 return false;
32 return boost::container::algo_equal(vector1.begin(), vector1.end(), vector2.begin());
33}
34
35template<class Vector>
36bool CheckUninitializedIsZero(const Vector & v)
37{
38 typedef typename Vector::value_type value_type;
39 typename Vector::size_type sz = v.size();
40 typename Vector::size_type extra = v.capacity() - v.size();
41 value_type comp(0);
42
43 const value_type *holder = &v[0] + sz;
44
45 while(extra--){
46 if(*holder++ != comp)
47 return false;
48 }
49 return true;
50}
51
52
53//This function tests all the possible combinations when
54//inserting data in a vector and expanding backwards
55template<class VectorWithExpandBwdAllocator>
56bool test_insert_with_expand_bwd()
57{
58 typedef typename VectorWithExpandBwdAllocator::value_type value_type;
59 typedef std::vector<value_type> Vect;
60 const unsigned int MemorySize = 1000;
61
62 //Distance old and new buffer
63 const unsigned int Offset[] =
64 { 350, 300, 250, 200, 150, 100, 150, 100,
65 150, 50, 50, 50 };
66 //Initial vector size
67 const unsigned int InitialSize[] =
68 { 200, 200, 200, 200, 200, 200, 200, 200,
69 200, 200, 200, 200 };
70 //Size of the data to insert
71 const unsigned int InsertSize[] =
72 { 100, 100, 100, 100, 100, 100, 200, 200,
73 300, 25, 100, 200 };
74 //Number of tests
75 const unsigned int Iterations = sizeof(InsertSize)/sizeof(int);
76
77 //Insert position
78 const int Position[] =
79 { 0, 100, 200 };
80
81 for(unsigned int pos = 0; pos < sizeof(Position)/sizeof(Position[0]); ++pos){
82 if(!life_count<value_type>::check(0))
83 return false;
84
85 for(unsigned int iteration = 0; iteration < Iterations; ++iteration)
86 {
87 boost::movelib::unique_ptr<char[]> memptr =
88 boost::movelib::make_unique_definit<char[]>(n: MemorySize*sizeof(value_type));
89 value_type *memory = move_detail::force_ptr<value_type*>(memptr.get());
90 std::vector<value_type> initial_data;
91 initial_data.resize(InitialSize[iteration]);
92 for(unsigned int i = 0; i < InitialSize[iteration]; ++i){
93 initial_data[i] = static_cast<value_type>((int)i);
94 }
95
96 if(!life_count<value_type>::check(InitialSize[iteration]))
97 return false;
98 Vect data_to_insert;
99 data_to_insert.resize(InsertSize[iteration]);
100 for(unsigned int i = 0; i < InsertSize[iteration]; ++i){
101 data_to_insert[i] = static_cast<value_type>((int)-i);
102 }
103
104 if(!life_count<value_type>::check(InitialSize[iteration]+InsertSize[iteration]))
105 return false;
106
107 expand_bwd_test_allocator<value_type> alloc
108 (memory, MemorySize, Offset[iteration]);
109 VectorWithExpandBwdAllocator vector(alloc);
110 vector.insert( vector.begin()
111 , initial_data.begin(), initial_data.end());
112 vector.insert( vector.begin() + Position[pos]
113 , data_to_insert.begin(), data_to_insert.end());
114
115 if(!life_count<value_type>::check(InitialSize[iteration]*2+InsertSize[iteration]*2))
116 return false;
117
118 initial_data.insert(initial_data.begin() + Position[pos]
119 , data_to_insert.begin(), data_to_insert.end());
120 //Now check that values are equal
121 if(!CheckEqualVector(vector, initial_data)){
122 std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
123 << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
124 << " Iteration: " << iteration << std::endl;
125 return false;
126 }
127 }
128 if(!life_count<value_type>::check(0))
129 return false;
130 }
131
132 return true;
133}
134
135//This function tests all the possible combinations when
136//inserting data in a vector and expanding backwards
137template<class VectorWithExpandBwdAllocator>
138bool test_assign_with_expand_bwd()
139{
140 typedef typename VectorWithExpandBwdAllocator::value_type value_type;
141 const unsigned int MemorySize = 200;
142
143 const unsigned int Offset[] = { 50, 50, 50};
144 const unsigned int InitialSize[] = { 25, 25, 25};
145 const unsigned int InsertSize[] = { 15, 35, 55};
146 const unsigned int Iterations = sizeof(InsertSize)/sizeof(int);
147
148 for(unsigned int iteration = 0; iteration <Iterations; ++iteration)
149 {
150 boost::movelib::unique_ptr<char[]> memptr =
151 boost::movelib::make_unique_definit<char[]>(n: MemorySize*sizeof(value_type));
152 value_type *memory = move_detail::force_ptr<value_type*>(memptr.get());
153 //Create initial data
154 std::vector<value_type> initial_data;
155 initial_data.resize(InitialSize[iteration]);
156 for(unsigned int i = 0; i < InitialSize[iteration]; ++i){
157 initial_data[i] = static_cast<value_type>((int)i);
158 }
159
160 //Create data to assign
161 std::vector<value_type> data_to_insert;
162 data_to_insert.resize(InsertSize[iteration]);
163 for(unsigned int i = 0; i < InsertSize[iteration]; ++i){
164 data_to_insert[i] = static_cast<value_type>((int)-i);
165 }
166
167 //Insert initial data to the vector to test
168 expand_bwd_test_allocator<value_type> alloc
169 (memory, MemorySize, Offset[iteration]);
170 VectorWithExpandBwdAllocator vector(alloc);
171 vector.insert( vector.begin()
172 , initial_data.begin(), initial_data.end());
173
174 //Assign data
175 vector.insert(vector.cbegin(), data_to_insert.begin(), data_to_insert.end());
176 initial_data.insert(initial_data.begin(), data_to_insert.begin(), data_to_insert.end());
177
178 //Now check that values are equal
179 if(!CheckEqualVector(vector, initial_data)){
180 std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
181 << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
182 << " Iteration: " << iteration << std::endl;
183 return false;
184 }
185 }
186
187 return true;
188}
189
190//This function calls all tests
191template<class VectorWithExpandBwdAllocator>
192bool test_all_expand_bwd()
193{
194 std::cout << "Starting test_insert_with_expand_bwd." << std::endl << " Class: "
195 << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
196
197 if(!test_insert_with_expand_bwd<VectorWithExpandBwdAllocator>()){
198 std::cout << "test_allocation_direct_deallocation failed. Class: "
199 << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
200 return false;
201 }
202
203 std::cout << "Starting test_assign_with_expand_bwd." << std::endl << " Class: "
204 << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
205
206 if(!test_assign_with_expand_bwd<VectorWithExpandBwdAllocator>()){
207 std::cout << "test_allocation_direct_deallocation failed. Class: "
208 << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
209 return false;
210 }
211
212 return true;
213}
214
215}}} //namespace boost { namespace container { namespace test {
216
217#include <boost/container/detail/config_end.hpp>
218
219#endif //BOOST_CONTAINER_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
220

source code of boost/libs/container/test/expand_bwd_test_template.hpp