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_SET_TEST_HEADER
12#define BOOST_INTERPROCESS_TEST_SET_TEST_HEADER
13
14#include <boost/interprocess/detail/config_begin.hpp>
15#include "check_equal_containers.hpp"
16#include "print_container.hpp"
17#include <boost/move/utility_core.hpp>
18#include "get_process_id_name.hpp"
19
20#include <functional>
21
22namespace boost{
23namespace interprocess{
24namespace test{
25
26template<class ManagedSharedMemory
27 ,class MyShmSet
28 ,class MyStdSet
29 ,class MyShmMultiSet
30 ,class MyStdMultiSet>
31int set_test ()
32{
33 typedef typename MyShmSet::value_type IntType;
34 const int Memsize = 128u * 1024u;
35 const char *const shMemName = test::get_process_id_name();
36 const int max = 100;
37
38 BOOST_TRY{
39 //Create shared memory
40 shared_memory_object::remove(filename: shMemName);
41 ManagedSharedMemory segment(create_only, shMemName, Memsize);
42
43 segment.reserve_named_objects(10);
44
45 //Shared memory allocator must be always be initialized
46 //since it has no default constructor
47 MyShmSet *shmset =
48 segment.template construct<MyShmSet>("MyShmSet")
49 (std::less<IntType>(), segment.get_segment_manager());
50
51 MyStdSet *stdset = new MyStdSet;
52
53 MyShmMultiSet *shmmultiset =
54 segment.template construct<MyShmMultiSet>("MyShmMultiSet")
55 (std::less<IntType>(), segment.get_segment_manager());
56
57 MyStdMultiSet *stdmultiset = new MyStdMultiSet;
58
59 //Test construction from a range
60 {
61 IntType aux_vect[50];
62 for(int i = 0; i < 50; ++i){
63 IntType move_me(i/2);
64 aux_vect[i] = boost::move(move_me);
65 }
66 int aux_vect2[50];
67 for(int i = 0; i < 50; ++i){
68 aux_vect2[i] = i/2;
69 }
70 IntType aux_vect3[50];
71 for(int i = 0; i < 50; ++i){
72 IntType move_me(i/2);
73 aux_vect3[i] = boost::move(move_me);
74 }
75
76 MyShmSet *shmset2 =
77 segment.template construct<MyShmSet>("MyShmSet2")
78 ( ::boost::make_move_iterator(&aux_vect[0])
79 , ::boost::make_move_iterator(aux_vect + 50)
80 , std::less<IntType>(), segment.get_segment_manager());
81
82 MyStdSet *stdset2 = new MyStdSet(aux_vect2, aux_vect2 + 50);
83
84 MyShmMultiSet *shmmultiset2 =
85 segment.template construct<MyShmMultiSet>("MyShmMultiSet2")
86 ( ::boost::make_move_iterator(&aux_vect3[0])
87 , ::boost::make_move_iterator(aux_vect3 + 50)
88 , std::less<IntType>(), segment.get_segment_manager());
89
90 MyStdMultiSet *stdmultiset2 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
91 if(!CheckEqualContainers(shmset2, stdset2)){
92 std::cout << "Error in construct<MyShmSet>(MyShmSet2)" << std::endl;
93 return 1;
94 }
95 if(!CheckEqualContainers(shmmultiset2, stdmultiset2)){
96 std::cout << "Error in construct<MyShmMultiSet>(MyShmMultiSet2)" << std::endl;
97 return 1;
98 }
99
100 //ordered range insertion
101 for(int i = 0; i < 50; ++i){
102 IntType move_me(i);
103 aux_vect[i] = boost::move(move_me);
104 }
105
106 for(int i = 0; i < 50; ++i){
107 aux_vect2[i] = i;
108 }
109
110 for(int i = 0; i < 50; ++i){
111 IntType move_me(i);
112 aux_vect3[i] = boost::move(move_me);
113 }
114
115 MyShmSet *shmset3 =
116 segment.template construct<MyShmSet>("MyShmSet3")
117 ( ordered_unique_range
118 , ::boost::make_move_iterator(&aux_vect[0])
119 , ::boost::make_move_iterator(aux_vect + 50)
120 , std::less<IntType>(), segment.get_segment_manager());
121
122 MyStdSet *stdset3 = new MyStdSet(aux_vect2, aux_vect2 + 50);
123
124 MyShmMultiSet *shmmultiset3 =
125 segment.template construct<MyShmMultiSet>("MyShmMultiSet3")
126 ( ordered_range
127 , ::boost::make_move_iterator(&aux_vect3[0])
128 , ::boost::make_move_iterator(aux_vect3 + 50)
129 , std::less<IntType>(), segment.get_segment_manager());
130
131 MyStdMultiSet *stdmultiset3 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
132
133 if(!CheckEqualContainers(shmset3, stdset3)){
134 std::cout << "Error in construct<MyShmSet>(MyShmSet3)" << std::endl;
135 return 1;
136 }
137 if(!CheckEqualContainers(shmmultiset3, stdmultiset3)){
138 std::cout << "Error in construct<MyShmMultiSet>(MyShmMultiSet3)" << std::endl;
139 return 1;
140 }
141
142 segment.destroy_ptr(shmset2);
143 segment.destroy_ptr(shmmultiset2);
144 delete stdset2;
145 delete stdmultiset2;
146
147 segment.destroy_ptr(shmset3);
148 segment.destroy_ptr(shmmultiset3);
149 delete stdset3;
150 delete stdmultiset3;
151 }
152
153 if(!CheckEqualContainers(shmset, stdset)){
154 std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
155 return 1;
156 }
157
158 for(int i = 0; i < max/2; ++i){
159 IntType move_me(i);
160 shmset->insert(boost::move(move_me));
161 stdset->insert(i);
162 IntType move_me2(i);
163 shmmultiset->insert(boost::move(move_me2));
164 stdmultiset->insert(i);
165
166 if(!CheckEqualContainers(shmset, stdset)){
167 std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
168 return 1;
169 }
170 //
171 shmset->insert(IntType(i));
172 stdset->insert(i);
173 shmmultiset->insert(IntType(i));
174 stdmultiset->insert(i);
175
176 if(!CheckEqualContainers(shmset, stdset)){
177 std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
178 return 1;
179 }
180
181 }
182
183 if(!CheckEqualContainers(shmset, stdset)){
184 std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
185 return 1;
186 }
187
188 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
189 std::cout << "Error in shmmultiset->insert(boost::move(move_me)" << std::endl;
190 return 1;
191 }
192
193 typename MyShmSet::iterator it;
194 typename MyShmSet::const_iterator cit = it;
195 (void)cit;
196
197 shmset->erase(shmset->begin()++);
198 stdset->erase(stdset->begin()++);
199 shmmultiset->erase(shmmultiset->begin()++);
200 stdmultiset->erase(stdmultiset->begin()++);
201 if(!CheckEqualContainers(shmset, stdset)){
202 std::cout << "Error in shmset->erase(shmset->begin()++)" << std::endl;
203 return 1;
204 }
205 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
206 std::cout << "Error in shmmultiset->erase(shmmultiset->begin()++)" << std::endl;
207 return 1;
208 }
209
210 shmset->erase(shmset->begin());
211 stdset->erase(stdset->begin());
212 shmmultiset->erase(shmmultiset->begin());
213 stdmultiset->erase(stdmultiset->begin());
214 if(!CheckEqualContainers(shmset, stdset)){
215 std::cout << "Error in shmset->erase(shmset->begin())" << std::endl;
216 return 1;
217 }
218 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
219 std::cout << "Error in shmmultiset->erase(shmmultiset->begin())" << std::endl;
220 return 1;
221 }
222
223 //Swapping test
224 std::less<IntType> lessfunc;
225 MyShmSet tmpshmeset2 (lessfunc, segment.get_segment_manager());
226 MyStdSet tmpstdset2;
227 MyShmMultiSet tmpshmemultiset2(lessfunc, segment.get_segment_manager());
228 MyStdMultiSet tmpstdmultiset2;
229 shmset->swap(tmpshmeset2);
230 stdset->swap(tmpstdset2);
231 shmmultiset->swap(tmpshmemultiset2);
232 stdmultiset->swap(tmpstdmultiset2);
233 shmset->swap(tmpshmeset2);
234 stdset->swap(tmpstdset2);
235 shmmultiset->swap(tmpshmemultiset2);
236 stdmultiset->swap(tmpstdmultiset2);
237 if(!CheckEqualContainers(shmset, stdset)){
238 std::cout << "Error in shmset->swap(tmpshmeset2)" << std::endl;
239 return 1;
240 }
241 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
242 std::cout << "Error in shmmultiset->swap(tmpshmemultiset2)" << std::endl;
243 return 1;
244 }
245
246 //Insertion from other container
247 //Initialize values
248 {
249 IntType aux_vect[50];
250 for(int i = 0; i < 50; ++i){
251 IntType move_me(-1);
252 aux_vect[i] = boost::move(move_me);
253 }
254 int aux_vect2[50];
255 for(int i = 0; i < 50; ++i){
256 aux_vect2[i] = -1;
257 }
258 IntType aux_vect3[50];
259 for(int i = 0; i < 50; ++i){
260 IntType move_me(-1);
261 aux_vect3[i] = boost::move(move_me);
262 }
263
264 shmset->insert(::boost::make_move_iterator(&aux_vect[0]), ::boost::make_move_iterator(aux_vect + 50));
265 stdset->insert(aux_vect2, aux_vect2 + 50);
266 shmmultiset->insert(::boost::make_move_iterator(&aux_vect3[0]), ::boost::make_move_iterator(aux_vect3 + 50));
267 stdmultiset->insert(aux_vect2, aux_vect2 + 50);
268 if(!CheckEqualContainers(shmset, stdset)){
269 std::cout << "Error in shmset->insert(::boost::make_move_iterator(&aux_vect[0])..." << std::endl;
270 return 1;
271 }
272 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
273 std::cout << "Error in shmmultiset->insert(::boost::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
274 return 1;
275 }
276
277 for(int i = 0, j = static_cast<int>(shmset->size()); i < j; ++i){
278 IntType erase_me(i);
279 shmset->erase(erase_me);
280 stdset->erase(i);
281 shmmultiset->erase(erase_me);
282 stdmultiset->erase(i);
283 if(!CheckEqualContainers(shmset, stdset)){
284 std::cout << "Error in shmset->erase(erase_me)" << shmset->size() << " " << stdset->size() << std::endl;
285 return 1;
286 }
287 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
288 std::cout << "Error in shmmultiset->erase(erase_me)" << std::endl;
289 return 1;
290 }
291 }
292 }
293 {
294 IntType aux_vect[50];
295 for(int i = 0; i < 50; ++i){
296 IntType move_me(-1);
297 aux_vect[i] = boost::move(move_me);
298 }
299 int aux_vect2[50];
300 for(int i = 0; i < 50; ++i){
301 aux_vect2[i] = -1;
302 }
303 IntType aux_vect3[50];
304 for(int i = 0; i < 50; ++i){
305 IntType move_me(-1);
306 aux_vect3[i] = boost::move(move_me);
307 }
308
309 IntType aux_vect4[50];
310 for(int i = 0; i < 50; ++i){
311 IntType move_me(-1);
312 aux_vect4[i] = boost::move(move_me);
313 }
314
315 IntType aux_vect5[50];
316 for(int i = 0; i < 50; ++i){
317 IntType move_me(-1);
318 aux_vect5[i] = boost::move(move_me);
319 }
320
321 shmset->insert(::boost::make_move_iterator(&aux_vect[0]), ::boost::make_move_iterator(aux_vect + 50));
322 shmset->insert(::boost::make_move_iterator(&aux_vect3[0]), ::boost::make_move_iterator(aux_vect3 + 50));
323 stdset->insert(aux_vect2, aux_vect2 + 50);
324 stdset->insert(aux_vect2, aux_vect2 + 50);
325 shmmultiset->insert(::boost::make_move_iterator(&aux_vect4[0]), ::boost::make_move_iterator(aux_vect4 + 50));
326 shmmultiset->insert(::boost::make_move_iterator(&aux_vect5[0]), ::boost::make_move_iterator(aux_vect5 + 50));
327 stdmultiset->insert(aux_vect2, aux_vect2 + 50);
328 stdmultiset->insert(aux_vect2, aux_vect2 + 50);
329 if(!CheckEqualContainers(shmset, stdset)){
330 std::cout << "Error in shmset->insert(::boost::make_move_iterator(&aux_vect3[0])..." << std::endl;
331 return 1;
332 }
333 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
334 std::cout << "Error in shmmultiset->insert(::boost::make_move_iterator(&aux_vect5[0])..." << std::endl;
335 return 1;
336 }
337
338 shmset->erase(*shmset->begin());
339 stdset->erase(*stdset->begin());
340 shmmultiset->erase(*shmmultiset->begin());
341 stdmultiset->erase(*stdmultiset->begin());
342 if(!CheckEqualContainers(shmset, stdset)){
343 std::cout << "Error in shmset->erase(*shmset->begin())" << std::endl;
344 return 1;
345 }
346 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
347 std::cout << "Error in shmmultiset->erase(*shmmultiset->begin())" << std::endl;
348 return 1;
349 }
350 }
351
352 for(int i = 0; i < max/2; ++i){
353 IntType move_me(i);
354 shmset->insert(shmset->begin(), boost::move(move_me));
355 stdset->insert(stdset->begin(), i);
356 IntType move_me2(i);
357 shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2));
358 stdmultiset->insert(stdmultiset->begin(), i);
359 //
360 shmset->insert(shmset->begin(), IntType(i));
361 stdset->insert(stdset->begin(), i);
362 shmmultiset->insert(shmmultiset->begin(), IntType(i));
363 stdmultiset->insert(stdmultiset->begin(), i);
364 }
365
366 if(!CheckEqualContainers(shmset, stdset)){
367 std::cout << "Error in shmset->insert(boost::move(move_me)) try 2" << std::endl;
368 return 1;
369 }
370 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
371 std::cout << "Error in shmmultiset->insert(boost::move(move_me2)) try 2" << std::endl;
372 return 1;
373 }
374
375 for(int i = 0; i < max; ++i){
376 {
377 IntType move_me(i);
378 shmset->insert(shmset->begin(), boost::move(move_me));
379 stdset->insert(stdset->begin(), i);
380 //PrintContainers(shmset, stdset);
381 IntType move_me2(i);
382 shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2));
383 stdmultiset->insert(stdmultiset->begin(), i);
384 //PrintContainers(shmmultiset, stdmultiset);
385 if(!CheckEqualContainers(shmset, stdset)){
386 std::cout << "Error in shmset->insert(shmset->begin(), boost::move(move_me))" << std::endl;
387 return 1;
388 }
389 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
390 std::cout << "Error in shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2))" << std::endl;
391 return 1;
392 }
393
394 IntType move_me3(i);
395 shmset->insert(shmset->end(), boost::move(move_me3));
396 stdset->insert(stdset->end(), i);
397 IntType move_me4(i);
398 shmmultiset->insert(shmmultiset->end(), boost::move(move_me4));
399 stdmultiset->insert(stdmultiset->end(), i);
400 if(!CheckEqualContainers(shmset, stdset)){
401 std::cout << "Error in shmset->insert(shmset->end(), boost::move(move_me3))" << std::endl;
402 return 1;
403 }
404 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
405 std::cout << "Error in shmmultiset->insert(shmmultiset->end(), boost::move(move_me4))" << std::endl;
406 return 1;
407 }
408 }
409 {
410 IntType move_me(i);
411 shmset->insert(shmset->upper_bound(move_me), boost::move(move_me));
412 stdset->insert(stdset->upper_bound(i), i);
413 //PrintContainers(shmset, stdset);
414 IntType move_me2(i);
415 shmmultiset->insert(shmmultiset->upper_bound(move_me2), boost::move(move_me2));
416 stdmultiset->insert(stdmultiset->upper_bound(i), i);
417 //PrintContainers(shmmultiset, stdmultiset);
418 if(!CheckEqualContainers(shmset, stdset)){
419 std::cout << "Error in shmset->insert(shmset->upper_bound(move_me), boost::move(move_me))" << std::endl;
420 return 1;
421 }
422 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
423 std::cout << "Error in shmmultiset->insert(shmmultiset->upper_bound(move_me2), boost::move(move_me2))" << std::endl;
424 return 1;
425 }
426 }
427 {
428 IntType move_me(i);
429 IntType move_me2(i);
430 shmset->insert(shmset->lower_bound(move_me), boost::move(move_me2));
431 stdset->insert(stdset->lower_bound(i), i);
432 //PrintContainers(shmset, stdset);
433 move_me2 = i;
434 shmmultiset->insert(shmmultiset->lower_bound(move_me2), boost::move(move_me2));
435 stdmultiset->insert(stdmultiset->lower_bound(i), i);
436 //PrintContainers(shmmultiset, stdmultiset);
437 if(!CheckEqualContainers(shmset, stdset)){
438 std::cout << "Error in shmset->insert(shmset->lower_bound(move_me), boost::move(move_me2))" << std::endl;
439 return 1;
440 }
441 if(!CheckEqualContainers(shmmultiset, stdmultiset)){
442 std::cout << "Error in shmmultiset->insert(shmmultiset->lower_bound(move_me2), boost::move(move_me2))" << std::endl;
443 return 1;
444 }
445 }
446 }
447
448 //Compare count with std containers
449 for(int i = 0; i < max; ++i){
450 IntType count_me(i);
451 if(shmset->count(count_me) != stdset->count(i)){
452 return -1;
453 }
454 if(shmmultiset->count(count_me) != stdmultiset->count(i)){
455 return -1;
456 }
457 }
458
459 //Now do count exercise
460 shmset->erase(shmset->begin(), shmset->end());
461 shmmultiset->erase(shmmultiset->begin(), shmmultiset->end());
462 shmset->clear();
463 shmmultiset->clear();
464
465 typedef typename MyShmMultiSet::size_type set_size_type;
466
467 for(int j = 0; j < 3; ++j)
468 for(int i = 0; i < 100; ++i){
469 IntType move_me(i);
470 shmset->insert(boost::move(move_me));
471 IntType move_me2(i);
472 shmmultiset->insert(boost::move(move_me2));
473 IntType count_me(i);
474 if(shmset->count(count_me) != set_size_type(1u)){
475 std::cout << "Error in shmset->count(count_me)" << std::endl;
476 return 1;
477 }
478 if(shmmultiset->count(count_me) != set_size_type(j)+1u){
479 std::cout << "Error in shmmultiset->count(count_me)" << std::endl;
480 return 1;
481 }
482 }
483
484 segment.template destroy<MyShmSet>("MyShmSet");
485 delete stdset;
486 segment.destroy_ptr(shmmultiset);
487 delete stdmultiset;
488 segment.shrink_to_fit_indexes();
489
490 if(!segment.all_memory_deallocated()){
491 std::cout << "Error in segment.all_memory_deallocated()" << std::endl;
492 return 1;
493 }
494 }
495 BOOST_CATCH(...){
496 shared_memory_object::remove(filename: shMemName);
497 BOOST_RETHROW
498 } BOOST_CATCH_END
499 shared_memory_object::remove(filename: shMemName);
500 return 0;
501}
502
503template<class ManagedSharedMemory
504 ,class MyShmSet
505 ,class MyStdSet
506 ,class MyShmMultiSet
507 ,class MyStdMultiSet>
508int set_test_copyable ()
509{
510 typedef typename MyShmSet::value_type IntType;
511 const int Memsize = 128u * 1024u;
512 const char *const shMemName = test::get_process_id_name();
513 const int max = 100;
514
515 BOOST_TRY{
516 //Create shared memory
517 shared_memory_object::remove(filename: shMemName);
518 ManagedSharedMemory segment(create_only, shMemName, Memsize);
519
520 segment.reserve_named_objects(10);
521
522 //Shared memory allocator must be always be initialized
523 //since it has no default constructor
524 MyShmSet *shmset =
525 segment.template construct<MyShmSet>("MyShmSet")
526 (std::less<IntType>(), segment.get_segment_manager());
527
528 MyStdSet *stdset = new MyStdSet;
529
530 MyShmMultiSet *shmmultiset =
531 segment.template construct<MyShmMultiSet>("MyShmMultiSet")
532 (std::less<IntType>(), segment.get_segment_manager());
533
534 MyStdMultiSet *stdmultiset = new MyStdMultiSet;
535
536 for(int i = 0; i < max; ++i){
537 IntType move_me(i);
538 shmset->insert(boost::move(move_me));
539 stdset->insert(i);
540 IntType move_me2(i);
541 shmmultiset->insert(boost::move(move_me2));
542 stdmultiset->insert(i);
543 }
544 if(!CheckEqualContainers(shmset, stdset)) return 1;
545 if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
546
547 {
548 //Now, test copy constructor
549 MyShmSet shmsetcopy(*shmset);
550 MyStdSet stdsetcopy(*stdset);
551
552 if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
553 return 1;
554
555 MyShmMultiSet shmmsetcopy(*shmmultiset);
556 MyStdMultiSet stdmsetcopy(*stdmultiset);
557
558 if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
559 return 1;
560
561 //And now assignment
562 shmsetcopy = *shmset;
563 stdsetcopy = *stdset;
564
565 if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
566 return 1;
567
568 shmmsetcopy = *shmmultiset;
569 stdmsetcopy = *stdmultiset;
570
571 if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
572 return 1;
573 }
574 segment.destroy_ptr(shmset);
575 segment.destroy_ptr(shmmultiset);
576 delete stdset;
577 delete stdmultiset;
578 segment.shrink_to_fit_indexes();
579 if(!segment.all_memory_deallocated())
580 return 1;
581 }
582 BOOST_CATCH(...){
583 shared_memory_object::remove(filename: shMemName);
584 BOOST_RETHROW
585 } BOOST_CATCH_END
586 shared_memory_object::remove(filename: shMemName);
587 return 0;
588}
589
590} //namespace test{
591} //namespace interprocess{
592} //namespace boost{
593
594#include <boost/interprocess/detail/config_end.hpp>
595
596#endif
597

source code of boost/libs/interprocess/test/set_test.hpp