1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #include <boost/container/detail/config_begin.hpp>
12 #include <boost/container/flat_map.hpp>
13 #include <boost/container/allocator.hpp>
14 #include <boost/container/detail/flat_tree.hpp>
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"
29 using namespace boost::container
;
34 //Explicit instantiation to detect compilation errors
38 template class flat_map
39 < test::movable_and_copyable_int
40 , test::movable_and_copyable_int
41 , std::less
<test::movable_and_copyable_int
>
42 , test::simple_allocator
43 < std::pair
<test::movable_and_copyable_int
, test::movable_and_copyable_int
> >
46 template class flat_map
47 < test::movable_and_copyable_int
48 , test::movable_and_copyable_int
49 , std::less
<test::movable_and_copyable_int
>
51 < std::pair
<test::movable_and_copyable_int
, test::movable_and_copyable_int
> >
54 template class flat_map
55 < test::movable_and_copyable_int
56 , test::movable_and_copyable_int
57 , std::less
<test::movable_and_copyable_int
>
59 < std::pair
<test::movable_and_copyable_int
, test::movable_and_copyable_int
> >
63 template class flat_multimap
64 < test::movable_and_copyable_int
65 , test::movable_and_copyable_int
66 , std::less
<test::movable_and_copyable_int
>
67 , test::simple_allocator
68 < std::pair
<test::movable_and_copyable_int
, test::movable_and_copyable_int
> >
71 //As flat container iterators are typedefs for vector::[const_]iterator,
72 //no need to explicit instantiate them
77 class recursive_flat_map
80 recursive_flat_map(const recursive_flat_map
&c
)
81 : id_(c
.id_
), map_(c
.map_
)
84 recursive_flat_map
& operator =(const recursive_flat_map
&c
)
92 flat_map
<recursive_flat_map
, recursive_flat_map
> map_
;
93 flat_map
<recursive_flat_map
, recursive_flat_map
>::iterator it_
;
94 flat_map
<recursive_flat_map
, recursive_flat_map
>::const_iterator cit_
;
95 flat_map
<recursive_flat_map
, recursive_flat_map
>::reverse_iterator rit_
;
96 flat_map
<recursive_flat_map
, recursive_flat_map
>::const_reverse_iterator crit_
;
98 friend bool operator< (const recursive_flat_map
&a
, const recursive_flat_map
&b
)
99 { return a
.id_
< b
.id_
; }
103 class recursive_flat_multimap
106 recursive_flat_multimap(const recursive_flat_multimap
&c
)
107 : id_(c
.id_
), map_(c
.map_
)
110 recursive_flat_multimap
& operator =(const recursive_flat_multimap
&c
)
117 flat_multimap
<recursive_flat_multimap
, recursive_flat_multimap
> map_
;
118 flat_multimap
<recursive_flat_multimap
, recursive_flat_multimap
>::iterator it_
;
119 flat_multimap
<recursive_flat_multimap
, recursive_flat_multimap
>::const_iterator cit_
;
120 flat_multimap
<recursive_flat_multimap
, recursive_flat_multimap
>::reverse_iterator rit_
;
121 flat_multimap
<recursive_flat_multimap
, recursive_flat_multimap
>::const_reverse_iterator crit_
;
123 friend bool operator< (const recursive_flat_multimap
&a
, const recursive_flat_multimap
&b
)
124 { return a
.id_
< b
.id_
; }
130 //Now test move semantics
132 C
move_ctor(boost::move(original
));
134 move_assign
= boost::move(move_ctor
);
135 move_assign
.swap(original
);
140 namespace container
{
143 bool flat_tree_ordered_insertion_test()
145 using namespace boost::container
;
146 const std::size_t NumElements
= 100;
148 //Ordered insertion multimap
150 std::multimap
<int, int> int_mmap
;
151 for(std::size_t i
= 0; i
!= NumElements
; ++i
){
152 int_mmap
.insert(std::multimap
<int, int>::value_type(static_cast<int>(i
), static_cast<int>(i
)));
154 //Construction insertion
155 flat_multimap
<int, int> fmmap(ordered_range
, int_mmap
.begin(), int_mmap
.end());
156 if(!CheckEqualContainers(int_mmap
, fmmap
))
158 //Insertion when empty
160 fmmap
.insert(ordered_range
, int_mmap
.begin(), int_mmap
.end());
161 if(!CheckEqualContainers(int_mmap
, fmmap
))
164 fmmap
.insert(ordered_range
, int_mmap
.begin(), int_mmap
.end());
165 std::multimap
<int, int> int_mmap2(int_mmap
);
166 int_mmap2
.insert(int_mmap
.begin(), int_mmap
.end());
167 if(!CheckEqualContainers(int_mmap2
, fmmap
))
170 fmmap
.insert(ordered_range
, int_mmap2
.begin(), int_mmap2
.end());
171 std::multimap
<int, int> int_mmap4(int_mmap2
);
172 int_mmap4
.insert(int_mmap2
.begin(), int_mmap2
.end());
173 if(!CheckEqualContainers(int_mmap4
, fmmap
))
175 //Re-re-insertion of even
176 std::multimap
<int, int> int_even_mmap
;
177 for(std::size_t i
= 0; i
< NumElements
; i
+=2){
178 int_mmap
.insert(std::multimap
<int, int>::value_type(static_cast<int>(i
), static_cast<int>(i
)));
180 fmmap
.insert(ordered_range
, int_even_mmap
.begin(), int_even_mmap
.end());
181 int_mmap4
.insert(int_even_mmap
.begin(), int_even_mmap
.end());
182 if(!CheckEqualContainers(int_mmap4
, fmmap
))
186 //Ordered insertion map
188 std::map
<int, int> int_map
;
189 for(std::size_t i
= 0; i
!= NumElements
; ++i
){
190 int_map
.insert(std::map
<int, int>::value_type(static_cast<int>(i
), static_cast<int>(i
)));
192 //Construction insertion
193 flat_map
<int, int> fmap(ordered_unique_range
, int_map
.begin(), int_map
.end());
194 if(!CheckEqualContainers(int_map
, fmap
))
196 //Insertion when empty
198 fmap
.insert(ordered_unique_range
, int_map
.begin(), int_map
.end());
199 if(!CheckEqualContainers(int_map
, fmap
))
202 fmap
.insert(ordered_unique_range
, int_map
.begin(), int_map
.end());
203 std::map
<int, int> int_map2(int_map
);
204 int_map2
.insert(int_map
.begin(), int_map
.end());
205 if(!CheckEqualContainers(int_map2
, fmap
))
208 fmap
.insert(ordered_unique_range
, int_map2
.begin(), int_map2
.end());
209 std::map
<int, int> int_map4(int_map2
);
210 int_map4
.insert(int_map2
.begin(), int_map2
.end());
211 if(!CheckEqualContainers(int_map4
, fmap
))
213 //Re-re-insertion of even
214 std::map
<int, int> int_even_map
;
215 for(std::size_t i
= 0; i
< NumElements
; i
+=2){
216 int_map
.insert(std::map
<int, int>::value_type(static_cast<int>(i
), static_cast<int>(i
)));
218 fmap
.insert(ordered_unique_range
, int_even_map
.begin(), int_even_map
.end());
219 int_map4
.insert(int_even_map
.begin(), int_even_map
.end());
220 if(!CheckEqualContainers(int_map4
, fmap
))
230 template<class VoidAllocator
>
231 struct GetAllocatorMap
233 template<class ValueType
>
236 typedef flat_map
< ValueType
238 , std::less
<ValueType
>
239 , typename allocator_traits
<VoidAllocator
>
240 ::template portable_rebind_alloc
< std::pair
<ValueType
, ValueType
> >::type
243 typedef flat_multimap
< ValueType
245 , std::less
<ValueType
>
246 , typename allocator_traits
<VoidAllocator
>
247 ::template portable_rebind_alloc
< std::pair
<ValueType
, ValueType
> >::type
252 struct boost_container_flat_map
;
253 struct boost_container_flat_multimap
;
255 namespace boost
{ namespace container
{ namespace test
{
258 struct alloc_propagate_base
<boost_container_flat_map
>
260 template <class T
, class Allocator
>
263 typedef typename
boost::container::allocator_traits
<Allocator
>::
264 template portable_rebind_alloc
<std::pair
<T
, T
> >::type TypeAllocator
;
265 typedef boost::container::flat_map
<T
, T
, std::less
<T
>, TypeAllocator
> type
;
270 struct alloc_propagate_base
<boost_container_flat_multimap
>
272 template <class T
, class Allocator
>
275 typedef typename
boost::container::allocator_traits
<Allocator
>::
276 template portable_rebind_alloc
<std::pair
<T
, T
> >::type TypeAllocator
;
277 typedef boost::container::flat_multimap
<T
, T
, std::less
<T
>, TypeAllocator
> type
;
281 template <class Key
, class T
, class Compare
, class Allocator
>
282 struct get_real_stored_allocator
<flat_map
<Key
, T
, Compare
, Allocator
> >
284 typedef typename flat_map
<Key
, T
, Compare
, Allocator
>::impl_stored_allocator_type type
;
287 template <class Key
, class T
, class Compare
, class Allocator
>
288 struct get_real_stored_allocator
<flat_multimap
<Key
, T
, Compare
, Allocator
> >
290 typedef typename flat_multimap
<Key
, T
, Compare
, Allocator
>::impl_stored_allocator_type type
;
293 }}} //namespace boost::container::test
295 template<class VoidAllocator
>
296 int test_map_variants()
298 typedef typename GetAllocatorMap
<VoidAllocator
>::template apply
<int>::map_type MyMap
;
299 typedef typename GetAllocatorMap
<VoidAllocator
>::template apply
<test::movable_int
>::map_type MyMoveMap
;
300 typedef typename GetAllocatorMap
<VoidAllocator
>::template apply
<test::movable_and_copyable_int
>::map_type MyCopyMoveMap
;
301 typedef typename GetAllocatorMap
<VoidAllocator
>::template apply
<test::copyable_int
>::map_type MyCopyMap
;
303 typedef typename GetAllocatorMap
<VoidAllocator
>::template apply
<int>::multimap_type MyMultiMap
;
304 typedef typename GetAllocatorMap
<VoidAllocator
>::template apply
<test::movable_int
>::multimap_type MyMoveMultiMap
;
305 typedef typename GetAllocatorMap
<VoidAllocator
>::template apply
<test::movable_and_copyable_int
>::multimap_type MyCopyMoveMultiMap
;
306 typedef typename GetAllocatorMap
<VoidAllocator
>::template apply
<test::copyable_int
>::multimap_type MyCopyMultiMap
;
308 typedef std::map
<int, int> MyStdMap
;
309 typedef std::multimap
<int, int> MyStdMultiMap
;
311 if (0 != test::map_test
<
316 std::cout
<< "Error in map_test<MyBoostMap>" << std::endl
;
320 if (0 != test::map_test
<
325 std::cout
<< "Error in map_test<MyBoostMap>" << std::endl
;
329 if (0 != test::map_test
<
334 std::cout
<< "Error in map_test<MyBoostMap>" << std::endl
;
338 if (0 != test::map_test
<
343 std::cout
<< "Error in map_test<MyBoostMap>" << std::endl
;
352 using namespace boost::container::test
;
354 //Allocator argument container
356 flat_map
<int, int> map_((flat_map
<int, int>::allocator_type()));
357 flat_multimap
<int, int> multimap_((flat_multimap
<int, int>::allocator_type()));
359 //Now test move semantics
361 test_move
<flat_map
<recursive_flat_map
, recursive_flat_map
> >();
362 test_move
<flat_multimap
<recursive_flat_multimap
, recursive_flat_multimap
> >();
364 //Now test nth/index_of
366 flat_map
<int, int> map
;
367 flat_multimap
<int, int> mmap
;
369 map
.insert(std::pair
<int, int>(0, 0));
370 map
.insert(std::pair
<int, int>(1, 0));
371 map
.insert(std::pair
<int, int>(2, 0));
372 mmap
.insert(std::pair
<int, int>(0, 0));
373 mmap
.insert(std::pair
<int, int>(1, 0));
374 mmap
.insert(std::pair
<int, int>(2, 0));
375 if(!boost::container::test::test_nth_index_of(map
))
377 if(!boost::container::test::test_nth_index_of(mmap
))
381 ////////////////////////////////////
382 // Ordered insertion test
383 ////////////////////////////////////
384 if(!flat_tree_ordered_insertion_test()){
388 ////////////////////////////////////
389 // Testing allocator implementations
390 ////////////////////////////////////
392 if(test_map_variants
< std::allocator
<void> >()){
393 std::cerr
<< "test_map_variants< std::allocator<void> > failed" << std::endl
;
396 // boost::container::allocator
397 if(test_map_variants
< allocator
<void> >()){
398 std::cerr
<< "test_map_variants< allocator<void> > failed" << std::endl
;
402 if(!boost::container::test::test_map_support_for_initialization_list_for
<flat_map
<int, int> >())
405 if (!boost::container::test::test_map_support_for_initialization_list_for
<flat_multimap
<int, int> >())
408 ////////////////////////////////////
410 ////////////////////////////////////
411 const test::EmplaceOptions MapOptions
= (test::EmplaceOptions
)(test::EMPLACE_HINT_PAIR
| test::EMPLACE_ASSOC_PAIR
);
413 if(!boost::container::test::test_emplace
<flat_map
<test::EmplaceInt
, test::EmplaceInt
>, MapOptions
>())
415 if(!boost::container::test::test_emplace
<flat_multimap
<test::EmplaceInt
, test::EmplaceInt
>, MapOptions
>())
418 ////////////////////////////////////
419 // Allocator propagation testing
420 ////////////////////////////////////
421 if(!boost::container::test::test_propagate_allocator
<boost_container_flat_map
>())
424 if(!boost::container::test::test_propagate_allocator
<boost_container_flat_multimap
>())
427 ////////////////////////////////////
429 ////////////////////////////////////
431 typedef boost::container::flat_map
<int, int> cont_int
;
432 cont_int a
; a
.insert(cont_int::value_type(0, 9)); a
.insert(cont_int::value_type(1, 9)); a
.insert(cont_int::value_type(2, 9));
433 boost::intrusive::test::test_iterator_random
< cont_int
>(a
);
434 if(boost::report_errors() != 0) {
439 typedef boost::container::flat_multimap
<int, int> cont_int
;
440 cont_int a
; a
.insert(cont_int::value_type(0, 9)); a
.insert(cont_int::value_type(1, 9)); a
.insert(cont_int::value_type(2, 9));
441 boost::intrusive::test::test_iterator_random
< cont_int
>(a
);
442 if(boost::report_errors() != 0) {
450 #include <boost/container/detail/config_end.hpp>