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