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