blob: 81cc105db77e6d91cb5d5af8876ee440e595efdb [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001//////////////////////////////////////////////////////////////////////////////
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/intrusive for documentation.
14//
15//////////////////////////////////////////////////////////////////////////////
16
17#ifndef BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
18#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
19
20#if (defined _MSC_VER) && (_MSC_VER >= 1200)
21# pragma once
22#endif
23
24#include <ndnboost/intrusive/detail/config_begin.hpp>
25#include <ndnboost/intrusive/detail/workaround.hpp>
26#include <ndnboost/intrusive/detail/mpl.hpp>
27#include <ndnboost/intrusive/detail/preprocessor.hpp>
28
29namespace ndnboost {
30namespace intrusive {
31namespace detail {
32
33template <typename T>
34inline T* addressof(T& obj)
35{
36 return static_cast<T*>
37 (static_cast<void*>
38 (const_cast<char*>
39 (&reinterpret_cast<const char&>(obj))
40 )
41 );
42}
43
44template <typename T> struct unvoid { typedef T type; };
45template <> struct unvoid<void> { struct type { }; };
46template <> struct unvoid<const void> { struct type { }; };
47
48template <typename T>
49struct LowPriorityConversion
50{
51 // Convertible from T with user-defined-conversion rank.
52 LowPriorityConversion(const T&) { }
53};
54
55// Infrastructure for providing a default type for T::TNAME if absent.
56#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
57 template <typename T, typename DefaultType> \
58 struct boost_intrusive_default_type_ ## TNAME \
59 { \
60 template <typename X> \
61 static char test(int, typename X::TNAME*); \
62 \
63 template <typename X> \
64 static int test(ndnboost::intrusive::detail:: \
65 LowPriorityConversion<int>, void*); \
66 \
67 struct DefaultWrap { typedef DefaultType TNAME; }; \
68 \
69 static const bool value = (1 == sizeof(test<T>(0, 0))); \
70 \
71 typedef typename \
72 ::ndnboost::intrusive::detail::if_c \
73 <value, T, DefaultWrap>::type::TNAME type; \
74 }; \
75 \
76 template <typename T, typename DefaultType> \
77 struct boost_intrusive_eval_default_type_ ## TNAME \
78 { \
79 template <typename X> \
80 static char test(int, typename X::TNAME*); \
81 \
82 template <typename X> \
83 static int test(ndnboost::intrusive::detail:: \
84 LowPriorityConversion<int>, void*); \
85 \
86 struct DefaultWrap \
87 { typedef typename DefaultType::type TNAME; }; \
88 \
89 static const bool value = (1 == sizeof(test<T>(0, 0))); \
90 \
91 typedef typename \
92 ::ndnboost::intrusive::detail::eval_if_c \
93 < value \
94 , ::ndnboost::intrusive::detail::identity<T> \
95 , ::ndnboost::intrusive::detail::identity<DefaultWrap> \
96 >::type::TNAME type; \
97 }; \
98//
99
100#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
101 typename INSTANTIATION_NS_PREFIX \
102 boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
103//
104
105#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
106 typename INSTANTIATION_NS_PREFIX \
107 boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \
108//
109
110}}} //namespace ndnboost::intrusive::detail
111
112#include <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>
113
114#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to
115#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace ndnboost { namespace intrusive { namespace detail {
116#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
117#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>))
118#include BOOST_PP_ITERATE()
119
120#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from
121#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace ndnboost { namespace intrusive { namespace detail {
122#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
123#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>))
124#include BOOST_PP_ITERATE()
125
126#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from
127#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace ndnboost { namespace intrusive { namespace detail {
128#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
129#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>))
130#include BOOST_PP_ITERATE()
131
132#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from
133#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace ndnboost { namespace intrusive { namespace detail {
134#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
135#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>))
136#include BOOST_PP_ITERATE()
137
138namespace ndnboost {
139namespace intrusive {
140namespace detail {
141
142BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(element_type)
143BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
144
145//////////////////////
146//struct first_param
147//////////////////////
148
149template <typename T> struct first_param
150{ typedef void type; };
151
152#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
153
154 template <template <typename, typename...> class TemplateClass, typename T, typename... Args>
155 struct first_param< TemplateClass<T, Args...> >
156 {
157 typedef T type;
158 };
159
160#else //C++03 compilers
161
162 #define BOOST_PP_LOCAL_MACRO(n) \
163 template < template <typename \
164 BOOST_PP_ENUM_TRAILING(n, BOOST_INTRUSIVE_PP_IDENTITY, typename) > \
165 class TemplateClass \
166 , typename T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> \
167 struct first_param \
168 < TemplateClass<T BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> > \
169 { \
170 typedef T type; \
171 }; \
172 //
173 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_INTRUSIVE_MAX_CONSTRUCTOR_PARAMETERS)
174 #include BOOST_PP_LOCAL_ITERATE()
175
176#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
177
178///////////////////////////
179//struct type_rebind_mode
180///////////////////////////
181template <typename Ptr, typename T>
182struct type_has_rebind
183{
184 template <typename X>
185 #if !defined (__SUNPRO_CC)
186 static char test(int, typename X::template rebind<T>*);
187 #else
188 static char test(int, typename X::rebind<T>*);
189 #endif
190
191 template <typename X>
192 static int test(ndnboost::intrusive::detail::LowPriorityConversion<int>, void*);
193
194 static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
195};
196
197template <typename Ptr, typename T>
198struct type_has_rebind_other
199{
200 template <typename X>
201 #if !defined (__SUNPRO_CC)
202 static char test(int, typename X::template rebind<T>::other*);
203 #else
204 static char test(int, typename X::rebind<T>::other*);
205 #endif
206
207 template <typename X>
208 static int test(ndnboost::intrusive::detail::LowPriorityConversion<int>, void*);
209
210 static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
211};
212
213template <typename Ptr, typename T>
214struct type_rebind_mode
215{
216 static const unsigned int rebind = (unsigned int)type_has_rebind<Ptr, T>::value;
217 static const unsigned int rebind_other = (unsigned int)type_has_rebind_other<Ptr, T>::value;
218 static const unsigned int mode = rebind + rebind*rebind_other;
219};
220
221////////////////////////
222//struct type_rebinder
223////////////////////////
224template <typename Ptr, typename U, unsigned int RebindMode = type_rebind_mode<Ptr, U>::mode>
225struct type_rebinder;
226
227// Implementation of pointer_traits<Ptr>::rebind if Ptr has
228// its own rebind::other type (C++03)
229template <typename Ptr, typename U>
230struct type_rebinder< Ptr, U, 2u >
231{
232 typedef typename Ptr::template rebind<U>::other type;
233};
234
235// Implementation of pointer_traits<Ptr>::rebind if Ptr has
236// its own rebind template.
237template <typename Ptr, typename U>
238struct type_rebinder< Ptr, U, 1u >
239{
240 typedef typename Ptr::template rebind<U> type;
241};
242
243// Specialization of pointer_traits<Ptr>::rebind if Ptr does not
244// have its own rebind template but has a the form Ptr<class T,
245// OtherArgs>, where OtherArgs comprises zero or more type parameters.
246// Many pointers fit this form, hence many pointers will get a
247// reasonable default for rebind.
248#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
249
250template <template <class, class...> class Ptr, typename T, class... Tn, class U>
251struct type_rebinder<Ptr<T, Tn...>, U, 0u >
252{
253 typedef Ptr<U, Tn...> type;
254};
255
256//Needed for non-conforming compilers like GCC 4.3
257template <template <class> class Ptr, typename T, class U>
258struct type_rebinder<Ptr<T>, U, 0u >
259{
260 typedef Ptr<U> type;
261};
262
263#else //C++03 compilers
264
265#define BOOST_PP_LOCAL_MACRO(n) \
266template < template <typename \
267 BOOST_PP_ENUM_TRAILING(n, BOOST_INTRUSIVE_PP_IDENTITY, typename) > \
268 class Ptr \
269 , typename T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \
270 , class U> \
271struct type_rebinder \
272 < Ptr<T BOOST_PP_ENUM_TRAILING_PARAMS(n, P)>, U, 0u > \
273{ \
274 typedef Ptr<U BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
275}; \
276//
277#define BOOST_PP_LOCAL_LIMITS (0, BOOST_INTRUSIVE_MAX_CONSTRUCTOR_PARAMETERS)
278#include BOOST_PP_LOCAL_ITERATE()
279
280#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
281
282} //namespace detail {
283} //namespace intrusive {
284} //namespace ndnboost {
285
286#include <ndnboost/intrusive/detail/config_end.hpp>
287
288#endif // ! defined(BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP)