1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2006-2012. 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/interprocess for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#ifndef BOOST_INTERPROCESS_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
12#define BOOST_INTERPROCESS_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
13
14#include <boost/interprocess/detail/config_begin.hpp>
15#include "expand_bwd_test_allocator.hpp"
16#include <boost/interprocess/detail/type_traits.hpp>
17#include <algorithm> //std::equal
18#include <vector>
19#include <iostream>
20#include <typeinfo>
21
22namespace boost { namespace interprocess { namespace test {
23
24template<class T>
25struct value_holder
26{
27 value_holder(T val) : m_value(val){}
28 value_holder(): m_value(0){}
29 ~value_holder(){ m_value = 0; }
30 bool operator == (const value_holder &other) const
31 { return m_value == other.m_value; }
32 bool operator != (const value_holder &other) const
33 { return m_value != other.m_value; }
34
35 T m_value;
36};
37
38template<class T>
39struct triple_value_holder
40{
41 triple_value_holder(T val)
42 : m_value1(val)
43 , m_value2(val)
44 , m_value3(val)
45 {}
46
47 triple_value_holder()
48 : m_value1(0)
49 , m_value2(0)
50 , m_value3(0)
51 {}
52
53 ~triple_value_holder()
54 { m_value1 = m_value2 = m_value3 = 0; }
55
56 bool operator == (const triple_value_holder &other) const
57 {
58 return m_value1 == other.m_value1
59 && m_value2 == other.m_value2
60 && m_value3 == other.m_value3;
61 }
62
63 bool operator != (const triple_value_holder &other) const
64 {
65 return m_value1 != other.m_value1
66 || m_value2 != other.m_value2
67 || m_value3 != other.m_value3;
68 }
69
70 T m_value1;
71 T m_value2;
72 T m_value3;
73};
74
75typedef value_holder<int> int_holder;
76typedef triple_value_holder<int> triple_int_holder;
77
78
79
80//Function to check if both sets are equal
81template <class Vector1, class Vector2>
82bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2)
83{
84 if(vector1.size() != vector2.size())
85 return false;
86 return std::equal(vector1.begin(), vector1.end(), vector2.begin());
87}
88
89template<class Vector>
90bool CheckUninitializedIsZero(const Vector & v)
91{
92 typedef typename Vector::value_type value_type;
93 typename Vector::size_type sz = v.size();
94 typename Vector::size_type extra = v.capacity() - v.size();
95 value_type comp(0);
96
97 const value_type *holder = &v[0] + sz;
98
99 while(extra--){
100 if(*holder++ != comp)
101 return false;
102 }
103 return true;
104}
105
106
107//This function tests all the possible combinations when
108//inserting data in a vector and expanding backwards
109template<class VectorWithExpandBwdAllocator>
110bool test_insert_with_expand_bwd()
111{
112 typedef typename VectorWithExpandBwdAllocator::value_type value_type;
113 typedef typename boost::interprocess::ipcdetail::remove_volatile<value_type>::type non_volatile_value_type;
114 typedef std::vector<non_volatile_value_type> Vect;
115 const std::size_t MemorySize = 1000;
116
117 //Distance old and new buffer
118 const std::size_t Offset[] =
119 { 350, 250, 150, 150,
120 150, 50, 50, 50 };
121 //Insert position
122 const std::size_t Position[] =
123 { 100, 100, 100, 100,
124 100, 100, 100, 100 };
125 //Initial vector size
126 const std::size_t InitialSize[] =
127 { 200, 200, 200, 200,
128 200, 200, 200, 200 };
129 //Size of the data to insert
130 const std::size_t InsertSize[] =
131 { 100, 100, 100, 200,
132 300, 25, 100, 200 };
133 //Number of tests
134 const std::size_t Iterations = sizeof(InsertSize)/sizeof(std::size_t);
135
136 for(std::size_t iteration = 0; iteration < Iterations; ++iteration)
137 {
138 value_type *memory = new value_type[MemorySize];
139 BOOST_TRY {
140 std::vector<non_volatile_value_type> initial_data;
141 initial_data.resize(InitialSize[iteration]);
142 for(std::size_t i = 0; i < InitialSize[iteration]; ++i){
143 initial_data[i] = non_volatile_value_type((int)i);
144 }
145
146 Vect data_to_insert;
147 data_to_insert.resize(InsertSize[iteration]);
148 for(std::size_t i = 0; i < InsertSize[iteration]; ++i){
149 data_to_insert[i] = value_type(-(int)i);
150 }
151
152 expand_bwd_test_allocator<value_type> alloc
153 (&memory[0], MemorySize, Offset[iteration]);
154 VectorWithExpandBwdAllocator vector(alloc);
155 vector.insert( vector.begin()
156 , initial_data.begin(), initial_data.end());
157 vector.insert( vector.begin() + std::ptrdiff_t(Position[iteration])
158 , data_to_insert.begin(), data_to_insert.end());
159 initial_data.insert(initial_data.begin() + std::ptrdiff_t(Position[iteration])
160 , data_to_insert.begin(), data_to_insert.end());
161 //Now check that values are equal
162 if(!CheckEqualVector(vector, initial_data)){
163 std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
164 << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
165 << " Iteration: " << iteration << std::endl;
166 return false;
167 }
168 }
169 BOOST_CATCH(...){
170 delete [](const_cast<non_volatile_value_type*>(memory));
171 BOOST_RETHROW
172 } BOOST_CATCH_END
173 delete [](const_cast<non_volatile_value_type*>(memory));
174 }
175
176 return true;
177}
178
179//This function tests all the possible combinations when
180//inserting data in a vector and expanding backwards
181template<class VectorWithExpandBwdAllocator>
182bool test_assign_with_expand_bwd()
183{
184 typedef typename VectorWithExpandBwdAllocator::value_type value_type;
185 typedef typename boost::interprocess::ipcdetail::remove_volatile<value_type>::type non_volatile_value_type;
186 const std::size_t MemorySize = 200;
187
188 const std::size_t Offset[] = { 50, 50, 50};
189 const std::size_t InitialSize[] = { 25, 25, 25};
190 const std::size_t InsertSize[] = { 15, 35, 55};
191 const std::size_t Iterations = sizeof(InsertSize)/sizeof(std::size_t);
192
193 for(std::size_t iteration = 0; iteration <Iterations; ++iteration)
194 {
195 value_type *memory = new value_type[MemorySize];
196 BOOST_TRY {
197 //Create initial data
198 std::vector<non_volatile_value_type> initial_data;
199 initial_data.resize(InitialSize[iteration]);
200 for(std::size_t i = 0; i < InitialSize[iteration]; ++i){
201 initial_data[i] = non_volatile_value_type((int)i);
202 }
203
204 //Create data to insert
205 std::vector<non_volatile_value_type> data_to_insert;
206 data_to_insert.resize(InsertSize[iteration]);
207 for(std::size_t i = 0; i < InsertSize[iteration]; ++i){
208 data_to_insert[i] = value_type(-(int)i);
209 }
210
211 //Insert initial data to the vector to test
212 expand_bwd_test_allocator<value_type> alloc
213 (&memory[0], MemorySize, Offset[iteration]);
214 VectorWithExpandBwdAllocator vector(alloc);
215 vector.insert( vector.begin()
216 , initial_data.begin(), initial_data.end());
217
218 //Insert data
219 vector.insert(vector.cbegin(), data_to_insert.begin(), data_to_insert.end());
220 initial_data.insert(initial_data.begin(), data_to_insert.begin(), data_to_insert.end());
221
222 //Now check that values are equal
223 if(!CheckEqualVector(vector, initial_data)){
224 std::cout << "test_insert_with_expand_bwd::CheckEqualVector failed." << std::endl
225 << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
226 << " Iteration: " << iteration << std::endl;
227 return false;
228 }
229 }
230 BOOST_CATCH(...){
231 delete [](const_cast<typename boost::interprocess::ipcdetail::remove_volatile<value_type>::type*>(memory));
232 BOOST_RETHROW
233 } BOOST_CATCH_END
234 delete [](const_cast<typename boost::interprocess::ipcdetail::remove_volatile<value_type>::type*>(memory));
235 }
236
237 return true;
238}
239
240//This function calls all tests
241template<class VectorWithExpandBwdAllocator>
242bool test_all_expand_bwd()
243{
244 std::cout << "Starting test_insert_with_expand_bwd." << std::endl << " Class: "
245 << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
246
247 if(!test_insert_with_expand_bwd<VectorWithExpandBwdAllocator>()){
248 std::cout << "test_allocation_direct_deallocation failed. Class: "
249 << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
250 return false;
251 }
252
253 std::cout << "Starting test_assign_with_expand_bwd." << std::endl << " Class: "
254 << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
255
256 if(!test_assign_with_expand_bwd<VectorWithExpandBwdAllocator>()){
257 std::cout << "test_allocation_direct_deallocation failed. Class: "
258 << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
259 return false;
260 }
261
262 return true;
263}
264
265}}} //namespace boost { namespace interprocess { namespace test {
266
267#include <boost/interprocess/detail/config_end.hpp>
268
269#endif //BOOST_INTERPROCESS_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
270
271

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