1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2004-2013. 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/container for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10#include <boost/container/map.hpp>
11#include <boost/container/adaptive_pool.hpp>
12
13#include <map>
14
15#include "print_container.hpp"
16#include "movable_int.hpp"
17#include "dummy_test_allocator.hpp"
18#include "map_test.hpp"
19#include "propagate_allocator_test.hpp"
20#include "emplace_test.hpp"
21#include "../../intrusive/test/iterator_test.hpp"
22
23using namespace boost::container;
24
25typedef std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> pair_t;
26
27class recursive_map
28{
29 public:
30 recursive_map()
31 {}
32
33 recursive_map(const recursive_map &x)
34 : map_(x.map_)
35 {}
36
37 recursive_map & operator=(const recursive_map &x)
38 { id_ = x.id_; map_ = x.map_; return *this; }
39
40 int id_;
41 map<recursive_map, recursive_map> map_;
42 map<recursive_map, recursive_map>::iterator it_;
43 map<recursive_map, recursive_map>::const_iterator cit_;
44 map<recursive_map, recursive_map>::reverse_iterator rit_;
45 map<recursive_map, recursive_map>::const_reverse_iterator crit_;
46
47 friend bool operator< (const recursive_map &a, const recursive_map &b)
48 { return a.id_ < b.id_; }
49};
50
51class recursive_multimap
52{
53 public:
54 recursive_multimap()
55 {}
56
57 recursive_multimap(const recursive_multimap &x)
58 : multimap_(x.multimap_)
59 {}
60
61 recursive_multimap & operator=(const recursive_multimap &x)
62 { id_ = x.id_; multimap_ = x.multimap_; return *this; }
63
64 int id_;
65 multimap<recursive_multimap, recursive_multimap> multimap_;
66 multimap<recursive_multimap, recursive_multimap>::iterator it_;
67 multimap<recursive_multimap, recursive_multimap>::const_iterator cit_;
68 multimap<recursive_multimap, recursive_multimap>::reverse_iterator rit_;
69 multimap<recursive_multimap, recursive_multimap>::const_reverse_iterator crit_;
70
71 friend bool operator< (const recursive_multimap &a, const recursive_multimap &b)
72 { return a.id_ < b.id_; }
73};
74
75template<class C>
76void test_move()
77{
78 //Now test move semantics
79 C original;
80 original.emplace();
81 C move_ctor(boost::move(original));
82 C move_assign;
83 move_assign.emplace();
84 move_assign = boost::move(move_ctor);
85 move_assign.swap(original);
86}
87
88bool node_type_test()
89{
90 using namespace boost::container;
91 {
92 typedef map<test::movable_int, test::movable_int> map_type;
93 map_type src;
94 {
95 test::movable_int mv_1(1), mv_2(2), mv_3(3), mv_11(11), mv_12(12), mv_13(13);
96 src.try_emplace(k: boost::move(t&: mv_1), args: boost::move(t&: mv_11));
97 src.try_emplace(k: boost::move(t&: mv_2), args: boost::move(t&: mv_12));
98 src.try_emplace(k: boost::move(t&: mv_3), args: boost::move(t&: mv_13));
99 }
100 if(src.size() != 3)
101 return false;
102
103 map_type dst;
104 {
105 test::movable_int mv_3(3), mv_33(33);
106 dst.try_emplace(k: boost::move(t&: mv_3), args: boost::move(t&: mv_33));
107 }
108
109 if(dst.size() != 1)
110 return false;
111
112 const test::movable_int mv_1(1);
113 const test::movable_int mv_2(2);
114 const test::movable_int mv_3(3);
115 const test::movable_int mv_33(33);
116 const test::movable_int mv_13(13);
117 map_type::insert_return_type r;
118
119 r = dst.insert(nh: src.extract(k: mv_33)); // Key version, try to insert empty node
120 if(! (r.position == dst.end() && r.inserted == false && r.node.empty()) )
121 return false;
122 r = dst.insert(nh: src.extract(position: src.find(k: mv_1))); // Iterator version, successful
123 if(! (r.position == dst.find(k: mv_1) && r.inserted == true && r.node.empty()) )
124 return false;
125 r = dst.insert(hint: dst.begin(), nh: src.extract(k: mv_2)); // Key type version, successful
126 if(! (r.position == dst.find(k: mv_2) && r.inserted == true && r.node.empty()) )
127 return false;
128 r = dst.insert(nh: src.extract(k: mv_3)); // Key type version, unsuccessful
129
130 if(!src.empty())
131 return false;
132 if(dst.size() != 3)
133 return false;
134 if(! (r.position == dst.find(k: mv_3) && r.inserted == false && r.node.key() == mv_3 && r.node.mapped() == mv_13) )
135 return false;
136 }
137
138 {
139 typedef multimap<test::movable_int, test::movable_int> multimap_type;
140 multimap_type src;
141 {
142 test::movable_int mv_1(1), mv_2(2), mv_3(3), mv_3bis(3), mv_11(11), mv_12(12), mv_13(13), mv_23(23);
143 src.emplace(args: boost::move(t&: mv_1), args: boost::move(t&: mv_11));
144 src.emplace(args: boost::move(t&: mv_2), args: boost::move(t&: mv_12));
145 src.emplace(args: boost::move(t&: mv_3), args: boost::move(t&: mv_13));
146 src.emplace_hint(p: src.begin(), args: boost::move(t&: mv_3bis), args: boost::move(t&: mv_23));
147 }
148 if(src.size() != 4)
149 return false;
150
151 multimap_type dst;
152 {
153 test::movable_int mv_3(3), mv_33(33);
154 dst.emplace(args: boost::move(t&: mv_3), args: boost::move(t&: mv_33));
155 }
156
157 if(dst.size() != 1)
158 return false;
159
160 const test::movable_int mv_1(1);
161 const test::movable_int mv_2(2);
162 const test::movable_int mv_3(3);
163 const test::movable_int mv_4(4);
164 const test::movable_int mv_33(33);
165 const test::movable_int mv_13(13);
166 const test::movable_int mv_23(23);
167 multimap_type::iterator r;
168
169 multimap_type::node_type nt(src.extract(k: mv_3));
170 r = dst.insert(hint: dst.begin(), nh: boost::move(t&: nt));
171 if(! (r->first == mv_3 && r->second == mv_23 && dst.find(k: mv_3) == r && nt.empty()) )
172 return false;
173
174 nt = src.extract(position: src.find(k: mv_1));
175 r = dst.insert(nh: boost::move(t&: nt)); // Iterator version, successful
176 if(! (r->first == mv_1 && nt.empty()) )
177 return false;
178
179 nt = src.extract(k: mv_2);
180 r = dst.insert(nh: boost::move(t&: nt)); // Key type version, successful
181 if(! (r->first == mv_2 && nt.empty()) )
182 return false;
183
184 r = dst.insert(nh: src.extract(k: mv_3)); // Key type version, successful
185 if(! (r->first == mv_3 && r->second == mv_13 && r == --multimap_type::iterator(dst.upper_bound(k: mv_3)) && nt.empty()) )
186 return false;
187
188 r = dst.insert(nh: src.extract(k: mv_4)); // Key type version, unsuccessful
189 if(! (r == dst.end()) )
190 return false;
191
192 if(!src.empty())
193 return false;
194 if(dst.size() != 5)
195 return false;
196 }
197 return true;
198}
199
200template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
201struct GetAllocatorMap
202{
203 template<class ValueType>
204 struct apply
205 {
206 typedef map< ValueType
207 , ValueType
208 , std::less<ValueType>
209 , typename allocator_traits<VoidAllocator>
210 ::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
211 , typename boost::container::tree_assoc_options
212 < boost::container::tree_type<tree_type_value>
213 >::type
214 > map_type;
215
216 typedef multimap< ValueType
217 , ValueType
218 , std::less<ValueType>
219 , typename allocator_traits<VoidAllocator>
220 ::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
221 , typename boost::container::tree_assoc_options
222 < boost::container::tree_type<tree_type_value>
223 >::type
224 > multimap_type;
225 };
226};
227
228struct boost_container_map;
229struct boost_container_multimap;
230
231namespace boost { namespace container { namespace test {
232
233template<>
234struct alloc_propagate_base<boost_container_map>
235{
236 template <class T, class Allocator>
237 struct apply
238 {
239 typedef typename boost::container::allocator_traits<Allocator>::
240 template portable_rebind_alloc<std::pair<const T, T> >::type TypeAllocator;
241 typedef boost::container::map<T, T, std::less<T>, TypeAllocator> type;
242 };
243};
244
245template<>
246struct alloc_propagate_base<boost_container_multimap>
247{
248 template <class T, class Allocator>
249 struct apply
250 {
251 typedef typename boost::container::allocator_traits<Allocator>::
252 template portable_rebind_alloc<std::pair<const T, T> >::type TypeAllocator;
253 typedef boost::container::multimap<T, T, std::less<T>, TypeAllocator> type;
254 };
255};
256
257void test_merge_from_different_comparison()
258{
259 map<int, int> map1;
260 map<int, int, std::greater<int> > map2;
261 map1.merge(source&: map2);
262}
263
264bool test_heterogeneous_lookups()
265{
266 typedef map<int, char, less_transparent> map_t;
267 typedef multimap<int, char, less_transparent> mmap_t;
268 typedef map_t::value_type value_type;
269
270 map_t map1;
271 mmap_t mmap1;
272
273 const map_t &cmap1 = map1;
274 const mmap_t &cmmap1 = mmap1;
275
276 if(!map1.insert_or_assign(k: 1, obj: 'a').second)
277 return false;
278 if( map1.insert_or_assign(k: 1, obj: 'b').second)
279 return false;
280 if(!map1.insert_or_assign(k: 2, obj: 'c').second)
281 return false;
282 if( map1.insert_or_assign(k: 2, obj: 'd').second)
283 return false;
284 if(!map1.insert_or_assign(k: 3, obj: 'e').second)
285 return false;
286
287 if(map1.insert_or_assign(k: 1, obj: 'a').second)
288 return false;
289 if(map1.insert_or_assign(k: 1, obj: 'b').second)
290 return false;
291 if(map1.insert_or_assign(k: 2, obj: 'c').second)
292 return false;
293 if(map1.insert_or_assign(k: 2, obj: 'd').second)
294 return false;
295 if(map1.insert_or_assign(k: 3, obj: 'e').second)
296 return false;
297
298 mmap1.insert(x: value_type(1, 'a'));
299 mmap1.insert(x: value_type(1, 'b'));
300 mmap1.insert(x: value_type(2, 'c'));
301 mmap1.insert(x: value_type(2, 'd'));
302 mmap1.insert(x: value_type(3, 'e'));
303
304 const test::non_copymovable_int find_me(2);
305
306 //find
307 if(map1.find(k: find_me)->second != 'd')
308 return false;
309 if(cmap1.find(k: find_me)->second != 'd')
310 return false;
311 if(mmap1.find(k: find_me)->second != 'c')
312 return false;
313 if(cmmap1.find(k: find_me)->second != 'c')
314 return false;
315
316 //count
317 if(map1.count(x: find_me) != 1)
318 return false;
319 if(cmap1.count(x: find_me) != 1)
320 return false;
321 if(mmap1.count(k: find_me) != 2)
322 return false;
323 if(cmmap1.count(k: find_me) != 2)
324 return false;
325
326 //contains
327 if(!map1.contains(x: find_me))
328 return false;
329 if(!cmap1.contains(x: find_me))
330 return false;
331 if(!mmap1.contains(x: find_me))
332 return false;
333 if(!cmmap1.contains(x: find_me))
334 return false;
335
336 //lower_bound
337 if(map1.lower_bound(k: find_me)->second != 'd')
338 return false;
339 if(cmap1.lower_bound(k: find_me)->second != 'd')
340 return false;
341 if(mmap1.lower_bound(k: find_me)->second != 'c')
342 return false;
343 if(cmmap1.lower_bound(k: find_me)->second != 'c')
344 return false;
345
346 //upper_bound
347 if(map1.upper_bound(k: find_me)->second != 'e')
348 return false;
349 if(cmap1.upper_bound(k: find_me)->second != 'e')
350 return false;
351 if(mmap1.upper_bound(k: find_me)->second != 'e')
352 return false;
353 if(cmmap1.upper_bound(k: find_me)->second != 'e')
354 return false;
355
356 //equal_range
357 if(map1.equal_range(k: find_me).first->second != 'd')
358 return false;
359 if(cmap1.equal_range(k: find_me).second->second != 'e')
360 return false;
361 if(mmap1.equal_range(k: find_me).first->second != 'c')
362 return false;
363 if(cmmap1.equal_range(k: find_me).second->second != 'e')
364 return false;
365
366 return true;
367}
368
369bool constructor_template_auto_deduction_test()
370{
371
372#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
373 using namespace boost::container;
374 const std::size_t NumElements = 100;
375 {
376 std::map<int, int> int_map;
377 for(std::size_t i = 0; i != NumElements; ++i){
378 int_map.insert(x: std::map<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
379 }
380 std::multimap<int, int> int_mmap;
381 for (std::size_t i = 0; i != NumElements; ++i) {
382 int_mmap.insert(x: std::multimap<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
383 }
384
385 typedef std::less<int> comp_int_t;
386 typedef std::allocator<std::pair<const int, int> > alloc_pair_int_t;
387
388 //range
389 {
390 auto fmap = map(int_map.begin(), int_map.end());
391 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
392 return false;
393 auto fmmap = multimap(int_mmap.begin(), int_mmap.end());
394 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
395 return false;
396 }
397 //range+comp
398 {
399 auto fmap = map(int_map.begin(), int_map.end(), comp_int_t());
400 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
401 return false;
402 auto fmmap = multimap(int_mmap.begin(), int_mmap.end(), comp_int_t());
403 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
404 return false;
405 }
406 //range+comp+alloc
407 {
408 auto fmap = map(int_map.begin(), int_map.end(), comp_int_t(), alloc_pair_int_t());
409 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
410 return false;
411 auto fmmap = multimap(int_mmap.begin(), int_mmap.end(), comp_int_t(), alloc_pair_int_t());
412 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
413 return false;
414 }
415 //range+alloc
416 {
417 auto fmap = map(int_map.begin(), int_map.end(), alloc_pair_int_t());
418 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
419 return false;
420 auto fmmap = multimap(int_mmap.begin(), int_mmap.end(), alloc_pair_int_t());
421 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
422 return false;
423 }
424
425 //ordered_unique_range / ordered_range
426
427 //range
428 {
429 auto fmap = map(ordered_unique_range, int_map.begin(), int_map.end());
430 if(!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
431 return false;
432 auto fmmap = multimap(ordered_range, int_mmap.begin(), int_mmap.end());
433 if(!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
434 return false;
435 }
436 //range+comp
437 {
438 auto fmap = map(ordered_unique_range, int_map.begin(), int_map.end(), comp_int_t());
439 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
440 return false;
441 auto fmmap = multimap(ordered_range, int_mmap.begin(), int_mmap.end(), comp_int_t());
442 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
443 return false;
444 }
445 //range+comp+alloc
446 {
447 auto fmap = map(ordered_unique_range, int_map.begin(), int_map.end(), comp_int_t(), alloc_pair_int_t());
448 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
449 return false;
450 auto fmmap = multimap(ordered_range, int_mmap.begin(), int_mmap.end(), comp_int_t(), alloc_pair_int_t());
451 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
452 return false;
453 }
454 //range+alloc
455 {
456 auto fmap = map(ordered_unique_range, int_map.begin(), int_map.end(),alloc_pair_int_t());
457 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
458 return false;
459 auto fmmap = multimap(ordered_range, int_mmap.begin(), int_mmap.end(),alloc_pair_int_t());
460 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
461 return false;
462 }
463 }
464#endif
465
466 return true;
467}
468
469}}} //namespace boost::container::test
470
471int main ()
472{
473 //Recursive container instantiation
474 {
475 map<recursive_map, recursive_map> map_;
476 multimap<recursive_multimap, recursive_multimap> multimap_;
477 }
478 //Allocator argument container
479 {
480 map<int, int> map_((map<int, int>::allocator_type()));
481 multimap<int, int> multimap_((multimap<int, int>::allocator_type()));
482 }
483 //Now test move semantics
484 {
485 test_move<map<recursive_map, recursive_map> >();
486 test_move<multimap<recursive_multimap, recursive_multimap> >();
487 }
488
489 //Test std::pair value type as tree has workarounds to make old std::pair
490 //implementations movable that can break things
491 {
492 boost::container::map<pair_t, pair_t> s;
493 std::pair<const pair_t,pair_t> p;
494 s.insert(x&: p);
495 s.emplace(args&: p);
496 }
497
498 ////////////////////////////////////
499 // Testing allocator implementations
500 ////////////////////////////////////
501 {
502 typedef std::map<int, int> MyStdMap;
503 typedef std::multimap<int, int> MyStdMultiMap;
504
505 if (0 != test::map_test
506 < GetAllocatorMap<std::allocator<void>, red_black_tree>::apply<int>::map_type
507 , MyStdMap
508 , GetAllocatorMap<std::allocator<void>, red_black_tree>::apply<int>::multimap_type
509 , MyStdMultiMap>()) {
510 std::cout << "Error in map_test<std::allocator<void>, red_black_tree>" << std::endl;
511 return 1;
512 }
513
514 if (0 != test::map_test
515 < GetAllocatorMap<new_allocator<void>, avl_tree>::apply<int>::map_type
516 , MyStdMap
517 , GetAllocatorMap<new_allocator<void>, avl_tree>::apply<int>::multimap_type
518 , MyStdMultiMap>()) {
519 std::cout << "Error in map_test<new_allocator<void>, avl_tree>" << std::endl;
520 return 1;
521 }
522
523 if (0 != test::map_test
524 < GetAllocatorMap<adaptive_pool<void>, scapegoat_tree>::apply<int>::map_type
525 , MyStdMap
526 , GetAllocatorMap<adaptive_pool<void>, scapegoat_tree>::apply<int>::multimap_type
527 , MyStdMultiMap>()) {
528 std::cout << "Error in map_test<adaptive_pool<void>, scapegoat_tree>" << std::endl;
529 return 1;
530 }
531
532 ///////////
533
534 if (0 != test::map_test
535 < GetAllocatorMap<new_allocator<void>, splay_tree>::apply<test::movable_int>::map_type
536 , MyStdMap
537 , GetAllocatorMap<new_allocator<void>, splay_tree>::apply<test::movable_int>::multimap_type
538 , MyStdMultiMap>()) {
539 std::cout << "Error in map_test<new_allocator<void>, splay_tree>" << std::endl;
540 return 1;
541 }
542
543 if (0 != test::map_test
544 < GetAllocatorMap<new_allocator<void>, red_black_tree>::apply<test::copyable_int>::map_type
545 , MyStdMap
546 , GetAllocatorMap<new_allocator<void>, red_black_tree>::apply<test::copyable_int>::multimap_type
547 , MyStdMultiMap>()) {
548 std::cout << "Error in map_test<new_allocator<void>, red_black_tree>" << std::endl;
549 return 1;
550 }
551
552 if (0 != test::map_test
553 < GetAllocatorMap<new_allocator<void>, red_black_tree>::apply<test::movable_and_copyable_int>::map_type
554 , MyStdMap
555 , GetAllocatorMap<new_allocator<void>, red_black_tree>::apply<test::movable_and_copyable_int>::multimap_type
556 , MyStdMultiMap>()) {
557 std::cout << "Error in map_test<new_allocator<void>, red_black_tree>" << std::endl;
558 return 1;
559 }
560 }
561
562 ////////////////////////////////////
563 // Emplace testing
564 ////////////////////////////////////
565 const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
566 if(!boost::container::test::test_emplace<map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
567 return 1;
568 if(!boost::container::test::test_emplace<multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
569 return 1;
570
571 ////////////////////////////////////
572 // Allocator propagation testing
573 ////////////////////////////////////
574 if(!boost::container::test::test_propagate_allocator<boost_container_map>())
575 return 1;
576
577 if(!boost::container::test::test_propagate_allocator<boost_container_multimap>())
578 return 1;
579
580 if (!boost::container::test::test_map_support_for_initialization_list_for<map<int, int> >())
581 return 1;
582
583 if (!boost::container::test::test_map_support_for_initialization_list_for<multimap<int, int> >())
584 return 1;
585
586 ////////////////////////////////////
587 // Iterator testing
588 ////////////////////////////////////
589 {
590 typedef boost::container::map<int, int> cont_int;
591 cont_int a; a.insert(x: cont_int::value_type(0, 9)); a.insert(x: cont_int::value_type(1, 9)); a.insert(x: cont_int::value_type(2, 9));
592 boost::intrusive::test::test_iterator_bidirectional< cont_int >(c&: a);
593 if(boost::report_errors() != 0) {
594 return 1;
595 }
596 }
597 {
598 typedef boost::container::multimap<int, int> cont_int;
599 cont_int a; a.insert(x: cont_int::value_type(0, 9)); a.insert(x: cont_int::value_type(1, 9)); a.insert(x: cont_int::value_type(2, 9));
600 boost::intrusive::test::test_iterator_bidirectional< cont_int >(c&: a);
601 if(boost::report_errors() != 0) {
602 return 1;
603 }
604 }
605
606 ////////////////////////////////////
607 // Node extraction/insertion testing functions
608 ////////////////////////////////////
609 if(!node_type_test())
610 return 1;
611
612 ////////////////////////////////////
613 // Constructor Template Auto Deduction test
614 ////////////////////////////////////
615 if (!test::constructor_template_auto_deduction_test()) {
616 return 1;
617 }
618
619 if (!boost::container::test::instantiate_constructors<map<int, int>, multimap<int, int> >())
620 return 1;
621
622 test::test_merge_from_different_comparison();
623
624 if(!test::test_heterogeneous_lookups())
625 return 1;
626
627 ////////////////////////////////////
628 // Test optimize_size option
629 ////////////////////////////////////
630 //
631 // map
632 //
633 typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int *const, int*> >
634 , tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbmap_size_optimized_no;
635
636 typedef map< int*, int*, std::less<int*>, std::allocator< std::pair<int *const, int*> >
637 , tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlmap_size_optimized_yes;
638 //
639 // multimap
640 //
641 typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int *const, int*> >
642 , tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmmap_size_optimized_yes;
643 typedef multimap< int*, int*, std::less<int*>, std::allocator< std::pair<int *const, int*> >
644 , tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmmap_size_optimized_no;
645
646 BOOST_CONTAINER_STATIC_ASSERT(sizeof(rbmmap_size_optimized_yes) < sizeof(rbmap_size_optimized_no));
647 BOOST_CONTAINER_STATIC_ASSERT(sizeof(avlmap_size_optimized_yes) < sizeof(avlmmap_size_optimized_no));
648
649 ////////////////////////////////////
650 // has_trivial_destructor_after_move testing
651 ////////////////////////////////////
652 {
653 typedef std::pair<const int, int> value_type;
654 //
655 // map
656 //
657 // default allocator
658 {
659 typedef boost::container::map<int, int> cont;
660 typedef boost::container::dtl::tree<value_type, int, std::less<int>, void, void> tree;
661 BOOST_CONTAINER_STATIC_ASSERT_MSG(
662 !(boost::has_trivial_destructor_after_move<cont>::value !=
663 boost::has_trivial_destructor_after_move<tree>::value)
664 , "has_trivial_destructor_after_move(map, default allocator) test failed");
665 }
666 // std::allocator
667 {
668 typedef boost::container::map<int, int, std::less<int>, std::allocator<value_type> > cont;
669 typedef boost::container::dtl::tree<value_type, int, std::less<int>, std::allocator<value_type>, void> tree;
670 BOOST_CONTAINER_STATIC_ASSERT_MSG(
671 !(boost::has_trivial_destructor_after_move<cont>::value !=
672 boost::has_trivial_destructor_after_move<tree>::value)
673 , "has_trivial_destructor_after_move(map, std::allocator) test failed");
674 }
675 //
676 // multimap
677 //
678 // default allocator
679 {
680 // default allocator
681 typedef boost::container::multimap<int, int> cont;
682 typedef boost::container::dtl::tree<value_type, int, std::less<int>, void, void> tree;
683 BOOST_CONTAINER_STATIC_ASSERT_MSG(
684 !(boost::has_trivial_destructor_after_move<cont>::value !=
685 boost::has_trivial_destructor_after_move<tree>::value)
686 , "has_trivial_destructor_after_move(multimap, default allocator) test failed");
687 }
688 // std::allocator
689 {
690 typedef boost::container::multimap<int, int, std::less<int>, std::allocator<value_type> > cont;
691 typedef boost::container::dtl::tree<value_type, int, std::less<int>, std::allocator<value_type>, void> tree;
692 BOOST_CONTAINER_STATIC_ASSERT_MSG(
693 !(boost::has_trivial_destructor_after_move<cont>::value !=
694 boost::has_trivial_destructor_after_move<tree>::value)
695 , "has_trivial_destructor_after_move(multimap, std::allocator) test failed");
696 }
697 }
698
699 return 0;
700}
701

source code of boost/libs/container/test/map_test.cpp