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
41using namespace boost::interprocess;
42
43//Function to check if both sets are equal
44template<class V1, class V2>
45bool copyable_only(V1 *, V2 *, ipcdetail::false_type)
46{
47 return true;
48}
49
50//Function to check if both sets are equal
51template<class V1, class V2>
52bool 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
104template<class IntType, template<class T, class SegmentManager> class AllocatorType >
105bool 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
288int 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

source code of boost/libs/interprocess/test/deque_test.cpp