]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/container/test/allocator_traits_test.cpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / container / test / allocator_traits_test.cpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
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)
6//
7// See http://www.boost.org/libs/container for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10#include <boost/container/detail/config_begin.hpp>
11#include <cstddef>
12#include <boost/container/allocator_traits.hpp>
13#include <boost/static_assert.hpp>
14#include <boost/container/detail/type_traits.hpp>
15#include <boost/container/detail/function_detector.hpp>
16#include <boost/move/utility_core.hpp>
17#include <memory>
18#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
19#include <boost/move/detail/fwd_macros.hpp>
20#endif
21#include <boost/core/lightweight_test.hpp>
22
23template<class T>
24class SimpleAllocator
25{
26 public:
27 bool allocate_called_;
28 bool deallocate_called_;
29
11fdf7f2 30 typedef boost::container::dtl::
7c673cae
FG
31 true_type is_always_equal;
32
33 typedef T value_type;
34
35 template <class U>
36 SimpleAllocator(SimpleAllocator<U>)
37 : allocate_called_(false)
38 , deallocate_called_(false)
39 {}
40
41 SimpleAllocator()
42 : allocate_called_(false)
43 , deallocate_called_(false)
44 {}
45
46 T* allocate(std::size_t)
47 { allocate_called_ = true; return 0; }
48
49 void deallocate(T*, std::size_t)
50 { deallocate_called_ = true; }
51
52 bool allocate_called() const
53 { return allocate_called_; }
54
55 bool deallocate_called() const
56 { return deallocate_called_; }
57
58 friend bool operator==(const SimpleAllocator &, const SimpleAllocator &)
59 { return true; }
60
61 friend bool operator!=(const SimpleAllocator &, const SimpleAllocator &)
62 { return false; }
63};
64
65template<class T>
66class SimpleSmartPtr
67{
68 void unspecified_bool_type_func() const {}
69 typedef void (SimpleSmartPtr::*unspecified_bool_type)() const;
70
71 public:
72
73 typedef T* pointer;
74
75 explicit SimpleSmartPtr(pointer p = 0)
76 : ptr_(p)
77 {}
78
79 SimpleSmartPtr(const SimpleSmartPtr &c)
80 { this->ptr_ = c.ptr_; }
81
82 SimpleSmartPtr & operator=(const SimpleSmartPtr &c)
83 { this->ptr_ = c.ptr_; }
84
85 operator unspecified_bool_type() const
86 { return ptr_? &SimpleSmartPtr::unspecified_bool_type_func : 0; }
87
88 private:
89 T *ptr_;
90};
91
92template<class T>
93class ComplexAllocator
94{
95 public:
96 bool allocate_called_;
97 bool deallocate_called_;
98 bool allocate_hint_called_;
99 bool destroy_called_;
100 mutable bool max_size_called_;
101 mutable bool select_on_container_copy_construction_called_;
102 bool construct_called_;
103 mutable bool storage_is_unpropagable_;
104
105 typedef T value_type;
106 typedef SimpleSmartPtr<T> pointer;
107 typedef SimpleSmartPtr<const T> const_pointer;
108 typedef typename ::boost::container::
11fdf7f2 109 dtl::unvoid_ref<T>::type reference;
7c673cae 110 typedef typename ::boost::container::
11fdf7f2 111 dtl::unvoid_ref<const T>::type const_reference;
7c673cae
FG
112 typedef SimpleSmartPtr<void> void_pointer;
113 typedef SimpleSmartPtr<const void> const_void_pointer;
114 typedef signed short difference_type;
115 typedef unsigned short size_type;
11fdf7f2 116 typedef boost::container::dtl::
7c673cae 117 true_type propagate_on_container_copy_assignment;
11fdf7f2 118 typedef boost::container::dtl::
7c673cae 119 true_type propagate_on_container_move_assignment;
11fdf7f2 120 typedef boost::container::dtl::
7c673cae 121 true_type propagate_on_container_swap;
11fdf7f2 122 typedef boost::container::dtl::
7c673cae
FG
123 true_type is_partially_propagable;
124
125 ComplexAllocator()
126 : allocate_called_(false)
127 , deallocate_called_(false)
128 , allocate_hint_called_(false)
129 , destroy_called_(false)
130 , max_size_called_(false)
131 , select_on_container_copy_construction_called_(false)
132 , construct_called_(false)
133 {}
134
135 pointer allocate(size_type)
136 { allocate_called_ = true; return pointer(); }
137
138 void deallocate(pointer, size_type)
139 { deallocate_called_ = true; }
140
141 //optional
142 ComplexAllocator select_on_container_copy_construction() const
143 { select_on_container_copy_construction_called_ = true; return *this; }
144
145 pointer allocate(size_type n, const const_void_pointer &)
146 { allocate_hint_called_ = true; return allocate(n); }
147
148 template<class U>
149 void destroy(U*)
150 { destroy_called_ = true; }
151
152 size_type max_size() const
153 { max_size_called_ = true; return size_type(size_type(0)-1); }
154
155 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
156
157 #define BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL(N)\
158 \
159 template< class U BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
160 void construct(U *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
161 { construct_called_ = true; ::new(p) U ( BOOST_MOVE_FWD##N ); }\
162 //
163 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL)
164 #undef BOOST_CONTAINER_COMPLEXALLOCATOR_CONSTRUCT_IMPL
165 #else
166
167 template< class U, class ...Args>
168 void construct(U *p, BOOST_FWD_REF(Args) ...args)
169 { construct_called_ = true; ::new(p) U( ::boost::forward<Args>(args)...); }
170
171 #endif
172
173 template<class U>
174 void construct(U *p, boost::container::default_init_t)
175 { construct_called_ = true; ::new(p)U; }
176
177 bool storage_is_unpropagable(pointer p) const
178 { storage_is_unpropagable_ = true; return !p; }
179
180 //getters
181 bool allocate_called() const
182 { return allocate_called_; }
183
184 bool deallocate_called() const
185 { return deallocate_called_; }
186
187 bool allocate_hint_called() const
188 { return allocate_hint_called_; }
189
190 bool destroy_called() const
191 { return destroy_called_; }
192
193 bool max_size_called() const
194 { return max_size_called_; }
195
196 bool select_on_container_copy_construction_called() const
197 { return select_on_container_copy_construction_called_; }
198
199 bool construct_called() const
200 { return construct_called_; }
201
202 bool storage_is_unpropagable_called() const
203 { return storage_is_unpropagable_; }
204};
205
206class copymovable
207{
208 BOOST_COPYABLE_AND_MOVABLE(copymovable)
209
210 public:
211
212 bool copymoveconstructed_;
213 bool moved_;
214
215 copymovable(int, int, int)
216 : copymoveconstructed_(false), moved_(false)
217 {}
218
219 copymovable()
220 : copymoveconstructed_(false), moved_(false)
221 {}
222
223 copymovable(const copymovable &)
224 : copymoveconstructed_(true), moved_(false)
225 {}
226
227 copymovable(BOOST_RV_REF(copymovable))
228 : copymoveconstructed_(true), moved_(true)
229 {}
230
231 copymovable & operator=(BOOST_COPY_ASSIGN_REF(copymovable) ){ return *this; }
232 copymovable & operator=(BOOST_RV_REF(copymovable) ){ return *this; }
233
234 bool copymoveconstructed() const
235 { return copymoveconstructed_; }
236
237 bool moved() const
238 { return moved_; }
239};
240
241void test_void_allocator()
242{
243 boost::container::allocator_traits<std::allocator<void> > stdtraits; (void)stdtraits;
244 boost::container::allocator_traits<SimpleAllocator<void> > simtraits; (void)simtraits;
245 boost::container::allocator_traits<ComplexAllocator<void> > comtraits; (void)comtraits;
246}
247
248int main()
249{
11fdf7f2 250 using namespace boost::container::dtl;
7c673cae
FG
251 test_void_allocator();
252
253 //SimpleAllocator
254 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
255 < SimpleAllocator<int> >::value_type, int>::value ));
256 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
257 < SimpleAllocator<int> >::pointer, int*>::value ));
258 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
259 < SimpleAllocator<int> >::const_pointer, const int*>::value ));
260 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
261 < SimpleAllocator<int> >::void_pointer, void*>::value ));
262 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
263 < SimpleAllocator<int> >::const_void_pointer, const void*>::value ));
264 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
265 < SimpleAllocator<int> >::difference_type, std::ptrdiff_t>::value ));
266 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
267 < SimpleAllocator<int> >::size_type, std::size_t>::value ));
268 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
269 < SimpleAllocator<int> >::propagate_on_container_copy_assignment::value == false ));
270 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
271 < SimpleAllocator<int> >::propagate_on_container_move_assignment::value == false ));
272 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
273 < SimpleAllocator<int> >::propagate_on_container_swap::value == false ));
274 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
275 < SimpleAllocator<int> >::is_always_equal::value == true ));
276 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
277 < SimpleAllocator<int> >::is_partially_propagable::value == false ));
278 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
279 < SimpleAllocator<int> >::rebind_traits<double>::allocator_type
280 , SimpleAllocator<double> >::value ));
281 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
282 < SimpleAllocator<int> >::rebind_alloc<double>::value_type
283 , double >::value ));
284
285 //ComplexAllocator
286 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
287 < ComplexAllocator<int> >::value_type, int>::value ));
288 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
289 < ComplexAllocator<int> >::pointer, SimpleSmartPtr<int> >::value ));
290 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
291 < ComplexAllocator<int> >::const_pointer, SimpleSmartPtr<const int> >::value ));
292 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
293 < ComplexAllocator<int> >::void_pointer, SimpleSmartPtr<void> >::value ));
294 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
295 < ComplexAllocator<int> >::const_void_pointer, SimpleSmartPtr<const void> >::value ));
296 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
297 < ComplexAllocator<int> >::difference_type, signed short>::value ));
298 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
299 < ComplexAllocator<int> >::size_type, unsigned short>::value ));
300 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
301 < ComplexAllocator<int> >::propagate_on_container_copy_assignment::value == true ));
302 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
303 < ComplexAllocator<int> >::propagate_on_container_move_assignment::value == true ));
304 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
305 < ComplexAllocator<int> >::propagate_on_container_swap::value == true ));
306 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
307 < ComplexAllocator<int> >::is_always_equal::value == false ));
308 BOOST_STATIC_ASSERT(( boost::container::allocator_traits
309 < ComplexAllocator<int> >::is_partially_propagable::value == true ));
310 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
311 < ComplexAllocator<int> >::rebind_traits<double>::allocator_type
312 , ComplexAllocator<double> >::value ));
313 BOOST_STATIC_ASSERT(( is_same<boost::container::allocator_traits
314 < ComplexAllocator<int> >::rebind_alloc<double>::value_type
315 , double >::value ));
316
317 typedef ComplexAllocator<int> CAlloc;
318 typedef SimpleAllocator<int> SAlloc;
319 typedef boost::container::allocator_traits<CAlloc> CAllocTraits;
320 typedef boost::container::allocator_traits<SAlloc> SAllocTraits;
321 CAlloc c_alloc;
322 SAlloc s_alloc;
323
324 //allocate
325 CAllocTraits::allocate(c_alloc, 1);
326 BOOST_TEST(c_alloc.allocate_called());
327
328 SAllocTraits::allocate(s_alloc, 1);
329 BOOST_TEST(s_alloc.allocate_called());
330
331 //deallocate
332 CAllocTraits::deallocate(c_alloc, CAllocTraits::pointer(), 1);
333 BOOST_TEST(c_alloc.deallocate_called());
334
335 SAllocTraits::deallocate(s_alloc, SAllocTraits::pointer(), 1);
336 BOOST_TEST(s_alloc.deallocate_called());
337
338 //allocate with hint
339 CAllocTraits::allocate(c_alloc, 1, CAllocTraits::const_void_pointer());
340 BOOST_TEST(c_alloc.allocate_hint_called());
341
342 s_alloc.allocate_called_ = false;
343 SAllocTraits::allocate(s_alloc, 1, SAllocTraits::const_void_pointer());
344 BOOST_TEST(s_alloc.allocate_called());
345
346 //destroy
347 float dummy;
348 CAllocTraits::destroy(c_alloc, &dummy);
349 BOOST_TEST(c_alloc.destroy_called());
350
351 SAllocTraits::destroy(s_alloc, &dummy);
352
353 //max_size
354 CAllocTraits::max_size(c_alloc);
355 BOOST_TEST(c_alloc.max_size_called());
356
357 BOOST_TEST(SAllocTraits::size_type(-1)/sizeof(SAllocTraits::value_type) == SAllocTraits::max_size(s_alloc));
358
359 //select_on_container_copy_construction
360 CAllocTraits::select_on_container_copy_construction(c_alloc);
361 BOOST_TEST(c_alloc.select_on_container_copy_construction_called());
362
363 SAllocTraits::select_on_container_copy_construction(s_alloc);
364
365 //construct
366 {
367 copymovable c;
368 c.copymoveconstructed_ = true;
369 c.copymoveconstructed_ = true;
370 CAllocTraits::construct(c_alloc, &c);
371 BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved());
372 }
373 {
374 int i = 5;
375 CAllocTraits::construct(c_alloc, &i, boost::container::default_init);
376 BOOST_TEST(c_alloc.construct_called() && i == 5);
377 }
378 {
379 copymovable c;
380 copymovable c2;
381 CAllocTraits::construct(c_alloc, &c, c2);
382 BOOST_TEST(c_alloc.construct_called() && c.copymoveconstructed() && !c.moved());
383 }
384 {
385 copymovable c;
386 copymovable c2;
387 CAllocTraits::construct(c_alloc, &c, ::boost::move(c2));
388 BOOST_TEST(c_alloc.construct_called() && c.copymoveconstructed() && c.moved());
389 }
390 {
391 copymovable c;
392 c.copymoveconstructed_ = true;
393 c.copymoveconstructed_ = true;
394 SAllocTraits::construct(s_alloc, &c);
395 BOOST_TEST(!c.copymoveconstructed() && !c.moved());
396 }
397 {
398 int i = 4;
399 SAllocTraits::construct(s_alloc, &i, boost::container::default_init);
400 BOOST_TEST(i == 4);
401 }
402 {
403 copymovable c;
404 copymovable c2;
405 SAllocTraits::construct(s_alloc, &c, c2);
406 BOOST_TEST(c.copymoveconstructed() && !c.moved());
407 }
408 {
409 copymovable c;
410 copymovable c2;
411 SAllocTraits::construct(s_alloc, &c, ::boost::move(c2));
412 BOOST_TEST(c.copymoveconstructed() && c.moved());
413 }
414 {
415 copymovable c;
416 CAllocTraits::construct(c_alloc, &c, 0, 1, 2);
417 BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved());
418 }
419 {
420 copymovable c;
421 copymovable c2;
422 SAllocTraits::construct(s_alloc, &c, 0, 1, 2);
423 BOOST_TEST(!c.copymoveconstructed() && !c.moved());
424 }
425 //storage_is_unpropagable
426 {
427 SAlloc s_alloc2;
428 BOOST_TEST(!SAllocTraits::storage_is_unpropagable(s_alloc, SAllocTraits::pointer()));
429 }
430 {
431 {
432 CAlloc c_alloc2;
433 CAlloc::value_type v;
434 BOOST_TEST(!CAllocTraits::storage_is_unpropagable(c_alloc, CAllocTraits::pointer(&v)));
435 BOOST_TEST(c_alloc.storage_is_unpropagable_called());
436 }
437 {
438 CAlloc c_alloc2;
439 BOOST_TEST( CAllocTraits::storage_is_unpropagable(c_alloc2, CAllocTraits::pointer()));
440 BOOST_TEST(c_alloc2.storage_is_unpropagable_called());
441 }
442
443 }
444
445 return ::boost::report_errors();
446}
447#include <boost/container/detail/config_end.hpp>