• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-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_VECTOR_TEST_HEADER
12 #define BOOST_INTERPROCESS_TEST_VECTOR_TEST_HEADER
13 
14 #include <boost/interprocess/detail/config_begin.hpp>
15 
16 #include <boost/interprocess/exceptions.hpp>
17 #include <boost/move/utility_core.hpp>
18 #include <boost/interprocess/detail/mpl.hpp>
19 #include "print_container.hpp"
20 #include "check_equal_containers.hpp"
21 #include "movable_int.hpp"
22 
23 #include "get_process_id_name.hpp"
24 #include "emplace_test.hpp"
25 
26 #include <vector>
27 #include <list>
28 #include <string>
29 #include <iostream>
30 #include <cstddef>
31 
32 
33 namespace boost{
34 namespace interprocess{
35 namespace test{
36 
37 template<class V1, class V2>
copyable_only(V1 *,V2 *,boost::interprocess::ipcdetail::false_type)38 bool copyable_only(V1 *, V2 *, boost::interprocess::ipcdetail::false_type)
39 {
40    return true;
41 }
42 
43 //Function to check if both sets are equal
44 template<class V1, class V2>
copyable_only(V1 * shmvector,V2 * stdvector,boost::interprocess::ipcdetail::true_type)45 bool copyable_only(V1 *shmvector, V2 *stdvector, boost::interprocess::ipcdetail::true_type)
46 {
47    typedef typename V1::value_type IntType;
48    std::size_t size = shmvector->size();
49    stdvector->insert(stdvector->end(), 50, 1);
50    shmvector->insert(shmvector->end(), 50, IntType(1));
51    if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
52 
53    {
54       IntType move_me(1);
55       stdvector->insert(stdvector->begin()+size/2, 50, 1);
56       shmvector->insert(shmvector->begin()+size/2, 50, boost::move(move_me));
57       if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
58    }
59    {
60       IntType move_me(2);
61       shmvector->assign(shmvector->size()/2, boost::move(move_me));
62       stdvector->assign(stdvector->size()/2, 2);
63       if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
64    }
65    {
66       IntType move_me(3);
67       shmvector->assign(shmvector->size()*3-1, boost::move(move_me));
68       stdvector->assign(stdvector->size()*3-1, 3);
69       if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
70    }
71    return true;
72 }
73 
74 template<class ManagedSharedMemory
75         ,class MyShmVector>
vector_test()76 int vector_test()
77 {
78    typedef std::vector<int>                     MyStdVector;
79    typedef typename MyShmVector::value_type     IntType;
80 
81    std::string process_name;
82    test::get_process_id_name(process_name);
83 
84    const int Memsize = 65536;
85    const char *const shMemName = process_name.c_str();
86    const int max = 100;
87 
88    {
89       //Compare several shared memory vector operations with std::vector
90       //Create shared memory
91       shared_memory_object::remove(shMemName);
92       try{
93          ManagedSharedMemory segment(create_only, shMemName, Memsize);
94 
95          segment.reserve_named_objects(100);
96 
97          //Shared memory allocator must be always be initialized
98          //since it has no default constructor
99          MyShmVector *shmvector = segment.template construct<MyShmVector>("MyShmVector")
100                                  (segment.get_segment_manager());
101          MyStdVector *stdvector = new MyStdVector;
102 
103          shmvector->resize(100);
104          stdvector->resize(100);
105          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
106 
107          shmvector->resize(200);
108          stdvector->resize(200);
109          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
110 
111          shmvector->resize(0);
112          stdvector->resize(0);
113          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
114 
115          for(int i = 0; i < max; ++i){
116             IntType new_int(i);
117             shmvector->insert(shmvector->end(), boost::move(new_int));
118             stdvector->insert(stdvector->end(), i);
119             if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
120          }
121          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
122 
123          typename MyShmVector::iterator shmit(shmvector->begin());
124          typename MyStdVector::iterator stdit(stdvector->begin());
125          typename MyShmVector::const_iterator cshmit = shmit;
126          (void)cshmit;
127          ++shmit; ++stdit;
128          shmvector->erase(shmit);
129          stdvector->erase(stdit);
130          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
131 
132          shmvector->erase(shmvector->begin());
133          stdvector->erase(stdvector->begin());
134          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
135 
136          {
137             //Initialize values
138             IntType aux_vect[50];
139             for(int i = 0; i < 50; ++i){
140                IntType new_int(-1);
141                //BOOST_STATIC_ASSERT((::boost::move_ipcdetail::is_copy_constructible<boost::interprocess::test::movable_int>::value == false));
142                aux_vect[i] = boost::move(new_int);
143             }
144             int aux_vect2[50];
145             for(int i = 0; i < 50; ++i){
146                aux_vect2[i] = -1;
147             }
148 
149             shmvector->insert(shmvector->end()
150                               ,::boost::make_move_iterator(&aux_vect[0])
151                               ,::boost::make_move_iterator(aux_vect + 50));
152             stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
153             if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
154 
155             for(int i = 0, j = static_cast<int>(shmvector->size()); i < j; ++i){
156                shmvector->erase(shmvector->begin());
157                stdvector->erase(stdvector->begin());
158             }
159             if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
160          }
161          {
162             IntType aux_vect[50];
163             for(int i = 0; i < 50; ++i){
164                IntType new_int(-1);
165                aux_vect[i] = boost::move(new_int);
166             }
167             int aux_vect2[50];
168             for(int i = 0; i < 50; ++i){
169                aux_vect2[i] = -1;
170             }
171             shmvector->insert(shmvector->begin()
172                               ,::boost::make_move_iterator(&aux_vect[0])
173                               ,::boost::make_move_iterator(aux_vect + 50));
174             stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
175             if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
176          }
177 
178          shmvector->reserve(shmvector->size()*2);
179          stdvector->reserve(stdvector->size()*2);
180          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
181 
182          IntType push_back_this(1);
183          shmvector->push_back(boost::move(push_back_this));
184          stdvector->push_back(int(1));
185          shmvector->push_back(IntType(1));
186          stdvector->push_back(int(1));
187          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
188 
189          if(!copyable_only(shmvector, stdvector
190                         ,ipcdetail::bool_<!ipcdetail::is_same<IntType, test::movable_int>::value>())){
191             return 1;
192          }
193 
194          shmvector->erase(shmvector->begin());
195          stdvector->erase(stdvector->begin());
196          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
197 
198          for(int i = 0; i < max; ++i){
199             IntType insert_this(i);
200             shmvector->insert(shmvector->begin(), boost::move(insert_this));
201             stdvector->insert(stdvector->begin(), i);
202             shmvector->insert(shmvector->begin(), IntType(i));
203             stdvector->insert(stdvector->begin(), int(i));
204          }
205          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
206 
207          //Test insertion from list
208          {
209             std::list<int> l(50, int(1));
210             shmvector->insert(shmvector->begin(), l.begin(), l.end());
211             stdvector->insert(stdvector->begin(), l.begin(), l.end());
212             if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
213             shmvector->assign(l.begin(), l.end());
214             stdvector->assign(l.begin(), l.end());
215             if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
216          }
217 /*
218          std::size_t cap = shmvector->capacity();
219          shmvector->reserve(cap*2);
220          stdvector->reserve(cap*2);
221          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
222          shmvector->resize(0);
223          stdvector->resize(0);
224          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
225          shmvector->resize(cap*2);
226          stdvector->resize(cap*2);
227          if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
228 */
229 
230          delete stdvector;
231          segment.template destroy<MyShmVector>("MyShmVector");
232          segment.shrink_to_fit_indexes();
233 
234          if(!segment.all_memory_deallocated())
235             return 1;
236       }
237       catch(std::exception &ex){
238          shared_memory_object::remove(shMemName);
239          std::cout << ex.what() << std::endl;
240          return 1;
241       }
242    }
243    shared_memory_object::remove(shMemName);
244    std::cout << std::endl << "Test OK!" << std::endl;
245    return 0;
246 }
247 
248 }  //namespace test{
249 }  //namespace interprocess{
250 }  //namespace boost{
251 
252 #include <boost/interprocess/detail/config_end.hpp>
253 
254 #endif
255