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