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 | #include <memory> |
12 | #include <deque> |
13 | #include <iostream> |
14 | #include <list> |
15 | |
16 | #include <boost/interprocess/managed_shared_memory.hpp> |
17 | #include <boost/interprocess/containers/deque.hpp> |
18 | #include <boost/interprocess/indexes/flat_map_index.hpp> |
19 | #include "print_container.hpp" |
20 | #include "check_equal_containers.hpp" |
21 | #include "dummy_test_allocator.hpp" |
22 | #include "movable_int.hpp" |
23 | #include <boost/interprocess/allocators/allocator.hpp> |
24 | #include "allocator_v1.hpp" |
25 | #include <boost/interprocess/exceptions.hpp> |
26 | #include <boost/move/utility_core.hpp> |
27 | #include <boost/interprocess/detail/mpl.hpp> |
28 | #include <boost/interprocess/detail/type_traits.hpp> |
29 | #include <string> |
30 | #include "get_process_id_name.hpp" |
31 | #include "emplace_test.hpp" |
32 | |
33 | /////////////////////////////////////////////////////////////////// |
34 | // // |
35 | // This example repeats the same operations with std::deque and // |
36 | // shmem_deque using the node allocator // |
37 | // and compares the values of both containers // |
38 | // // |
39 | /////////////////////////////////////////////////////////////////// |
40 | |
41 | using namespace boost::interprocess; |
42 | |
43 | //Function to check if both sets are equal |
44 | template<class V1, class V2> |
45 | bool copyable_only(V1 *, V2 *, ipcdetail::false_type) |
46 | { |
47 | return true; |
48 | } |
49 | |
50 | //Function to check if both sets are equal |
51 | template<class V1, class V2> |
52 | bool copyable_only(V1 *shmdeque, V2 *stddeque, ipcdetail::true_type) |
53 | { |
54 | typedef typename V1::value_type IntType; |
55 | std::size_t size = shmdeque->size(); |
56 | stddeque->insert(stddeque->end(), 50, 1); |
57 | shmdeque->insert(shmdeque->end(), 50, IntType(1)); |
58 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
59 | { |
60 | IntType move_me(1); |
61 | stddeque->insert(stddeque->begin()+std::ptrdiff_t(size/2u), 50u, 1); |
62 | shmdeque->insert(shmdeque->begin()+std::ptrdiff_t(size/2u), 50u, boost::move(move_me)); |
63 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
64 | } |
65 | { |
66 | IntType move_me(2); |
67 | shmdeque->assign(shmdeque->size()/2, boost::move(move_me)); |
68 | stddeque->assign(stddeque->size()/2, 2); |
69 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
70 | } |
71 | { |
72 | IntType move_me(1); |
73 | stddeque->clear(); |
74 | shmdeque->clear(); |
75 | stddeque->insert(stddeque->begin(), 50, 1); |
76 | shmdeque->insert(shmdeque->begin(), 50, boost::move(move_me)); |
77 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
78 | stddeque->insert(stddeque->begin()+20, 50, 1); |
79 | shmdeque->insert(shmdeque->begin()+20, 50, boost::move(move_me)); |
80 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
81 | stddeque->insert(stddeque->begin()+20, 20, 1); |
82 | shmdeque->insert(shmdeque->begin()+20, 20, boost::move(move_me)); |
83 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
84 | } |
85 | { |
86 | IntType move_me(1); |
87 | stddeque->clear(); |
88 | shmdeque->clear(); |
89 | stddeque->insert(stddeque->end(), 50, 1); |
90 | shmdeque->insert(shmdeque->end(), 50, boost::move(move_me)); |
91 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
92 | stddeque->insert(stddeque->end()-20, 50, 1); |
93 | shmdeque->insert(shmdeque->end()-20, 50, boost::move(move_me)); |
94 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
95 | stddeque->insert(stddeque->end()-20, 20, 1); |
96 | shmdeque->insert(shmdeque->end()-20, 20, boost::move(move_me)); |
97 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
98 | } |
99 | |
100 | return true; |
101 | } |
102 | |
103 | |
104 | template<class IntType, template<class T, class SegmentManager> class AllocatorType > |
105 | bool do_test() |
106 | { |
107 | //Customize managed_shared_memory class |
108 | typedef basic_managed_shared_memory |
109 | <char, |
110 | //simple_seq_fit<mutex_family>, |
111 | rbtree_best_fit<mutex_family>, |
112 | //flat_map_index |
113 | iset_index |
114 | > my_managed_shared_memory; |
115 | |
116 | //Alias AllocatorType type |
117 | typedef AllocatorType<IntType, my_managed_shared_memory::segment_manager> |
118 | shmem_allocator_t; |
119 | |
120 | //Alias deque types |
121 | typedef deque<IntType, shmem_allocator_t> MyShmDeque; |
122 | typedef std::deque<int> MyStdDeque; |
123 | const int Memsize = 128u*1024u; |
124 | const char *const shMemName = test::get_process_id_name(); |
125 | const int max = 100; |
126 | |
127 | /*BOOST_TRY*/{ |
128 | shared_memory_object::remove(filename: shMemName); |
129 | |
130 | //Create shared memory |
131 | my_managed_shared_memory segment(create_only, shMemName, Memsize); |
132 | |
133 | segment.reserve_named_objects(num: 10); |
134 | |
135 | //Shared memory allocator must be always be initialized |
136 | //since it has no default constructor |
137 | MyShmDeque *shmdeque = segment.template construct<MyShmDeque>("MyShmDeque" ) |
138 | (segment.get_segment_manager()); |
139 | |
140 | MyStdDeque *stddeque = new MyStdDeque; |
141 | |
142 | /*BOOST_TRY*/{ |
143 | //Compare several shared memory deque operations with std::deque |
144 | for(int i = 0; i < max*50; ++i){ |
145 | IntType move_me(i); |
146 | shmdeque->insert(shmdeque->end(), boost::move(move_me)); |
147 | stddeque->insert(position: stddeque->end(), x: i); |
148 | shmdeque->insert(shmdeque->end(), IntType(i)); |
149 | stddeque->insert(position: stddeque->end(), x: int(i)); |
150 | } |
151 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
152 | |
153 | shmdeque->clear(); |
154 | stddeque->clear(); |
155 | |
156 | for(int i = 0; i < max*50; ++i){ |
157 | IntType move_me(i); |
158 | shmdeque->push_back(boost::move(move_me)); |
159 | stddeque->push_back(x: i); |
160 | shmdeque->push_back(IntType(i)); |
161 | stddeque->push_back(x: i); |
162 | } |
163 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
164 | |
165 | shmdeque->clear(); |
166 | stddeque->clear(); |
167 | |
168 | for(int i = 0; i < max*50; ++i){ |
169 | IntType move_me(i); |
170 | shmdeque->push_front(boost::move(move_me)); |
171 | stddeque->push_front(x: i); |
172 | shmdeque->push_front(IntType(i)); |
173 | stddeque->push_front(x: int(i)); |
174 | } |
175 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
176 | |
177 | typename MyShmDeque::iterator it; |
178 | typename MyShmDeque::const_iterator cit = it; |
179 | (void)cit; |
180 | |
181 | shmdeque->erase(shmdeque->begin()++); |
182 | stddeque->erase(position: stddeque->begin()++); |
183 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
184 | |
185 | shmdeque->erase(shmdeque->begin()); |
186 | stddeque->erase(position: stddeque->begin()); |
187 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
188 | |
189 | { |
190 | //Initialize values |
191 | IntType aux_vect[50]; |
192 | for(int i = 0; i < 50; ++i){ |
193 | IntType move_me (-1); |
194 | aux_vect[i] = boost::move(move_me); |
195 | } |
196 | int aux_vect2[50]; |
197 | for(int i = 0; i < 50; ++i){ |
198 | aux_vect2[i] = -1; |
199 | } |
200 | |
201 | shmdeque->insert(shmdeque->end() |
202 | ,::boost::make_move_iterator(&aux_vect[0]) |
203 | ,::boost::make_move_iterator(aux_vect + 50)); |
204 | stddeque->insert(position: stddeque->end(), first: aux_vect2, last: aux_vect2 + 50); |
205 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
206 | |
207 | for(int i = 0, j = static_cast<int>(shmdeque->size()); i < j; ++i){ |
208 | shmdeque->erase(shmdeque->begin()); |
209 | stddeque->erase(position: stddeque->begin()); |
210 | } |
211 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
212 | } |
213 | { |
214 | IntType aux_vect[50]; |
215 | for(int i = 0; i < 50; ++i){ |
216 | IntType move_me(-1); |
217 | aux_vect[i] = boost::move(move_me); |
218 | } |
219 | int aux_vect2[50]; |
220 | for(int i = 0; i < 50; ++i){ |
221 | aux_vect2[i] = -1; |
222 | } |
223 | shmdeque->insert(shmdeque->begin() |
224 | ,::boost::make_move_iterator(&aux_vect[0]) |
225 | ,::boost::make_move_iterator(aux_vect + 50)); |
226 | stddeque->insert(position: stddeque->begin(), first: aux_vect2, last: aux_vect2 + 50); |
227 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
228 | } |
229 | |
230 | if(!copyable_only(shmdeque, stddeque |
231 | ,ipcdetail::bool_<!ipcdetail::is_same<IntType, test::movable_int>::value>())){ |
232 | return false; |
233 | } |
234 | |
235 | shmdeque->erase(shmdeque->begin()); |
236 | stddeque->erase(position: stddeque->begin()); |
237 | |
238 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
239 | |
240 | for(int i = 0; i < max; ++i){ |
241 | IntType move_me(i); |
242 | shmdeque->insert(shmdeque->begin(), boost::move(move_me)); |
243 | stddeque->insert(position: stddeque->begin(), x: i); |
244 | } |
245 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; |
246 | |
247 | //Test insertion from list |
248 | { |
249 | std::list<int> l(50, int(1)); |
250 | shmdeque->insert(shmdeque->begin(), l.begin(), l.end()); |
251 | stddeque->insert(position: stddeque->begin(), first: l.begin(), last: l.end()); |
252 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; |
253 | shmdeque->assign(l.begin(), l.end()); |
254 | stddeque->assign(first: l.begin(), last: l.end()); |
255 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; |
256 | } |
257 | |
258 | shmdeque->resize(100); |
259 | stddeque->resize(new_size: 100); |
260 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; |
261 | |
262 | shmdeque->resize(200); |
263 | stddeque->resize(new_size: 200); |
264 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; |
265 | |
266 | segment.template destroy<MyShmDeque>("MyShmDeque" ); |
267 | delete stddeque; |
268 | segment.shrink_to_fit_indexes(); |
269 | |
270 | if(!segment.all_memory_deallocated()) |
271 | return false; |
272 | }/* |
273 | BOOST_CATCH(std::exception &ex){ |
274 | std::cout << ex.what() << std::endl; |
275 | return false; |
276 | } BOOST_CATCH_END*/ |
277 | |
278 | std::cout << std::endl << "Test OK!" << std::endl; |
279 | }/* |
280 | BOOST_CATCH(...){ |
281 | shared_memory_object::remove(shMemName); |
282 | BOOST_RETHROW |
283 | } BOOST_CATCH_END*/ |
284 | shared_memory_object::remove(filename: shMemName); |
285 | return true; |
286 | } |
287 | |
288 | int main () |
289 | { |
290 | if(!do_test<int, allocator>()) |
291 | return 1; |
292 | |
293 | if(!do_test<test::movable_int, allocator>()) |
294 | return 1; |
295 | |
296 | if(!do_test<test::copyable_int, allocator>()) |
297 | return 1; |
298 | |
299 | if(!do_test<int, test::allocator_v1>()) |
300 | return 1; |
301 | |
302 | const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE); |
303 | |
304 | if(!boost::interprocess::test::test_emplace |
305 | < deque<test::EmplaceInt>, Options>()) |
306 | return 1; |
307 | |
308 | return 0; |
309 | } |
310 | |