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 <vector>
11
12#include <boost/container/flat_map.hpp>
13#include <boost/container/allocator.hpp>
14#include <boost/container/detail/container_or_allocator_rebind.hpp>
15
16#include "print_container.hpp"
17#include "dummy_test_allocator.hpp"
18#include "movable_int.hpp"
19#include "map_test.hpp"
20#include "propagate_allocator_test.hpp"
21#include "container_common_tests.hpp"
22#include "emplace_test.hpp"
23#include "../../intrusive/test/iterator_test.hpp"
24
25#include <map>
26#include <utility>
27
28
29using namespace boost::container;
30
31class recursive_flat_map
32{
33 public:
34 recursive_flat_map(const recursive_flat_map &c)
35 : id_(c.id_), map_(c.map_)
36 {}
37
38 recursive_flat_map & operator =(const recursive_flat_map &c)
39 {
40 id_ = c.id_;
41 map_= c.map_;
42 return *this;
43 }
44
45 int id_;
46 flat_map<recursive_flat_map, recursive_flat_map> map_;
47 flat_map<recursive_flat_map, recursive_flat_map>::iterator it_;
48 flat_map<recursive_flat_map, recursive_flat_map>::const_iterator cit_;
49 flat_map<recursive_flat_map, recursive_flat_map>::reverse_iterator rit_;
50 flat_map<recursive_flat_map, recursive_flat_map>::const_reverse_iterator crit_;
51
52 friend bool operator< (const recursive_flat_map &a, const recursive_flat_map &b)
53 { return a.id_ < b.id_; }
54};
55
56
57class recursive_flat_multimap
58{
59public:
60 recursive_flat_multimap(const recursive_flat_multimap &c)
61 : id_(c.id_), map_(c.map_)
62 {}
63
64 recursive_flat_multimap & operator =(const recursive_flat_multimap &c)
65 {
66 id_ = c.id_;
67 map_= c.map_;
68 return *this;
69 }
70 int id_;
71 flat_multimap<recursive_flat_multimap, recursive_flat_multimap> map_;
72 flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::iterator it_;
73 flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::const_iterator cit_;
74 flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::reverse_iterator rit_;
75 flat_multimap<recursive_flat_multimap, recursive_flat_multimap>::const_reverse_iterator crit_;
76
77 friend bool operator< (const recursive_flat_multimap &a, const recursive_flat_multimap &b)
78 { return a.id_ < b.id_; }
79};
80
81template<class C>
82void test_move()
83{
84 //Now test move semantics
85 C original;
86 C move_ctor(boost::move(original));
87 C move_assign;
88 move_assign = boost::move(move_ctor);
89 move_assign.swap(original);
90}
91
92
93namespace boost{
94namespace container {
95namespace test{
96
97bool flat_tree_ordered_insertion_test()
98{
99 using namespace boost::container;
100 const std::size_t NumElements = 100;
101
102 //Ordered insertion multimap
103 {
104 std::multimap<int, int> int_mmap;
105 for(std::size_t i = 0; i != NumElements; ++i){
106 int_mmap.insert(x: std::multimap<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
107 }
108 //Construction insertion
109 flat_multimap<int, int> fmmap(ordered_range, int_mmap.begin(), int_mmap.end());
110 if(!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
111 return false;
112 //Insertion when empty
113 fmmap.clear();
114 fmmap.insert(ordered_range, first: int_mmap.begin(), last: int_mmap.end());
115 if(!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
116 return false;
117 //Re-insertion
118 fmmap.insert(ordered_range, first: int_mmap.begin(), last: int_mmap.end());
119 std::multimap<int, int> int_mmap2(int_mmap);
120 int_mmap2.insert(first: int_mmap.begin(), last: int_mmap.end());
121 if(!CheckEqualContainers(cont_a: int_mmap2, cont_b: fmmap))
122 return false;
123 //Re-re-insertion
124 fmmap.insert(ordered_range, first: int_mmap2.begin(), last: int_mmap2.end());
125 std::multimap<int, int> int_mmap4(int_mmap2);
126 int_mmap4.insert(first: int_mmap2.begin(), last: int_mmap2.end());
127 if(!CheckEqualContainers(cont_a: int_mmap4, cont_b: fmmap))
128 return false;
129 //Re-re-insertion of even
130 std::multimap<int, int> int_even_mmap;
131 for(std::size_t i = 0; i < NumElements; i+=2){
132 int_mmap.insert(x: std::multimap<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
133 }
134 fmmap.insert(ordered_range, first: int_even_mmap.begin(), last: int_even_mmap.end());
135 int_mmap4.insert(first: int_even_mmap.begin(), last: int_even_mmap.end());
136 if(!CheckEqualContainers(cont_a: int_mmap4, cont_b: fmmap))
137 return false;
138 }
139
140 //Ordered insertion map
141 {
142 std::map<int, int> int_map;
143 for(std::size_t i = 0; i != NumElements; ++i){
144 int_map.insert(x: std::map<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
145 }
146 //Construction insertion
147 flat_map<int, int> fmap(ordered_unique_range, int_map.begin(), int_map.end());
148 if(!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
149 return false;
150 //Insertion when empty
151 fmap.clear();
152 fmap.insert(ordered_unique_range, first: int_map.begin(), last: int_map.end());
153 if(!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
154 return false;
155 //Re-insertion
156 fmap.insert(ordered_unique_range, first: int_map.begin(), last: int_map.end());
157 std::map<int, int> int_map2(int_map);
158 int_map2.insert(first: int_map.begin(), last: int_map.end());
159 if(!CheckEqualContainers(cont_a: int_map2, cont_b: fmap))
160 return false;
161 //Re-re-insertion
162 fmap.insert(ordered_unique_range, first: int_map2.begin(), last: int_map2.end());
163 std::map<int, int> int_map4(int_map2);
164 int_map4.insert(first: int_map2.begin(), last: int_map2.end());
165 if(!CheckEqualContainers(cont_a: int_map4, cont_b: fmap))
166 return false;
167 //Re-re-insertion of even
168 std::map<int, int> int_even_map;
169 for(std::size_t i = 0; i < NumElements; i+=2){
170 int_map.insert(x: std::map<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
171 }
172 fmap.insert(ordered_unique_range, first: int_even_map.begin(), last: int_even_map.end());
173 int_map4.insert(first: int_even_map.begin(), last: int_even_map.end());
174 if(!CheckEqualContainers(cont_a: int_map4, cont_b: fmap))
175 return false;
176 }
177
178 return true;
179}
180
181bool constructor_template_auto_deduction_test()
182{
183
184#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
185 using namespace boost::container;
186 const std::size_t NumElements = 100;
187 {
188 std::map<int, int> int_map;
189 for(std::size_t i = 0; i != NumElements; ++i){
190 int_map.insert(x: std::map<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
191 }
192 std::multimap<int, int> int_mmap;
193 for (std::size_t i = 0; i != NumElements; ++i) {
194 int_mmap.insert(x: std::multimap<int, int>::value_type(static_cast<int>(i), static_cast<int>(i)));
195 }
196
197 typedef std::less<int> comp_int_t;
198 typedef std::allocator<std::pair<int, int> > alloc_pair_int_t;
199
200 //range
201 {
202 auto fmap = flat_map(int_map.begin(), int_map.end());
203 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
204 return false;
205 auto fmmap = flat_multimap(int_mmap.begin(), int_mmap.end());
206 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
207 return false;
208 }
209 //range+comp
210 {
211 auto fmap = flat_map(int_map.begin(), int_map.end(), comp_int_t());
212 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
213 return false;
214 auto fmmap = flat_multimap(int_mmap.begin(), int_mmap.end(), comp_int_t());
215 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
216 return false;
217 }
218 //range+comp+alloc
219 {
220 auto fmap = flat_map(int_map.begin(), int_map.end(), comp_int_t(), alloc_pair_int_t());
221 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
222 return false;
223 auto fmmap = flat_multimap(int_mmap.begin(), int_mmap.end(), comp_int_t(), alloc_pair_int_t());
224 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
225 return false;
226 }
227 //range+alloc
228 {
229 auto fmap = flat_map(int_map.begin(), int_map.end(), alloc_pair_int_t());
230 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
231 return false;
232 auto fmmap = flat_multimap(int_mmap.begin(), int_mmap.end(), alloc_pair_int_t());
233 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
234 return false;
235 }
236
237 //ordered_unique_range / ordered_range
238
239 //range
240 {
241 auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end());
242 if(!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
243 return false;
244 auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end());
245 if(!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
246 return false;
247 }
248 //range+comp
249 {
250 auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end(), comp_int_t());
251 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
252 return false;
253 auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end(), comp_int_t());
254 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
255 return false;
256 }
257 //range+comp+alloc
258 {
259 auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end(), comp_int_t(), alloc_pair_int_t());
260 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
261 return false;
262 auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end(), comp_int_t(), alloc_pair_int_t());
263 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
264 return false;
265 }
266 //range+alloc
267 {
268 auto fmap = flat_map(ordered_unique_range, int_map.begin(), int_map.end(),alloc_pair_int_t());
269 if (!CheckEqualContainers(cont_a: int_map, cont_b: fmap))
270 return false;
271 auto fmmap = flat_multimap(ordered_range, int_mmap.begin(), int_mmap.end(),alloc_pair_int_t());
272 if (!CheckEqualContainers(cont_a: int_mmap, cont_b: fmmap))
273 return false;
274 }
275 }
276#endif
277
278 return true;
279}
280
281template< class RandomIt >
282void random_shuffle( RandomIt first, RandomIt last )
283{
284 typedef typename boost::container::iterator_traits<RandomIt>::difference_type difference_type;
285 difference_type n = last - first;
286 for (difference_type i = n-1; i > 0; --i) {
287 difference_type j = std::rand() % (i+1);
288 if(j != i) {
289 boost::adl_move_swap(first[i], first[j]);
290 }
291 }
292}
293
294bool flat_tree_extract_adopt_test()
295{
296 using namespace boost::container;
297 const std::size_t NumElements = 100;
298
299 //extract/adopt map
300 {
301 //Construction insertion
302 flat_map<int, int> fmap;
303
304 for(std::size_t i = 0; i != NumElements; ++i){
305 fmap.emplace(args: static_cast<int>(i), args: -static_cast<int>(i));
306 }
307
308 const flat_map<int, int> fmap_copy(fmap);
309 flat_map<int, int>::sequence_type seq(fmap.extract_sequence());
310 if(!fmap.empty())
311 return false;
312 if(!CheckEqualContainers(cont_a: seq, cont_b: fmap_copy))
313 return false;
314
315 seq.insert(pos: seq.end(), first: fmap_copy.begin(), last: fmap_copy.end());
316 boost::container::test::random_shuffle(first: seq.begin(), last: seq.end());
317 fmap.adopt_sequence(seq: boost::move(t&: seq));
318 if(!CheckEqualContainers(cont_a: fmap, cont_b: fmap_copy))
319 return false;
320 if (!CheckEqualContainers(cont_a: fmap.sequence(), cont_b: fmap_copy.sequence()))
321 return false;
322 }
323
324 //extract/adopt map, ordered_unique_range
325 {
326 //Construction insertion
327 flat_map<int, int> fmap;
328
329 for(std::size_t i = 0; i != NumElements; ++i){
330 fmap.emplace(args: static_cast<int>(i), args: -static_cast<int>(i));
331 }
332
333 const flat_map<int, int> fmap_copy(fmap);
334 flat_map<int, int>::sequence_type seq(fmap.extract_sequence());
335 if(!fmap.empty())
336 return false;
337 if(!CheckEqualContainers(cont_a: seq, cont_b: fmap_copy))
338 return false;
339
340 fmap.adopt_sequence(ordered_unique_range, seq: boost::move(t&: seq));
341 if(!CheckEqualContainers(cont_a: fmap, cont_b: fmap_copy))
342 return false;
343 if (!CheckEqualContainers(cont_a: fmap.sequence(), cont_b: fmap_copy.sequence()))
344 return false;
345 }
346
347 //extract/adopt multimap
348 {
349 //Construction insertion
350 flat_multimap<int, int> fmmap;
351
352 for(std::size_t i = 0; i != NumElements; ++i){
353 fmmap.emplace(args: static_cast<int>(i), args: -static_cast<int>(i));
354 fmmap.emplace(args: static_cast<int>(i), args: -static_cast<int>(i));
355 }
356
357 const flat_multimap<int, int> fmmap_copy(fmmap);
358 flat_multimap<int, int>::sequence_type seq(fmmap.extract_sequence());
359 if(!fmmap.empty())
360 return false;
361 if(!CheckEqualContainers(cont_a: seq, cont_b: fmmap_copy))
362 return false;
363
364 boost::container::test::random_shuffle(first: seq.begin(), last: seq.end());
365 fmmap.adopt_sequence(seq: boost::move(t&: seq));
366 if(!CheckEqualContainers(cont_a: fmmap, cont_b: fmmap_copy))
367 return false;
368 if (!CheckEqualContainers(cont_a: fmmap.sequence(), cont_b: fmmap_copy.sequence()))
369 return false;
370 }
371
372 //extract/adopt multimap, ordered_range
373 {
374 //Construction insertion
375 flat_multimap<int, int> fmmap;
376
377 for(std::size_t i = 0; i != NumElements; ++i){
378 fmmap.emplace(args: static_cast<int>(i), args: -static_cast<int>(i));
379 fmmap.emplace(args: static_cast<int>(i), args: -static_cast<int>(i));
380 }
381
382 const flat_multimap<int, int> fmmap_copy(fmmap);
383 flat_multimap<int, int>::sequence_type seq(fmmap.extract_sequence());
384 if(!fmmap.empty())
385 return false;
386 if(!CheckEqualContainers(cont_a: seq, cont_b: fmmap_copy))
387 return false;
388
389 fmmap.adopt_sequence(ordered_range, seq: boost::move(t&: seq));
390 if(!CheckEqualContainers(cont_a: fmmap, cont_b: fmmap_copy))
391 return false;
392 if (!CheckEqualContainers(cont_a: fmmap.sequence(), cont_b: fmmap_copy.sequence()))
393 return false;
394 }
395
396 return true;
397}
398
399}}}
400
401template<class VoidAllocatorOrContainer>
402struct GetMapContainer
403{
404 template<class ValueType>
405 struct apply
406 {
407 typedef std::pair<ValueType, ValueType> type_t;
408 typedef flat_map< ValueType
409 , ValueType
410 , std::less<ValueType>
411 , typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, type_t>::type
412 > map_type;
413
414 typedef flat_multimap< ValueType
415 , ValueType
416 , std::less<ValueType>
417 , typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, type_t>::type
418 > multimap_type;
419 };
420};
421
422struct boost_container_flat_map;
423struct boost_container_flat_multimap;
424
425namespace boost { namespace container { namespace test {
426
427template<>
428struct alloc_propagate_base<boost_container_flat_map>
429{
430 template <class T, class Allocator>
431 struct apply
432 {
433 typedef typename boost::container::allocator_traits<Allocator>::
434 template portable_rebind_alloc<std::pair<T, T> >::type TypeAllocator;
435 typedef boost::container::flat_map<T, T, std::less<T>, TypeAllocator> type;
436 };
437};
438
439template<>
440struct alloc_propagate_base<boost_container_flat_multimap>
441{
442 template <class T, class Allocator>
443 struct apply
444 {
445 typedef typename boost::container::allocator_traits<Allocator>::
446 template portable_rebind_alloc<std::pair<T, T> >::type TypeAllocator;
447 typedef boost::container::flat_multimap<T, T, std::less<T>, TypeAllocator> type;
448 };
449};
450
451template <class Key, class T, class Compare, class Allocator>
452struct get_real_stored_allocator<flat_map<Key, T, Compare, Allocator> >
453{
454 typedef typename flat_map<Key, T, Compare, Allocator>::impl_stored_allocator_type type;
455};
456
457template <class Key, class T, class Compare, class Allocator>
458struct get_real_stored_allocator<flat_multimap<Key, T, Compare, Allocator> >
459{
460 typedef typename flat_multimap<Key, T, Compare, Allocator>::impl_stored_allocator_type type;
461};
462
463bool test_heterogeneous_lookups()
464{
465 BOOST_CONTAINER_STATIC_ASSERT((dtl::is_transparent<less_transparent>::value));
466 BOOST_CONTAINER_STATIC_ASSERT(!(dtl::is_transparent<std::less<int> >::value));
467 typedef flat_map<int, char, less_transparent> map_t;
468 typedef flat_multimap<int, char, less_transparent> mmap_t;
469 typedef map_t::value_type value_type;
470
471 map_t map1;
472 mmap_t mmap1;
473
474 const map_t &cmap1 = map1;
475 const mmap_t &cmmap1 = mmap1;
476
477 if(!map1.insert_or_assign(k: 1, obj: 'a').second)
478 return false;
479 if( map1.insert_or_assign(k: 1, obj: 'b').second)
480 return false;
481 if(!map1.insert_or_assign(k: 2, obj: 'c').second)
482 return false;
483 if( map1.insert_or_assign(k: 2, obj: 'd').second)
484 return false;
485 if(!map1.insert_or_assign(k: 3, obj: 'e').second)
486 return false;
487
488 if(map1.insert_or_assign(k: 1, obj: 'a').second)
489 return false;
490 if(map1.insert_or_assign(k: 1, obj: 'b').second)
491 return false;
492 if(map1.insert_or_assign(k: 2, obj: 'c').second)
493 return false;
494 if(map1.insert_or_assign(k: 2, obj: 'd').second)
495 return false;
496 if(map1.insert_or_assign(k: 3, obj: 'e').second)
497 return false;
498
499 mmap1.insert(x: value_type(1, 'a'));
500 mmap1.insert(x: value_type(1, 'b'));
501 mmap1.insert(x: value_type(2, 'c'));
502 mmap1.insert(x: value_type(2, 'd'));
503 mmap1.insert(x: value_type(3, 'e'));
504
505 const test::non_copymovable_int find_me(2);
506
507 //find
508 if(map1.find(x: find_me)->second != 'd')
509 return false;
510 if(cmap1.find(x: find_me)->second != 'd')
511 return false;
512 if(mmap1.find(x: find_me)->second != 'c')
513 return false;
514 if(cmmap1.find(x: find_me)->second != 'c')
515 return false;
516
517 //count
518 if(map1.count(x: find_me) != 1)
519 return false;
520 if(cmap1.count(x: find_me) != 1)
521 return false;
522 if(mmap1.count(x: find_me) != 2)
523 return false;
524 if(cmmap1.count(x: find_me) != 2)
525 return false;
526
527 //contains
528 if(!map1.contains(x: find_me))
529 return false;
530 if(!cmap1.contains(x: find_me))
531 return false;
532 if(!mmap1.contains(x: find_me))
533 return false;
534 if(!cmmap1.contains(x: find_me))
535 return false;
536
537 //lower_bound
538 if(map1.lower_bound(x: find_me)->second != 'd')
539 return false;
540 if(cmap1.lower_bound(x: find_me)->second != 'd')
541 return false;
542 if(mmap1.lower_bound(x: find_me)->second != 'c')
543 return false;
544 if(cmmap1.lower_bound(x: find_me)->second != 'c')
545 return false;
546
547 //upper_bound
548 if(map1.upper_bound(x: find_me)->second != 'e')
549 return false;
550 if(cmap1.upper_bound(x: find_me)->second != 'e')
551 return false;
552 if(mmap1.upper_bound(x: find_me)->second != 'e')
553 return false;
554 if(cmmap1.upper_bound(x: find_me)->second != 'e')
555 return false;
556
557 //equal_range
558 if(map1.equal_range(x: find_me).first->second != 'd')
559 return false;
560 if(cmap1.equal_range(x: find_me).second->second != 'e')
561 return false;
562 if(mmap1.equal_range(x: find_me).first->second != 'c')
563 return false;
564 if(cmmap1.equal_range(x: find_me).second->second != 'e')
565 return false;
566
567 return true;
568}
569
570// An ordered sequence of std:pair is also ordered by std::pair::first.
571struct with_lookup_by_first
572{
573 typedef void is_transparent;
574 inline bool operator()(std::pair<int, int> a, std::pair<int, int> b) const
575 {
576 return a < b;
577 }
578 inline bool operator()(std::pair<int, int> a, int first) const
579 {
580 return a.first < first;
581 }
582 inline bool operator()(int first, std::pair<int, int> b) const
583 {
584 return first < b.first;
585 }
586};
587
588bool test_heterogeneous_lookup_by_partial_key()
589{
590 typedef flat_map<std::pair<int, int>,int, with_lookup_by_first> map_t;
591
592 map_t map1;
593 map1[std::pair<int, int>(0, 1)] = 3;
594 map1[std::pair<int, int>(0, 2)] = 3;
595
596 std::pair<map_t::iterator, map_t::iterator> const first_0_range = map1.equal_range(x: 0);
597
598 if(2 != (first_0_range.second - first_0_range.first))
599 return false;
600
601 if(2 != map1.count(x: 0))
602 return false;
603 return true;
604}
605
606}}} //namespace boost::container::test
607
608int main()
609{
610 using namespace boost::container::test;
611
612 //Allocator argument container
613 {
614 flat_map<int, int> map_((flat_map<int, int>::allocator_type()));
615 flat_multimap<int, int> multimap_((flat_multimap<int, int>::allocator_type()));
616 }
617 //Now test move semantics
618 {
619 test_move<flat_map<recursive_flat_map, recursive_flat_map> >();
620 test_move<flat_multimap<recursive_flat_multimap, recursive_flat_multimap> >();
621 }
622 //Now test nth/index_of
623 {
624 flat_map<int, int> map;
625 flat_multimap<int, int> mmap;
626
627 map.insert(x: std::pair<int, int>(0, 0));
628 map.insert(x: std::pair<int, int>(1, 0));
629 map.insert(x: std::pair<int, int>(2, 0));
630 mmap.insert(x: std::pair<int, int>(0, 0));
631 mmap.insert(x: std::pair<int, int>(1, 0));
632 mmap.insert(x: std::pair<int, int>(2, 0));
633 if(!boost::container::test::test_nth_index_of(c&: map))
634 return 1;
635 if(!boost::container::test::test_nth_index_of(c&: mmap))
636 return 1;
637 }
638
639 ////////////////////////////////////
640 // Ordered insertion test
641 ////////////////////////////////////
642 if(!flat_tree_ordered_insertion_test()){
643 return 1;
644 }
645
646 ////////////////////////////////////
647 // Constructor Template Auto Deduction test
648 ////////////////////////////////////
649 if(!constructor_template_auto_deduction_test()){
650 return 1;
651 }
652
653 ////////////////////////////////////
654 // Extract/Adopt test
655 ////////////////////////////////////
656 if(!flat_tree_extract_adopt_test()){
657 return 1;
658 }
659
660 if (!boost::container::test::instantiate_constructors<flat_map<int, int>, flat_multimap<int, int> >())
661 return 1;
662
663 if (!test_heterogeneous_lookups())
664 return 1;
665
666 if (!test_heterogeneous_lookup_by_partial_key())
667 return 1;
668
669 ////////////////////////////////////
670 // Testing allocator implementations
671 ////////////////////////////////////
672 {
673 typedef std::map<int, int> MyStdMap;
674 typedef std::multimap<int, int> MyStdMultiMap;
675
676 if (0 != test::map_test
677 < GetMapContainer<std::allocator<void> >::apply<int>::map_type
678 , MyStdMap
679 , GetMapContainer<std::allocator<void> >::apply<int>::multimap_type
680 , MyStdMultiMap>()) {
681 std::cout << "Error in map_test<std::allocator<void> >" << std::endl;
682 return 1;
683 }
684
685 if (0 != test::map_test
686 < GetMapContainer<new_allocator<void> >::apply<int>::map_type
687 , MyStdMap
688 , GetMapContainer<new_allocator<void> >::apply<int>::multimap_type
689 , MyStdMultiMap>()) {
690 std::cout << "Error in map_test<new_allocator<void> >" << std::endl;
691 return 1;
692 }
693
694 if (0 != test::map_test
695 < GetMapContainer<new_allocator<void> >::apply<test::movable_int>::map_type
696 , MyStdMap
697 , GetMapContainer<new_allocator<void> >::apply<test::movable_int>::multimap_type
698 , MyStdMultiMap>()) {
699 std::cout << "Error in map_test<new_allocator<void> >" << std::endl;
700 return 1;
701 }
702
703 if (0 != test::map_test
704 < GetMapContainer<new_allocator<void> >::apply<test::copyable_int>::map_type
705 , MyStdMap
706 , GetMapContainer<new_allocator<void> >::apply<test::copyable_int>::multimap_type
707 , MyStdMultiMap>()) {
708 std::cout << "Error in map_test<new_allocator<void> >" << std::endl;
709 return 1;
710 }
711
712 if (0 != test::map_test
713 < GetMapContainer<new_allocator<void> >::apply<test::movable_and_copyable_int>::map_type
714 , MyStdMap
715 , GetMapContainer<new_allocator<void> >::apply<test::movable_and_copyable_int>::multimap_type
716 , MyStdMultiMap>()) {
717 std::cout << "Error in map_test<new_allocator<void> >" << std::endl;
718 return 1;
719 }
720 }
721
722 if(!boost::container::test::test_map_support_for_initialization_list_for<flat_map<int, int> >())
723 return 1;
724
725 if (!boost::container::test::test_map_support_for_initialization_list_for<flat_multimap<int, int> >())
726 return 1;
727
728 ////////////////////////////////////
729 // Emplace testing
730 ////////////////////////////////////
731 const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
732
733 if(!boost::container::test::test_emplace<flat_map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
734 return 1;
735 if(!boost::container::test::test_emplace<flat_multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
736 return 1;
737
738 ////////////////////////////////////
739 // Allocator propagation testing
740 ////////////////////////////////////
741 if(!boost::container::test::test_propagate_allocator<boost_container_flat_map>())
742 return 1;
743
744 if(!boost::container::test::test_propagate_allocator<boost_container_flat_multimap>())
745 return 1;
746
747 ////////////////////////////////////
748 // Iterator testing
749 ////////////////////////////////////
750 {
751 typedef boost::container::flat_map<int, int> cont_int;
752 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));
753 boost::intrusive::test::test_iterator_random< cont_int >(c&: a);
754 if(boost::report_errors() != 0) {
755 return 1;
756 }
757 }
758 {
759 typedef boost::container::flat_multimap<int, int> cont_int;
760 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));
761 boost::intrusive::test::test_iterator_random< cont_int >(c&: a);
762 if(boost::report_errors() != 0) {
763 return 1;
764 }
765 }
766
767 ////////////////////////////////////
768 // has_trivial_destructor_after_move testing
769 ////////////////////////////////////
770 {
771 typedef boost::container::dtl::pair<int, int> value_t;
772 typedef boost::container::dtl::select1st<int> key_of_value_t;
773 // flat_map, default
774 {
775 typedef boost::container::new_allocator<value_t> alloc_or_cont_t;
776 typedef boost::container::flat_map<int, int> cont;
777 typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
778 BOOST_CONTAINER_STATIC_ASSERT_MSG( boost::has_trivial_destructor_after_move<cont>::value ==
779 boost::has_trivial_destructor_after_move<tree>::value
780 , "has_trivial_destructor_after_move(flat_map, default) test failed");
781 }
782 // flat_map, vector
783 {
784 typedef boost::container::vector<value_t> alloc_or_cont_t;
785 typedef boost::container::flat_map<int, int, std::less<int>, alloc_or_cont_t> cont;
786 typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
787 BOOST_CONTAINER_STATIC_ASSERT_MSG( boost::has_trivial_destructor_after_move<cont>::value ==
788 boost::has_trivial_destructor_after_move<tree>::value
789 , "has_trivial_destructor_after_move(flat_map, vector) test failed");
790 }
791 // flat_map, std::vector
792 {
793 typedef std::vector<value_t> alloc_or_cont_t;
794 typedef boost::container::flat_map<int, int, std::less<int>, alloc_or_cont_t> cont;
795 typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
796 BOOST_CONTAINER_STATIC_ASSERT_MSG( boost::has_trivial_destructor_after_move<cont>::value ==
797 boost::has_trivial_destructor_after_move<tree>::value
798 , "has_trivial_destructor_after_move(flat_map, std::vector) test failed");
799 }
800 // flat_multimap, default
801 {
802 typedef boost::container::new_allocator<value_t> alloc_or_cont_t;
803 typedef boost::container::flat_multimap<int, int> cont;
804 typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
805 BOOST_CONTAINER_STATIC_ASSERT_MSG( boost::has_trivial_destructor_after_move<cont>::value ==
806 boost::has_trivial_destructor_after_move<tree>::value
807 , "has_trivial_destructor_after_move(flat_multimap, default) test failed");
808 }
809 // flat_multimap, vector
810 {
811 typedef boost::container::vector<value_t> alloc_or_cont_t;
812 typedef boost::container::flat_multimap<int, int, std::less<int>, alloc_or_cont_t> cont;
813 typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
814 BOOST_CONTAINER_STATIC_ASSERT_MSG( boost::has_trivial_destructor_after_move<cont>::value ==
815 boost::has_trivial_destructor_after_move<tree>::value
816 , "has_trivial_destructor_after_move(flat_multimap, vector) test failed");
817 }
818 // flat_multimap, std::vector
819 {
820 typedef std::vector<value_t> alloc_or_cont_t;
821 typedef boost::container::flat_multimap<int, int, std::less<int>, alloc_or_cont_t> cont;
822 typedef boost::container::dtl::flat_tree<value_t, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
823 BOOST_CONTAINER_STATIC_ASSERT_MSG (boost::has_trivial_destructor_after_move<cont>::value ==
824 boost::has_trivial_destructor_after_move<tree>::value
825 , "has_trivial_destructor_after_move(flat_multimap, std::vector) test failed");
826 }
827 }
828
829 return 0;
830}
831

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