Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/container/allocator_traits.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 ////////////////////////////////////////////////////////////////////////////// | |
2 // | |
3 // (C) Copyright Pablo Halpern 2009. 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 ////////////////////////////////////////////////////////////////////////////// | |
8 // | |
9 // (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost | |
10 // Software License, Version 1.0. (See accompanying file | |
11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
12 // | |
13 // See http://www.boost.org/libs/container for documentation. | |
14 // | |
15 ////////////////////////////////////////////////////////////////////////////// | |
16 | |
17 #ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP | |
18 #define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP | |
19 | |
20 #if defined(_MSC_VER) | |
21 # pragma once | |
22 #endif | |
23 | |
24 #include <boost/container/detail/config_begin.hpp> | |
25 #include <boost/container/detail/workaround.hpp> | |
26 #include <boost/container/container_fwd.hpp> | |
27 #include <boost/intrusive/pointer_traits.hpp> | |
28 #include <boost/intrusive/detail/memory_util.hpp> | |
29 #include <boost/container/detail/memory_util.hpp> | |
30 #include <boost/type_traits/integral_constant.hpp> | |
31 #include <boost/container/detail/mpl.hpp> | |
32 #include <boost/move/utility.hpp> | |
33 #include <limits> //numeric_limits<>::max() | |
34 #include <new> //placement new | |
35 #include <memory> //std::allocator | |
36 | |
37 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
38 #include <boost/container/detail/preprocessor.hpp> | |
39 #endif | |
40 | |
41 ///@cond | |
42 | |
43 namespace boost { | |
44 namespace container { | |
45 namespace container_detail { | |
46 | |
47 //workaround needed for C++03 compilers with no construct() | |
48 //supporting rvalue references | |
49 template<class A> | |
50 struct is_std_allocator | |
51 { static const bool value = false; }; | |
52 | |
53 template<class T> | |
54 struct is_std_allocator< std::allocator<T> > | |
55 { static const bool value = true; }; | |
56 | |
57 } //namespace container_detail { | |
58 | |
59 ///@endcond | |
60 | |
61 //! The class template allocator_traits supplies a uniform interface to all allocator types. | |
62 //! This class is a C++03-compatible implementation of std::allocator_traits | |
63 template <typename Alloc> | |
64 struct allocator_traits | |
65 { | |
66 //allocator_type | |
67 typedef Alloc allocator_type; | |
68 //value_type | |
69 typedef typename Alloc::value_type value_type; | |
70 | |
71 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
72 //! Alloc::pointer if such a type exists; otherwise, value_type* | |
73 //! | |
74 typedef unspecified pointer; | |
75 //! Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const | |
76 //! | |
77 typedef see_documentation const_pointer; | |
78 //! Non-standard extension | |
79 //! Alloc::reference if such a type exists; otherwise, value_type& | |
80 typedef see_documentation reference; | |
81 //! Non-standard extension | |
82 //! Alloc::const_reference if such a type exists ; otherwise, const value_type& | |
83 typedef see_documentation const_reference; | |
84 //! Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>. | |
85 //! | |
86 typedef see_documentation void_pointer; | |
87 //! Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const | |
88 //! | |
89 typedef see_documentation const_void_pointer; | |
90 //! Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type. | |
91 //! | |
92 typedef see_documentation difference_type; | |
93 //! Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type | |
94 //! | |
95 typedef see_documentation size_type; | |
96 //! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant | |
97 //! type with internal constant static member `value` == false. | |
98 typedef see_documentation propagate_on_container_copy_assignment; | |
99 //! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant | |
100 //! type with internal constant static member `value` == false. | |
101 typedef see_documentation propagate_on_container_move_assignment; | |
102 //! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant | |
103 //! type with internal constant static member `value` == false. | |
104 typedef see_documentation propagate_on_container_swap; | |
105 //! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args> | |
106 //! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or | |
107 //! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed. | |
108 //! | |
109 //! In C++03 compilers `rebind_alloc` is a struct derived from an allocator | |
110 //! deduced by previously detailed rules. | |
111 template <class T> using rebind_alloc = see_documentation; | |
112 | |
113 //! In C++03 compilers `rebind_traits` is a struct derived from | |
114 //! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is | |
115 //! the allocator deduced by rules explained in `rebind_alloc`. | |
116 template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >; | |
117 | |
118 //! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers. | |
119 //! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`. | |
120 template <class T> | |
121 struct portable_rebind_alloc | |
122 { typedef see_documentation type; }; | |
123 #else | |
124 //pointer | |
125 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, | |
126 pointer, value_type*) | |
127 pointer; | |
128 //const_pointer | |
129 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, | |
130 const_pointer, typename boost::intrusive::pointer_traits<pointer>::template | |
131 rebind_pointer<const value_type>) | |
132 const_pointer; | |
133 //reference | |
134 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, | |
135 reference, typename container_detail::unvoid<value_type>::type&) | |
136 reference; | |
137 //const_reference | |
138 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, | |
139 const_reference, const typename container_detail::unvoid<value_type>::type&) | |
140 const_reference; | |
141 //void_pointer | |
142 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, | |
143 void_pointer, typename boost::intrusive::pointer_traits<pointer>::template | |
144 rebind_pointer<void>) | |
145 void_pointer; | |
146 //const_void_pointer | |
147 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, | |
148 const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template | |
149 rebind_pointer<const void>) | |
150 const_void_pointer; | |
151 //difference_type | |
152 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, | |
153 difference_type, std::ptrdiff_t) | |
154 difference_type; | |
155 //size_type | |
156 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, | |
157 size_type, std::size_t) | |
158 size_type; | |
159 //propagate_on_container_copy_assignment | |
160 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, | |
161 propagate_on_container_copy_assignment, boost::false_type) | |
162 propagate_on_container_copy_assignment; | |
163 //propagate_on_container_move_assignment | |
164 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, | |
165 propagate_on_container_move_assignment, boost::false_type) | |
166 propagate_on_container_move_assignment; | |
167 //propagate_on_container_swap | |
168 typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, | |
169 propagate_on_container_swap, boost::false_type) | |
170 propagate_on_container_swap; | |
171 | |
172 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) | |
173 //C++11 | |
174 template <typename T> using rebind_alloc = typename boost::intrusive::detail::type_rebinder<Alloc, T>::type; | |
175 template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >; | |
176 #else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) | |
177 //Some workaround for C++03 or C++11 compilers with no template aliases | |
178 template <typename T> | |
179 struct rebind_alloc : boost::intrusive::detail::type_rebinder<Alloc,T>::type | |
180 { | |
181 typedef typename boost::intrusive::detail::type_rebinder<Alloc,T>::type Base; | |
182 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
183 template <typename... Args> | |
184 rebind_alloc(BOOST_FWD_REF(Args)... args) | |
185 : Base(boost::forward<Args>(args)...) | |
186 {} | |
187 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
188 #define BOOST_PP_LOCAL_MACRO(n) \ | |
189 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ | |
190 rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
191 : Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \ | |
192 {} \ | |
193 // | |
194 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) | |
195 #include BOOST_PP_LOCAL_ITERATE() | |
196 #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
197 }; | |
198 | |
199 template <typename T> | |
200 struct rebind_traits | |
201 : allocator_traits<typename boost::intrusive::detail::type_rebinder<Alloc, T>::type> | |
202 {}; | |
203 #endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) | |
204 template <class T> | |
205 struct portable_rebind_alloc | |
206 { typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; }; | |
207 #endif //BOOST_CONTAINER_DOXYGEN_INVOKED | |
208 | |
209 //! <b>Returns</b>: `a.allocate(n)` | |
210 //! | |
211 static pointer allocate(Alloc &a, size_type n) | |
212 { return a.allocate(n); } | |
213 | |
214 //! <b>Returns</b>: `a.deallocate(p, n)` | |
215 //! | |
216 //! <b>Throws</b>: Nothing | |
217 static void deallocate(Alloc &a, pointer p, size_type n) | |
218 { a.deallocate(p, n); } | |
219 | |
220 //! <b>Effects</b>: calls `a.allocate(n, p)` if that call is well-formed; | |
221 //! otherwise, invokes `a.allocate(n)` | |
222 static pointer allocate(Alloc &a, size_type n, const_void_pointer p) | |
223 { | |
224 const bool value = boost::container::container_detail:: | |
225 has_member_function_callable_with_allocate | |
226 <Alloc, const size_type, const const_void_pointer>::value; | |
227 ::boost::integral_constant<bool, value> flag; | |
228 return allocator_traits::priv_allocate(flag, a, n, p); | |
229 } | |
230 | |
231 //! <b>Effects</b>: calls `a.destroy(p)` if that call is well-formed; | |
232 //! otherwise, invokes `p->~T()`. | |
233 template<class T> | |
234 static void destroy(Alloc &a, T*p) | |
235 { | |
236 typedef T* destroy_pointer; | |
237 const bool value = boost::container::container_detail:: | |
238 has_member_function_callable_with_destroy | |
239 <Alloc, const destroy_pointer>::value; | |
240 ::boost::integral_constant<bool, value> flag; | |
241 allocator_traits::priv_destroy(flag, a, p); | |
242 } | |
243 | |
244 //! <b>Returns</b>: `a.max_size()` if that expression is well-formed; otherwise, | |
245 //! `numeric_limits<size_type>::max()`. | |
246 static size_type max_size(const Alloc &a) | |
247 { | |
248 const bool value = boost::container::container_detail:: | |
249 has_member_function_callable_with_max_size | |
250 <const Alloc>::value; | |
251 ::boost::integral_constant<bool, value> flag; | |
252 return allocator_traits::priv_max_size(flag, a); | |
253 } | |
254 | |
255 //! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed; | |
256 //! otherwise, a. | |
257 static | |
258 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
259 typename container_detail::if_c | |
260 < boost::container::container_detail:: | |
261 has_member_function_callable_with_select_on_container_copy_construction | |
262 <const Alloc>::value | |
263 , Alloc | |
264 , const Alloc & | |
265 >::type | |
266 #else | |
267 Alloc | |
268 #endif | |
269 select_on_container_copy_construction(const Alloc &a) | |
270 { | |
271 const bool value = boost::container::container_detail:: | |
272 has_member_function_callable_with_select_on_container_copy_construction | |
273 <const Alloc>::value; | |
274 ::boost::integral_constant<bool, value> flag; | |
275 return allocator_traits::priv_select_on_container_copy_construction(flag, a); | |
276 } | |
277 | |
278 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
279 //! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed; | |
280 //! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)` | |
281 template <class T, class ...Args> | |
282 static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args) | |
283 { | |
284 ::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag; | |
285 allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...); | |
286 } | |
287 #endif | |
288 ///@cond | |
289 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
290 private: | |
291 static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p) | |
292 { return a.allocate(n, p); } | |
293 | |
294 static pointer priv_allocate(boost::false_type, Alloc &a, size_type n, const_void_pointer) | |
295 { return allocator_traits::allocate(a, n); } | |
296 | |
297 template<class T> | |
298 static void priv_destroy(boost::true_type, Alloc &a, T* p) | |
299 { a.destroy(p); } | |
300 | |
301 template<class T> | |
302 static void priv_destroy(boost::false_type, Alloc &, T* p) | |
303 { p->~T(); (void)p; } | |
304 | |
305 static size_type priv_max_size(boost::true_type, const Alloc &a) | |
306 { return a.max_size(); } | |
307 | |
308 static size_type priv_max_size(boost::false_type, const Alloc &) | |
309 { return (std::numeric_limits<size_type>::max)(); } | |
310 | |
311 static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a) | |
312 { return a.select_on_container_copy_construction(); } | |
313 | |
314 static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a) | |
315 { return a; } | |
316 | |
317 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
318 template<class T, class ...Args> | |
319 static void priv_construct(boost::false_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args) | |
320 { | |
321 const bool value = boost::container::container_detail:: | |
322 has_member_function_callable_with_construct | |
323 < Alloc, T*, Args... >::value; | |
324 ::boost::integral_constant<bool, value> flag; | |
325 priv_construct_dispatch2(flag, a, p, ::boost::forward<Args>(args)...); | |
326 } | |
327 | |
328 template<class T, class ...Args> | |
329 static void priv_construct(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args) | |
330 { | |
331 priv_construct_dispatch2(boost::false_type(), a, p, ::boost::forward<Args>(args)...); | |
332 } | |
333 | |
334 template<class T, class ...Args> | |
335 static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args) | |
336 { a.construct( p, ::boost::forward<Args>(args)...); } | |
337 | |
338 template<class T, class ...Args> | |
339 static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, BOOST_FWD_REF(Args) ...args) | |
340 { ::new((void*)p) T(::boost::forward<Args>(args)...); } | |
341 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
342 public: | |
343 #define BOOST_PP_LOCAL_MACRO(n) \ | |
344 template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ | |
345 static void construct(Alloc &a, T *p \ | |
346 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ | |
347 { \ | |
348 ::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag; \ | |
349 allocator_traits::priv_construct(flag, a, p \ | |
350 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ | |
351 } \ | |
352 // | |
353 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) | |
354 #include BOOST_PP_LOCAL_ITERATE() | |
355 | |
356 private: | |
357 #define BOOST_PP_LOCAL_MACRO(n) \ | |
358 template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ | |
359 static void priv_construct(boost::false_type, Alloc &a, T *p \ | |
360 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \ | |
361 { \ | |
362 const bool value = \ | |
363 boost::container::container_detail::has_member_function_callable_with_construct \ | |
364 < Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value; \ | |
365 ::boost::integral_constant<bool, value> flag; \ | |
366 priv_construct_dispatch2(flag, a, p \ | |
367 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ | |
368 } \ | |
369 \ | |
370 template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ | |
371 static void priv_construct(boost::true_type, Alloc &a, T *p \ | |
372 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \ | |
373 { \ | |
374 priv_construct_dispatch2(boost::false_type(), a, p \ | |
375 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ | |
376 } \ | |
377 \ | |
378 template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ | |
379 static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p \ | |
380 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \ | |
381 { a.construct( p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); } \ | |
382 \ | |
383 template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ | |
384 static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p \ | |
385 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ | |
386 { ::new((void*)p) T(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ | |
387 // | |
388 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) | |
389 #include BOOST_PP_LOCAL_ITERATE() | |
390 #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
391 | |
392 template<class T> | |
393 static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, ::boost::container::default_init_t) | |
394 { ::new((void*)p) T; } | |
395 #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) | |
396 | |
397 ///@endcond | |
398 }; | |
399 | |
400 } //namespace container { | |
401 } //namespace boost { | |
402 | |
403 #include <boost/container/detail/config_end.hpp> | |
404 | |
405 #endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP) |