]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
7c673cae FG |
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()+size/2, 50, 1); | |
62 | shmdeque->insert(shmdeque->begin()+size/2, 50, 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 = 65536; | |
124 | const char *const shMemName = test::get_process_id_name(); | |
125 | const int max = 100; | |
126 | ||
127 | /*try*/{ | |
128 | shared_memory_object::remove(shMemName); | |
129 | ||
130 | //Create shared memory | |
131 | my_managed_shared_memory segment(create_only, shMemName, Memsize); | |
132 | ||
133 | segment.reserve_named_objects(100); | |
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 | /*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(stddeque->end(), i); | |
148 | shmdeque->insert(shmdeque->end(), IntType(i)); | |
149 | stddeque->insert(stddeque->end(), 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(i); | |
160 | shmdeque->push_back(IntType(i)); | |
161 | stddeque->push_back(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(i); | |
172 | shmdeque->push_front(IntType(i)); | |
173 | stddeque->push_front(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(stddeque->begin()++); | |
183 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return false; | |
184 | ||
185 | shmdeque->erase(shmdeque->begin()); | |
186 | stddeque->erase(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(stddeque->end(), aux_vect2, 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(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(stddeque->begin(), aux_vect2, 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(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(stddeque->begin(), 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(stddeque->begin(), l.begin(), l.end()); | |
252 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; | |
253 | shmdeque->assign(l.begin(), l.end()); | |
254 | stddeque->assign(l.begin(), l.end()); | |
255 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; | |
256 | } | |
257 | ||
258 | shmdeque->resize(100); | |
259 | stddeque->resize(100); | |
260 | if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1; | |
261 | ||
262 | shmdeque->resize(200); | |
263 | stddeque->resize(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 | catch(std::exception &ex){ | |
274 | std::cout << ex.what() << std::endl; | |
275 | return false; | |
276 | }*/ | |
277 | ||
278 | std::cout << std::endl << "Test OK!" << std::endl; | |
279 | }/* | |
280 | catch(...){ | |
281 | shared_memory_object::remove(shMemName); | |
282 | throw; | |
283 | }*/ | |
284 | shared_memory_object::remove(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 | } |