• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 namespace boost{
23 namespace interprocess{
24 namespace test{
25 
26 template<class ManagedSharedMemory
27         ,class MyShmSet
28         ,class MyStdSet
29         ,class MyShmMultiSet
30         ,class MyStdMultiSet>
set_test()31 int set_test ()
32 {
33    typedef typename MyShmSet::value_type IntType;
34    const int memsize = 65536;
35    const char *const shMemName = test::get_process_id_name();
36    const int max = 100;
37 
38    try{
39       //Create shared memory
40       shared_memory_object::remove(shMemName);
41       ManagedSharedMemory segment(create_only, shMemName, memsize);
42 
43       segment.reserve_named_objects(100);
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       for(int j = 0; j < 3; ++j)
466       for(int i = 0; i < 100; ++i){
467          IntType move_me(i);
468          shmset->insert(boost::move(move_me));
469          IntType move_me2(i);
470          shmmultiset->insert(boost::move(move_me2));
471          IntType count_me(i);
472          if(shmset->count(count_me) != typename MyShmMultiSet::size_type(1)){
473             std::cout << "Error in shmset->count(count_me)" << std::endl;
474             return 1;
475          }
476          if(shmmultiset->count(count_me) != typename MyShmMultiSet::size_type(j+1)){
477             std::cout << "Error in shmmultiset->count(count_me)" << std::endl;
478             return 1;
479          }
480       }
481 
482       segment.template destroy<MyShmSet>("MyShmSet");
483       delete stdset;
484       segment.destroy_ptr(shmmultiset);
485       delete stdmultiset;
486       segment.shrink_to_fit_indexes();
487 
488       if(!segment.all_memory_deallocated()){
489          std::cout << "Error in segment.all_memory_deallocated()" << std::endl;
490          return 1;
491       }
492    }
493    catch(...){
494       shared_memory_object::remove(shMemName);
495       throw;
496    }
497    shared_memory_object::remove(shMemName);
498    return 0;
499 }
500 
501 template<class ManagedSharedMemory
502         ,class MyShmSet
503         ,class MyStdSet
504         ,class MyShmMultiSet
505         ,class MyStdMultiSet>
set_test_copyable()506 int set_test_copyable ()
507 {
508    typedef typename MyShmSet::value_type IntType;
509    const int memsize = 65536;
510    const char *const shMemName = test::get_process_id_name();
511    const int max = 100;
512 
513    try{
514       //Create shared memory
515       shared_memory_object::remove(shMemName);
516       ManagedSharedMemory segment(create_only, shMemName, memsize);
517 
518       segment.reserve_named_objects(100);
519 
520       //Shared memory allocator must be always be initialized
521       //since it has no default constructor
522       MyShmSet *shmset =
523          segment.template construct<MyShmSet>("MyShmSet")
524             (std::less<IntType>(), segment.get_segment_manager());
525 
526       MyStdSet *stdset = new MyStdSet;
527 
528       MyShmMultiSet *shmmultiset =
529          segment.template construct<MyShmMultiSet>("MyShmMultiSet")
530             (std::less<IntType>(), segment.get_segment_manager());
531 
532       MyStdMultiSet *stdmultiset = new MyStdMultiSet;
533 
534       for(int i = 0; i < max; ++i){
535          IntType move_me(i);
536          shmset->insert(boost::move(move_me));
537          stdset->insert(i);
538          IntType move_me2(i);
539          shmmultiset->insert(boost::move(move_me2));
540          stdmultiset->insert(i);
541       }
542       if(!CheckEqualContainers(shmset, stdset)) return 1;
543       if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
544 
545       {
546          //Now, test copy constructor
547          MyShmSet shmsetcopy(*shmset);
548          MyStdSet stdsetcopy(*stdset);
549 
550          if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
551             return 1;
552 
553          MyShmMultiSet shmmsetcopy(*shmmultiset);
554          MyStdMultiSet stdmsetcopy(*stdmultiset);
555 
556          if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
557             return 1;
558 
559          //And now assignment
560          shmsetcopy  = *shmset;
561          stdsetcopy  = *stdset;
562 
563          if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
564             return 1;
565 
566          shmmsetcopy = *shmmultiset;
567          stdmsetcopy = *stdmultiset;
568 
569          if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
570             return 1;
571       }
572       segment.destroy_ptr(shmset);
573       segment.destroy_ptr(shmmultiset);
574       delete stdset;
575       delete stdmultiset;
576       segment.shrink_to_fit_indexes();
577       if(!segment.all_memory_deallocated())
578          return 1;
579    }
580    catch(...){
581       shared_memory_object::remove(shMemName);
582       throw;
583    }
584    shared_memory_object::remove(shMemName);
585    return 0;
586 }
587 
588 }  //namespace test{
589 }  //namespace interprocess{
590 }  //namespace boost{
591 
592 #include <boost/interprocess/detail/config_end.hpp>
593 
594 #endif
595