1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2011-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 //////////////////////////////////////////////////////////////////////////////
10 #include <boost/container/detail/config_begin.hpp>
13 #include <boost/move/utility_core.hpp>
14 #include <boost/container/vector.hpp>
15 #include <boost/container/deque.hpp>
16 #include <boost/container/list.hpp>
17 #include <boost/container/slist.hpp>
18 #include <boost/container/stable_vector.hpp>
19 #include <boost/container/small_vector.hpp>
20 #include <boost/container/flat_map.hpp>
21 #include <boost/container/flat_set.hpp>
22 #include <boost/container/map.hpp>
23 #include <boost/container/set.hpp>
24 #include <boost/container/detail/mpl.hpp>
26 #include <boost/container/scoped_allocator.hpp>
28 template <typename Ty
>
32 typedef Ty value_type
;
34 explicit SimpleAllocator(int value
)
39 SimpleAllocator(const SimpleAllocator
<T
> &other
)
40 : m_state(other
.m_state
)
43 Ty
* allocate(std::size_t n
)
45 return m_allocator
.allocate(n
);
48 void deallocate(Ty
* p
, std::size_t n
)
50 m_allocator
.deallocate(p
, n
);
58 std::allocator
<Ty
> m_allocator
;
60 template <typename T
> friend class SimpleAllocator
;
62 friend bool operator == (const SimpleAllocator
&, const SimpleAllocator
&)
65 friend bool operator != (const SimpleAllocator
&, const SimpleAllocator
&)
71 private: // Not copyable
73 BOOST_MOVABLE_BUT_NOT_COPYABLE(alloc_int
)
76 typedef SimpleAllocator
<int> allocator_type
;
78 alloc_int(BOOST_RV_REF(alloc_int
)other
)
79 : m_value(other
.m_value
), m_allocator(boost::move(other
.m_allocator
))
84 alloc_int(BOOST_RV_REF(alloc_int
)other
, const allocator_type
&allocator
)
85 : m_value(other
.m_value
), m_allocator(allocator
)
90 alloc_int(int value
, const allocator_type
&allocator
)
91 : m_value(value
), m_allocator(allocator
)
94 alloc_int
& operator=(BOOST_RV_REF(alloc_int
)other
)
96 other
.m_value
= other
.m_value
;
100 int get_allocator_state() const
101 { return m_allocator
.get_value(); }
103 int get_value() const
106 friend bool operator < (const alloc_int
&l
, const alloc_int
&r
)
107 { return l
.m_value
< r
.m_value
; }
109 friend bool operator == (const alloc_int
&l
, const alloc_int
&r
)
110 { return l
.m_value
== r
.m_value
; }
114 allocator_type m_allocator
;
117 using namespace ::boost::container
;
120 typedef scoped_allocator_adaptor
<SimpleAllocator
<alloc_int
> > AllocIntAllocator
;
123 typedef std::pair
<const alloc_int
, alloc_int
> MapNode
;
124 typedef scoped_allocator_adaptor
<SimpleAllocator
<MapNode
> > MapAllocator
;
125 typedef map
<alloc_int
, alloc_int
, std::less
<alloc_int
>, MapAllocator
> Map
;
126 typedef set
<alloc_int
, std::less
<alloc_int
>, AllocIntAllocator
> Set
;
127 typedef multimap
<alloc_int
, alloc_int
, std::less
<alloc_int
>, MapAllocator
> MultiMap
;
128 typedef multiset
<alloc_int
, std::less
<alloc_int
>, AllocIntAllocator
> MultiSet
;
130 //[multi]flat_map/set
131 typedef std::pair
<alloc_int
, alloc_int
> FlatMapNode
;
132 typedef scoped_allocator_adaptor
<SimpleAllocator
<FlatMapNode
> > FlatMapAllocator
;
133 typedef flat_map
<alloc_int
, alloc_int
, std::less
<alloc_int
>, FlatMapAllocator
> FlatMap
;
134 typedef flat_set
<alloc_int
, std::less
<alloc_int
>, AllocIntAllocator
> FlatSet
;
135 typedef flat_multimap
<alloc_int
, alloc_int
, std::less
<alloc_int
>, FlatMapAllocator
> FlatMultiMap
;
136 typedef flat_multiset
<alloc_int
, std::less
<alloc_int
>, AllocIntAllocator
> FlatMultiSet
;
138 //vector, deque, list, slist, stable_vector.
139 typedef vector
<alloc_int
, AllocIntAllocator
> Vector
;
140 typedef deque
<alloc_int
, AllocIntAllocator
> Deque
;
141 typedef list
<alloc_int
, AllocIntAllocator
> List
;
142 typedef slist
<alloc_int
, AllocIntAllocator
> Slist
;
143 typedef stable_vector
<alloc_int
, AllocIntAllocator
> StableVector
;
144 typedef small_vector
<alloc_int
, 9, AllocIntAllocator
> SmallVector
;
151 struct is_unique_assoc
153 static const bool value
= false;
156 template<class Key
, class T
, class Compare
, class Allocator
>
157 struct is_unique_assoc
< map
<Key
, T
, Compare
, Allocator
> >
159 static const bool value
= true;
162 template<class Key
, class T
, class Compare
, class Allocator
>
163 struct is_unique_assoc
< flat_map
<Key
, T
, Compare
, Allocator
> >
165 static const bool value
= true;
168 template<class Key
, class Compare
, class Allocator
>
169 struct is_unique_assoc
< set
<Key
, Compare
, Allocator
> >
171 static const bool value
= true;
174 template<class Key
, class Compare
, class Allocator
>
175 struct is_unique_assoc
< flat_set
<Key
, Compare
, Allocator
> >
177 static const bool value
= true;
188 static const bool value
= false;
191 template<class Key
, class T
, class Compare
, class Allocator
>
192 struct is_map
< map
<Key
, T
, Compare
, Allocator
> >
194 static const bool value
= true;
197 template<class Key
, class T
, class Compare
, class Allocator
>
198 struct is_map
< flat_map
<Key
, T
, Compare
, Allocator
> >
200 static const bool value
= true;
203 template<class Key
, class T
, class Compare
, class Allocator
>
204 struct is_map
< multimap
<Key
, T
, Compare
, Allocator
> >
206 static const bool value
= true;
209 template<class Key
, class T
, class Compare
, class Allocator
>
210 struct is_map
< flat_multimap
<Key
, T
, Compare
, Allocator
> >
212 static const bool value
= true;
218 static const bool value
= false;
221 template<class Key
, class Compare
, class Allocator
>
222 struct is_set
< set
<Key
, Compare
, Allocator
> >
224 static const bool value
= true;
227 template<class Key
, class Compare
, class Allocator
>
228 struct is_set
< flat_set
<Key
, Compare
, Allocator
> >
230 static const bool value
= true;
233 template<class Key
, class Compare
, class Allocator
>
234 struct is_set
< multiset
<Key
, Compare
, Allocator
> >
236 static const bool value
= true;
239 template<class Key
, class Compare
, class Allocator
>
240 struct is_set
< flat_multiset
<Key
, Compare
, Allocator
> >
242 static const bool value
= true;
249 //Try to define-allocator_aware requirements
250 template< class Container
251 , bool Assoc
= is_set
<Container
>::value
|| is_map
<Container
>::value
252 , bool UniqueAssoc
= is_unique_assoc
<Container
>::value
253 , bool Map
= is_map
<Container
>::value
255 struct container_wrapper_inserter
257 typedef typename
Container::const_iterator const_iterator
;
258 typedef typename
Container::iterator iterator
;
261 static iterator
emplace(Container
&c
, const_iterator p
, const Arg
&arg
)
262 { return c
.emplace(p
, arg
); }
265 template<class Container
> //map
266 struct container_wrapper_inserter
<Container
, true, true, true>
268 typedef typename
Container::const_iterator const_iterator
;
269 typedef typename
Container::iterator iterator
;
272 static iterator
emplace(Container
&c
, const_iterator
, const Arg
&arg
)
273 { return c
.emplace(arg
, arg
).first
; }
276 template<class Container
> //set
277 struct container_wrapper_inserter
<Container
, true, true, false>
279 typedef typename
Container::const_iterator const_iterator
;
280 typedef typename
Container::iterator iterator
;
283 static iterator
emplace(Container
&c
, const_iterator
, const Arg
&arg
)
284 { return c
.emplace(arg
).first
; }
287 template<class Container
> //multimap
288 struct container_wrapper_inserter
<Container
, true, false, true>
290 typedef typename
Container::const_iterator const_iterator
;
291 typedef typename
Container::iterator iterator
;
294 static iterator
emplace(Container
&c
, const_iterator
, const Arg
&arg
)
295 { return c
.emplace(arg
, arg
); }
299 template<class Container
> //multimap
300 struct container_wrapper_inserter
<Container
, true, false, false>
302 typedef typename
Container::const_iterator const_iterator
;
303 typedef typename
Container::iterator iterator
;
306 static iterator
emplace(Container
&c
, const_iterator
, const Arg
&arg
)
307 { return c
.emplace(arg
); }
310 template< class Container
>
311 struct container_wrapper
315 BOOST_COPYABLE_AND_MOVABLE(container_wrapper
)
318 typedef typename
Container::allocator_type allocator_type
;
319 typedef typename
Container::const_iterator const_iterator
;
320 typedef typename
Container::iterator iterator
;
322 container_wrapper(const allocator_type
&a
)
326 container_wrapper(BOOST_RV_REF(container_wrapper
) o
, const allocator_type
&a
)
327 : Container(BOOST_MOVE_BASE(Container
, o
), a
)
330 container_wrapper(const container_wrapper
&o
, const allocator_type
&a
)
335 iterator
emplace(const_iterator p
, const Arg
&arg
)
336 { return container_wrapper_inserter
<Container
>::emplace(*this, p
, arg
); }
340 bool test_value_and_state_equals(const alloc_int
&r
, int value
, int state
)
341 { return r
.get_value() == value
&& r
.get_allocator_state() == state
; }
343 template<class F
, class S
>
344 bool test_value_and_state_equals(const dtl::pair
<F
, S
> &p
, int value
, int state
)
345 { return test_value_and_state_equals(p
.first
, value
, state
) && test_alloc_state_equals(p
.second
, value
, state
); }
347 template<class F
, class S
>
348 bool test_value_and_state_equals(const std::pair
<F
, S
> &p
, int value
, int state
)
349 { return test_value_and_state_equals(p
.first
, value
, state
) && test_value_and_state_equals(p
.second
, value
, state
); }
351 template<class Container
>
352 bool one_level_allocator_propagation_test()
354 typedef container_wrapper
<Container
> ContainerWrapper
;
355 typedef typename
ContainerWrapper::iterator iterator
;
356 typedef typename
ContainerWrapper::allocator_type allocator_type
;
357 typedef typename
ContainerWrapper::value_type value_type
;
359 allocator_type
al(SimpleAllocator
<value_type
>(5));
360 ContainerWrapper
c(al
);
363 iterator it
= c
.emplace(c
.cbegin(), 42);
365 if(!test_value_and_state_equals(*it
, 42, 5))
369 allocator_type
al(SimpleAllocator
<value_type
>(4));
370 ContainerWrapper
c2(al
);
371 ContainerWrapper
c(::boost::move(c2
), allocator_type(SimpleAllocator
<value_type
>(5)));
374 iterator it
= c
.emplace(c
.cbegin(), 42);
376 if(!test_value_and_state_equals(*it
, 42, 5))
380 ContainerWrapper c2(allocator_type(SimpleAllocator<value_type>(3)));
381 ContainerWrapper c(c2, allocator_type(SimpleAllocator<value_type>(5)));
384 iterator it = c.emplace(c.cbegin(), 42);
386 if(!test_value_and_state_equals(*it, 42, 5))
395 if(!one_level_allocator_propagation_test
<FlatMap
>())
397 if(!one_level_allocator_propagation_test
<Map
>())
399 if(!one_level_allocator_propagation_test
<FlatSet
>())
401 if(!one_level_allocator_propagation_test
<Set
>())
404 if(!one_level_allocator_propagation_test
<FlatMultiMap
>())
406 if(!one_level_allocator_propagation_test
<MultiMap
>())
408 if(!one_level_allocator_propagation_test
<FlatMultiSet
>())
410 if(!one_level_allocator_propagation_test
<MultiSet
>())
412 //sequence containers
413 if(!one_level_allocator_propagation_test
<Vector
>())
415 if(!one_level_allocator_propagation_test
<Deque
>())
417 if(!one_level_allocator_propagation_test
<List
>())
419 if(!one_level_allocator_propagation_test
<Slist
>())
421 if(!one_level_allocator_propagation_test
<StableVector
>())
423 if(!one_level_allocator_propagation_test
<SmallVector
>())
428 #include <boost/container/detail/config_end.hpp>