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