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 | |
29 | using namespace boost::container; |
30 | |
31 | class 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 | |
57 | class recursive_flat_multimap |
58 | { |
59 | public: |
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 | |
81 | template<class C> |
82 | void 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 | |
93 | namespace boost{ |
94 | namespace container { |
95 | namespace test{ |
96 | |
97 | bool 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 | |
181 | bool 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 | |
281 | template< class RandomIt > |
282 | void 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 | |
294 | bool 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 | |
401 | template<class VoidAllocatorOrContainer> |
402 | struct 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 | |
422 | struct boost_container_flat_map; |
423 | struct boost_container_flat_multimap; |
424 | |
425 | namespace boost { namespace container { namespace test { |
426 | |
427 | template<> |
428 | struct 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 | |
439 | template<> |
440 | struct 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 | |
451 | template <class Key, class T, class Compare, class Allocator> |
452 | struct 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 | |
457 | template <class Key, class T, class Compare, class Allocator> |
458 | struct 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 | |
463 | bool 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. |
571 | struct 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 | |
588 | bool 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 | |
608 | int 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 |
Definitions
- recursive_flat_map
- recursive_flat_map
- operator =
- operator<
- recursive_flat_multimap
- recursive_flat_multimap
- operator =
- operator<
- test_move
- flat_tree_ordered_insertion_test
- constructor_template_auto_deduction_test
- random_shuffle
- flat_tree_extract_adopt_test
- GetMapContainer
- apply
- alloc_propagate_base
- apply
- alloc_propagate_base
- apply
- get_real_stored_allocator
- get_real_stored_allocator
- test_heterogeneous_lookups
- with_lookup_by_first
- operator()
- operator()
- operator()
- test_heterogeneous_lookup_by_partial_key
Improve your Profiling and Debugging skills
Find out more