1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2011-2012. 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>
12 #include <boost/container/allocator_traits.hpp>
13 #include <boost/static_assert.hpp>
14 #include <boost/type_traits/is_same.hpp>
15 #include <boost/type_traits/integral_constant.hpp>
16 #include <boost/container/detail/function_detector.hpp>
17 #include <boost/move/move.hpp>
23 bool allocate_called_;
24 bool deallocate_called_;
29 : allocate_called_(false)
30 , deallocate_called_(false)
33 T* allocate(std::size_t)
34 { allocate_called_ = true; return 0; }
36 void deallocate(T*, std::size_t)
37 { deallocate_called_ = true; }
39 bool allocate_called() const
40 { return allocate_called_; }
42 bool deallocate_called() const
43 { return deallocate_called_; }
55 SimpleSmartPtr(const SimpleSmartPtr &c)
56 { this->ptr_ = c.ptr_; }
58 SimpleSmartPtr & operator=(const SimpleSmartPtr &c)
59 { this->ptr_ = c.ptr_; }
68 class ComplexAllocator
70 bool allocate_called_;
71 bool deallocate_called_;
72 bool allocate_hint_called_;
74 mutable bool max_size_called_;
75 mutable bool select_on_container_copy_construction_called_;
76 bool construct_called_;
80 typedef SimpleSmartPtr<T> pointer;
81 typedef SimpleSmartPtr<const T> const_pointer;
82 typedef typename boost::container::
83 container_detail::unvoid<T>::type & reference;
84 typedef const typename boost::container::
85 container_detail::unvoid<T>::type & const_reference;
86 typedef SimpleSmartPtr<void> void_pointer;
87 typedef SimpleSmartPtr<const void> const_void_pointer;
88 typedef signed short difference_type;
89 typedef unsigned short size_type;
90 typedef boost::true_type propagate_on_container_copy_assignment;
91 typedef boost::true_type propagate_on_container_move_assignment;
92 typedef boost::true_type propagate_on_container_swap;
95 : allocate_called_(false)
96 , deallocate_called_(false)
97 , allocate_hint_called_(false)
98 , destroy_called_(false)
99 , max_size_called_(false)
100 , select_on_container_copy_construction_called_(false)
101 , construct_called_(false)
104 pointer allocate(size_type)
105 { allocate_called_ = true; return pointer(); }
107 void deallocate(pointer, size_type)
108 { deallocate_called_ = true; }
111 ComplexAllocator select_on_container_copy_construction() const
112 { select_on_container_copy_construction_called_ = true; return *this; }
114 pointer allocate(size_type n, const const_void_pointer &)
115 { allocate_hint_called_ = true; return allocate(n); }
119 { destroy_called_ = true; }
121 size_type max_size() const
122 { max_size_called_ = true; return size_type(size_type(0)-1); }
124 #define BOOST_PP_LOCAL_MACRO(n) \
125 template<class U BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
126 void construct(U *p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
128 construct_called_ = true; \
129 ::new (p) U (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
132 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
133 #include BOOST_PP_LOCAL_ITERATE()
136 bool allocate_called() const
137 { return allocate_called_; }
139 bool deallocate_called() const
140 { return deallocate_called_; }
142 bool allocate_hint_called() const
143 { return allocate_hint_called_; }
145 bool destroy_called() const
146 { return destroy_called_; }
148 bool max_size_called() const
149 { return max_size_called_; }
151 bool select_on_container_copy_construction_called() const
152 { return select_on_container_copy_construction_called_; }
154 bool construct_called() const
155 { return construct_called_; }
160 bool copymoveconstructed_;
163 BOOST_COPYABLE_AND_MOVABLE(copymovable)
167 copymovable(int, int, int)
168 : copymoveconstructed_(false), moved_(false)
172 : copymoveconstructed_(false), moved_(false)
175 copymovable(const copymovable &)
176 : copymoveconstructed_(true), moved_(false)
179 copymovable(BOOST_RV_REF(copymovable))
180 : copymoveconstructed_(true), moved_(true)
183 copymovable & operator=(BOOST_COPY_ASSIGN_REF(copymovable) ){ return *this; }
184 copymovable & operator=(BOOST_RV_REF(copymovable) ){ return *this; }
186 bool copymoveconstructed() const
187 { return copymoveconstructed_; }
193 void test_void_allocator()
195 boost::container::allocator_traits<std::allocator<void> > stdtraits; (void)stdtraits;
196 boost::container::allocator_traits<SimpleAllocator<void> > simtraits; (void)simtraits;
197 boost::container::allocator_traits<ComplexAllocator<void> > comtraits; (void)comtraits;
202 test_void_allocator();
205 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
206 < SimpleAllocator<int> >::value_type, int>::value ));
207 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
208 < SimpleAllocator<int> >::pointer, int*>::value ));
209 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
210 < SimpleAllocator<int> >::const_pointer, const int*>::value ));
211 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
212 < SimpleAllocator<int> >::void_pointer, void*>::value ));
213 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
214 < SimpleAllocator<int> >::const_void_pointer, const void*>::value ));
215 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
216 < SimpleAllocator<int> >::difference_type, std::ptrdiff_t>::value ));
217 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
218 < SimpleAllocator<int> >::size_type, std::size_t>::value ));
219 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
220 < SimpleAllocator<int> >::propagate_on_container_copy_assignment::value == false ));
221 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
222 < SimpleAllocator<int> >::propagate_on_container_move_assignment::value == false ));
223 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
224 < SimpleAllocator<int> >::propagate_on_container_swap::value == false ));
225 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
226 < SimpleAllocator<int> >::rebind_traits<double>::allocator_type
227 , SimpleAllocator<double> >::value ));
228 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
229 < SimpleAllocator<int> >::rebind_alloc<double>::value_type
230 , double >::value ));
233 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
234 < ComplexAllocator<int> >::value_type, int>::value ));
235 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
236 < ComplexAllocator<int> >::pointer, SimpleSmartPtr<int> >::value ));
237 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
238 < ComplexAllocator<int> >::const_pointer, SimpleSmartPtr<const int> >::value ));
239 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
240 < ComplexAllocator<int> >::void_pointer, SimpleSmartPtr<void> >::value ));
241 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
242 < ComplexAllocator<int> >::const_void_pointer, SimpleSmartPtr<const void> >::value ));
243 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
244 < ComplexAllocator<int> >::difference_type, signed short>::value ));
245 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
246 < ComplexAllocator<int> >::size_type, unsigned short>::value ));
247 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
248 < ComplexAllocator<int> >::propagate_on_container_copy_assignment::value == true ));
249 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
250 < ComplexAllocator<int> >::propagate_on_container_move_assignment::value == true ));
251 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
252 < ComplexAllocator<int> >::propagate_on_container_swap::value == true ));
253 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
254 < ComplexAllocator<int> >::rebind_traits<double>::allocator_type
255 , ComplexAllocator<double> >::value ));
256 BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
257 < ComplexAllocator<int> >::rebind_alloc<double>::value_type
258 , double >::value ));
260 typedef ComplexAllocator<int> CAlloc;
261 typedef SimpleAllocator<int> SAlloc;
262 typedef boost::container::allocator_traits<CAlloc> CAllocTraits;
263 typedef boost::container::allocator_traits<SAlloc> SAllocTraits;
268 CAllocTraits::allocate(c_alloc, 1);
269 if(!c_alloc.allocate_called()){
272 SAllocTraits::allocate(s_alloc, 1);
273 if(!s_alloc.allocate_called()){
278 CAllocTraits::deallocate(c_alloc, CAllocTraits::pointer(), 1);
279 if(!c_alloc.deallocate_called()){
282 SAllocTraits::deallocate(s_alloc, SAllocTraits::pointer(), 1);
283 if(!s_alloc.deallocate_called()){
288 CAllocTraits::allocate(c_alloc, 1, CAllocTraits::const_void_pointer());
289 if(!c_alloc.allocate_hint_called()){
292 SAllocTraits::allocate(s_alloc, 1, SAllocTraits::const_void_pointer());
296 CAllocTraits::destroy(c_alloc, &dummy);
297 if(!c_alloc.destroy_called()){
300 SAllocTraits::destroy(s_alloc, &dummy);
303 CAllocTraits::max_size(c_alloc);
304 if(!c_alloc.max_size_called()){
307 SAllocTraits::max_size(s_alloc);
309 //select_on_container_copy_construction
310 CAllocTraits::select_on_container_copy_construction(c_alloc);
311 if(!c_alloc.select_on_container_copy_construction_called()){
314 SAllocTraits::select_on_container_copy_construction(s_alloc);
320 CAllocTraits::construct(c_alloc, &c, c2);
321 if(!c_alloc.construct_called() || !c.copymoveconstructed() || c.moved()){
328 CAllocTraits::construct(c_alloc, &c, ::boost::move(c2));
329 if(!c_alloc.construct_called() || !c.copymoveconstructed() || !c.moved()){
336 SAllocTraits::construct(s_alloc, &c, c2);
337 if(!c.copymoveconstructed() || c.moved()){
344 SAllocTraits::construct(s_alloc, &c, ::boost::move(c2));
345 if(!c.copymoveconstructed() || !c.moved()){
351 CAllocTraits::construct(c_alloc, &c, 0, 1, 2);
352 if(!c_alloc.construct_called() || c.copymoveconstructed() || c.moved()){
359 SAllocTraits::construct(s_alloc, &c, 0, 1, 2);
360 if(c.copymoveconstructed() || c.moved()){
367 #include <boost/container/detail/config_end.hpp>