1 ////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 ////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_TEST_MAP_TEST_HEADER
12 #define BOOST_INTERPROCESS_TEST_MAP_TEST_HEADER
14 #include <boost/interprocess/detail/config_begin.hpp>
15 #include "check_equal_containers.hpp"
19 #include <boost/interprocess/containers/pair.hpp>
20 // interprocess/detail
21 #include <boost/interprocess/detail/utilities.hpp>
23 #include <boost/intrusive/detail/minimal_pair_header.hpp>
24 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>
28 #include "print_container.hpp"
29 #include "get_process_id_name.hpp"
31 template<class T1, class T2, class T3, class T4>
32 bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
34 return p1.first == p2.first && p1.second == p2.second;
38 namespace interprocess{
41 template<class ManagedSharedMemory
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();
56 //Create shared memory
57 shared_memory_object::remove(shMemName);
58 ManagedSharedMemory segment(create_only, shMemName, memsize);
60 segment.reserve_named_objects(100);
62 //Shared memory allocator must be always be initialized
63 //since it has no default constructor
65 segment.template construct<MyShmMap>("MyShmMap")
66 (std::less<IntType>(), segment.get_segment_manager());
68 MyStdMap *stdmap = new MyStdMap;
70 MyShmMultiMap *shmmultimap =
71 segment.template construct<MyShmMultiMap>("MyShmMultiMap")
72 (std::less<IntType>(), segment.get_segment_manager());
74 MyStdMultiMap *stdmultimap = new MyStdMultiMap;
76 //Test construction from a range
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){
83 new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
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));
94 IntPairType aux_vect3[50];
95 for(int i = 0; i < 50; ++i){
98 new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
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());
107 MyStdMap *stdmap2 = new MyStdMap(aux_vect2, aux_vect2 + 50);
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());
115 MyStdMultiMap *stdmultimap2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
116 if(!CheckEqualContainers(shmmap2, stdmap2)) return 1;
117 if(!CheckEqualContainers(shmmultimap2, stdmultimap2)) return 1;
119 //ordered range insertion
120 //This is really nasty, but we have no other simple choice
121 for(int i = 0; i < 50; ++i){
124 new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
127 for(int i = 0; i < 50; ++i){
128 new(&aux_vect2[i])StdValueType(StdKeyType(i), StdMappedType(i));
131 for(int i = 0; i < 50; ++i){
134 new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
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());
144 MyStdMap *stdmap3 = new MyStdMap(aux_vect2, aux_vect2 + 50);
146 MyShmMultiMap *shmmultimap3 =
147 segment.template construct<MyShmMultiMap>("MyShmMultiMap3")
149 , ::boost::make_move_iterator(&aux_vect3[0])
150 , ::boost::make_move_iterator(aux_vect3 + 50)
151 , std::less<IntType>(), segment.get_segment_manager());
153 MyStdMultiMap *stdmultimap3 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
155 if(!CheckEqualContainers(shmmap3, stdmap3)){
156 std::cout << "Error in construct<MyShmMap>(MyShmMap3)" << std::endl;
159 if(!CheckEqualContainers(shmmultimap3, stdmultimap3)){
160 std::cout << "Error in construct<MyShmMultiMap>(MyShmMultiMap3)" << std::endl;
164 segment.destroy_ptr(shmmap2);
165 segment.destroy_ptr(shmmultimap2);
168 segment.destroy_ptr(shmmap3);
169 segment.destroy_ptr(shmmultimap3);
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){
179 new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
181 IntPairType aux_vect3[max];
182 for(int i = 0; i < max; ++i){
185 new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
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));
195 if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
196 if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
198 typename MyShmMap::iterator it;
199 typename MyShmMap::const_iterator cit = it;
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;
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;
217 std::less<IntType> lessfunc;
218 MyShmMap tmpshmemap2 (lessfunc, segment.get_segment_manager());
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;
233 //Insertion from other container
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){
241 new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
243 IntPairType aux_vect3[50];
244 for(int i = 0; i < 50; ++i){
247 new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
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);
257 if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
258 if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
260 for(int i = 0, j = static_cast<int>(shmmap->size()); i < j; ++i){
261 shmmap->erase(IntType(i));
263 shmmultimap->erase(IntType(i));
264 stdmultimap->erase(i);
266 if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
267 if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
270 IntPairType aux_vect[50];
271 for(int i = 0; i < 50; ++i){
274 new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
277 IntPairType aux_vect3[50];
278 for(int i = 0; i < 50; ++i){
281 new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
284 IntPairType aux_vect4[50];
285 for(int i = 0; i < 50; ++i){
288 new(&aux_vect4[i])IntPairType(boost::move(i1), boost::move(i2));
291 IntPairType aux_vect5[50];
292 for(int i = 0; i < 50; ++i){
295 new(&aux_vect5[i])IntPairType(boost::move(i1), boost::move(i2));
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));
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);
310 if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
311 if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
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;
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){
327 new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
329 IntPairType aux_vect3[max];
330 for(int i = 0; i < max; ++i){
333 new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
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));
343 if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
344 if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
346 for(int i = 0; i < max; ++i){
351 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
353 shmmap->insert(shmmap->begin(), boost::move(intpair));
354 stdmap->insert(stdmap->begin(), StdPairType(i, i));
355 //PrintContainers(shmmap, stdmap);
359 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
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))
366 if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
371 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
373 shmmap->insert(shmmap->end(), boost::move(intpair));
374 stdmap->insert(stdmap->end(), StdPairType(i, i));
378 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
380 shmmultimap->insert(shmmultimap->end(), boost::move(intpair));
381 stdmultimap->insert(stdmultimap->end(), StdPairType(i, i));
382 if(!CheckEqualPairContainers(shmmap, stdmap))
384 if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
389 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
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);
397 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
401 shmmultimap->insert(shmmultimap->lower_bound(boost::move(i1)), boost::move(intpair));
402 stdmultimap->insert(stdmultimap->lower_bound(i), StdPairType(i, i));
405 //PrintContainers(shmmultimap, stdmultimap);
406 if(!CheckEqualPairContainers(shmmap, stdmap))
408 if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
413 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
417 shmmap->insert(shmmap->upper_bound(boost::move(i1)), boost::move(intpair));
418 stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i));
420 //PrintContainers(shmmap, stdmap);
424 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
428 shmmultimap->insert(shmmultimap->upper_bound(boost::move(i1)), boost::move(intpair));
429 stdmultimap->insert(stdmultimap->upper_bound(i), StdPairType(i, i));
431 //PrintContainers(shmmultimap, stdmultimap);
432 if(!CheckEqualPairContainers(shmmap, stdmap))
434 if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
438 //Compare count with std containers
439 for(int i = 0; i < max; ++i){
440 if(shmmap->count(IntType(i)) != stdmap->count(i)){
444 if(shmmultimap->count(IntType(i)) != stdmultimap->count(i)){
449 //Now do count exercise
450 shmmap->erase(shmmap->begin(), shmmap->end());
451 shmmultimap->erase(shmmultimap->begin(), shmmultimap->end());
453 shmmultimap->clear();
455 for(int j = 0; j < 3; ++j)
456 for(int i = 0; i < 100; ++i){
459 IntType i1(i), i2(i);
460 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
462 shmmap->insert(boost::move(intpair));
464 IntType i1(i), i2(i);
465 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
467 shmmultimap->insert(boost::move(intpair));
468 if(shmmap->count(IntType(i)) != typename MyShmMultiMap::size_type(1))
470 if(shmmultimap->count(IntType(i)) != typename MyShmMultiMap::size_type(j+1))
475 segment.template destroy<MyShmMap>("MyShmMap");
477 segment.destroy_ptr(shmmultimap);
480 segment.shrink_to_fit_indexes();
482 if(!segment.all_memory_deallocated())
486 shared_memory_object::remove(shMemName);
489 shared_memory_object::remove(shMemName);
493 template<class ManagedSharedMemory
497 ,class MyStdMultiMap>
498 int map_test_copyable ()
500 typedef typename MyShmMap::key_type IntType;
501 typedef boost::interprocess::pair<IntType, IntType> IntPairType;
502 typedef typename MyStdMap::value_type StdPairType;
504 const int memsize = 65536;
505 const char *const shMemName = test::get_process_id_name();
509 //Create shared memory
510 shared_memory_object::remove(shMemName);
511 ManagedSharedMemory segment(create_only, shMemName, memsize);
513 segment.reserve_named_objects(100);
515 //Shared memory allocator must be always be initialized
516 //since it has no default constructor
518 segment.template construct<MyShmMap>("MyShmMap")
519 (std::less<IntType>(), segment.get_segment_manager());
521 MyStdMap *stdmap = new MyStdMap;
523 MyShmMultiMap *shmmultimap =
524 segment.template construct<MyShmMultiMap>("MyShmMultiMap")
525 (std::less<IntType>(), segment.get_segment_manager());
527 MyStdMultiMap *stdmultimap = new MyStdMultiMap;
530 for(i = 0; i < max; ++i){
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));
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));
544 if(!CheckEqualContainers(shmmap, stdmap)) return 1;
545 if(!CheckEqualContainers(shmmultimap, stdmultimap)) return 1;
548 //Now, test copy constructor
549 MyShmMap shmmapcopy(*shmmap);
550 MyStdMap stdmapcopy(*stdmap);
551 MyShmMultiMap shmmmapcopy(*shmmultimap);
552 MyStdMultiMap stdmmapcopy(*stdmultimap);
554 if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
556 if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
560 shmmapcopy = *shmmap;
561 stdmapcopy = *stdmap;
562 shmmmapcopy = *shmmultimap;
563 stdmmapcopy = *stdmultimap;
565 if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
567 if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
571 segment.destroy_ptr(shmmap);
572 segment.destroy_ptr(shmmultimap);
574 segment.shrink_to_fit_indexes();
576 if(!segment.all_memory_deallocated())
580 shared_memory_object::remove(shMemName);
583 shared_memory_object::remove(shMemName);
588 } //namespace interprocess{
591 #include <boost/interprocess/detail/config_end.hpp>
593 #endif //#ifndef BOOST_INTERPROCESS_TEST_MAP_TEST_HEADER