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