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
31template<class T1, class T2, class T3, class T4>
32bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
33{
34 return p1.first == p2.first && p1.second == p2.second;
35}
36
37namespace boost{
38namespace interprocess{
39namespace test{
40
41template<class ManagedSharedMemory
42 ,class MyShmMap
43 ,class MyStdMap
44 ,class MyShmMultiMap
45 ,class MyStdMultiMap>
46int 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 = 128u * 1024u;
52 const char *const shMemName = test::get_process_id_name();
53 const int max = 100;
54
55 BOOST_TRY{
56 //Create shared memory
57 shared_memory_object::remove(filename: shMemName);
58 ManagedSharedMemory segment(create_only, shMemName, Memsize);
59
60 segment.reserve_named_objects(10);
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[std::size_t(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[std::size_t(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[std::size_t(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[std::size_t(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 typedef typename MyShmMultiMap::size_type map_size_type;
456
457 for(int j = 0; j < 3; ++j)
458 for(int i = 0; i < 100; ++i){
459 IntPairType intpair;
460 {
461 IntType i1(i), i2(i);
462 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
463 }
464 shmmap->insert(boost::move(intpair));
465 {
466 IntType i1(i), i2(i);
467 new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
468 }
469 shmmultimap->insert(boost::move(intpair));
470 if(shmmap->count(IntType(i)) != map_size_type(1u))
471 return 1;
472 if(shmmultimap->count(IntType(i)) != map_size_type(j)+1u)
473 return 1;
474 }
475 }
476
477 segment.template destroy<MyShmMap>("MyShmMap");
478 delete stdmap;
479 segment.destroy_ptr(shmmultimap);
480 delete stdmultimap;
481
482 segment.shrink_to_fit_indexes();
483
484 if(!segment.all_memory_deallocated())
485 return 1;
486 }
487 BOOST_CATCH(...){
488 shared_memory_object::remove(filename: shMemName);
489 BOOST_RETHROW
490 } BOOST_CATCH_END
491 shared_memory_object::remove(filename: shMemName);
492 return 0;
493}
494
495template<class ManagedSharedMemory
496 ,class MyShmMap
497 ,class MyStdMap
498 ,class MyShmMultiMap
499 ,class MyStdMultiMap>
500int map_test_copyable ()
501{
502 typedef typename MyShmMap::key_type IntType;
503 typedef boost::interprocess::pair<IntType, IntType> IntPairType;
504 typedef typename MyStdMap::value_type StdPairType;
505
506 const int Memsize = 128u * 1024u;
507 const char *const shMemName = test::get_process_id_name();
508 const int max = 100;
509
510 BOOST_TRY{
511 //Create shared memory
512 shared_memory_object::remove(filename: shMemName);
513 ManagedSharedMemory segment(create_only, shMemName, Memsize);
514
515 segment.reserve_named_objects(10);
516
517 //Shared memory allocator must be always be initialized
518 //since it has no default constructor
519 MyShmMap *shmmap =
520 segment.template construct<MyShmMap>("MyShmMap")
521 (std::less<IntType>(), segment.get_segment_manager());
522
523 MyStdMap *stdmap = new MyStdMap;
524
525 MyShmMultiMap *shmmultimap =
526 segment.template construct<MyShmMultiMap>("MyShmMultiMap")
527 (std::less<IntType>(), segment.get_segment_manager());
528
529 MyStdMultiMap *stdmultimap = new MyStdMultiMap;
530
531 int i;
532 for(i = 0; i < max; ++i){
533 {
534 IntType i1(i), i2(i);
535 IntPairType intpair1(boost::move(i1), boost::move(i2));
536 shmmap->insert(boost::move(intpair1));
537 stdmap->insert(StdPairType(i, i));
538 }
539 {
540 IntType i1(i), i2(i);
541 IntPairType intpair2(boost::move(i1), boost::move(i2));
542 shmmultimap->insert(boost::move(intpair2));
543 stdmultimap->insert(StdPairType(i, i));
544 }
545 }
546 if(!CheckEqualContainers(shmmap, stdmap)) return 1;
547 if(!CheckEqualContainers(shmmultimap, stdmultimap)) return 1;
548
549 {
550 //Now, test copy constructor
551 MyShmMap shmmapcopy(*shmmap);
552 MyStdMap stdmapcopy(*stdmap);
553 MyShmMultiMap shmmmapcopy(*shmmultimap);
554 MyStdMultiMap stdmmapcopy(*stdmultimap);
555
556 if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
557 return 1;
558 if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
559 return 1;
560
561 //And now assignment
562 shmmapcopy = *shmmap;
563 stdmapcopy = *stdmap;
564 shmmmapcopy = *shmmultimap;
565 stdmmapcopy = *stdmultimap;
566
567 if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
568 return 1;
569 if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
570 return 1;
571 delete stdmap;
572 delete stdmultimap;
573 segment.destroy_ptr(shmmap);
574 segment.destroy_ptr(shmmultimap);
575 }
576 segment.shrink_to_fit_indexes();
577
578 if(!segment.all_memory_deallocated())
579 return 1;
580 }
581 BOOST_CATCH(...){
582 shared_memory_object::remove(filename: shMemName);
583 BOOST_RETHROW
584 } BOOST_CATCH_END
585 shared_memory_object::remove(filename: shMemName);
586 return 0;
587}
588
589} //namespace test{
590} //namespace interprocess{
591} //namespace boost{
592
593#include <boost/interprocess/detail/config_end.hpp>
594
595#endif //#ifndef BOOST_INTERPROCESS_TEST_MAP_TEST_HEADER
596

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