blob: 4d88ef9bd8c083675a68aa0f84390d216f8b0c05 [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
Jeff Thompson3d613fd2013-10-15 15:39:04 -070017#ifndef NDNBOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
18#define NDNBOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
Jeff Thompsona28eed82013-08-22 16:21:10 -070019
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.
Jeff Thompson3d613fd2013-10-15 15:39:04 -070056#define NDNBOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
Jeff Thompsona28eed82013-08-22 16:21:10 -070057 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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700100#define NDNBOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700101 typename INSTANTIATION_NS_PREFIX \
102 boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
103//
104
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700105#define NDNBOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700106 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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700114#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to
115#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace ndnboost { namespace intrusive { namespace detail {
116#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
117#define NDNBOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>))
118#include NDNBOOST_PP_ITERATE()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700119
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700120#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from
121#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace ndnboost { namespace intrusive { namespace detail {
122#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
123#define NDNBOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>))
124#include NDNBOOST_PP_ITERATE()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700125
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700126#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from
127#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace ndnboost { namespace intrusive { namespace detail {
128#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
129#define NDNBOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>))
130#include NDNBOOST_PP_ITERATE()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700131
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700132#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from
133#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace ndnboost { namespace intrusive { namespace detail {
134#define NDNBOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
135#define NDNBOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <ndnboost/intrusive/detail/has_member_function_callable_with.hpp>))
136#include NDNBOOST_PP_ITERATE()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700137
138namespace ndnboost {
139namespace intrusive {
140namespace detail {
141
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700142NDNBOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(element_type)
143NDNBOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700144
145//////////////////////
146//struct first_param
147//////////////////////
148
149template <typename T> struct first_param
150{ typedef void type; };
151
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700152#if !defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700153
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700162 #define NDNBOOST_PP_LOCAL_MACRO(n) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700163 template < template <typename \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700164 NDNBOOST_PP_ENUM_TRAILING(n, NDNBOOST_INTRUSIVE_PP_IDENTITY, typename) > \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700165 class TemplateClass \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700166 , typename T NDNBOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700167 struct first_param \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700168 < TemplateClass<T NDNBOOST_PP_ENUM_TRAILING_PARAMS(n, P)> > \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700169 { \
170 typedef T type; \
171 }; \
172 //
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700173 #define NDNBOOST_PP_LOCAL_LIMITS (0, NDNBOOST_INTRUSIVE_MAX_CONSTRUCTOR_PARAMETERS)
174 #include NDNBOOST_PP_LOCAL_ITERATE()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700175
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700176#endif //!defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700177
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.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700248#if !defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700249
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
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700265#define NDNBOOST_PP_LOCAL_MACRO(n) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700266template < template <typename \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700267 NDNBOOST_PP_ENUM_TRAILING(n, NDNBOOST_INTRUSIVE_PP_IDENTITY, typename) > \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700268 class Ptr \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700269 , typename T NDNBOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700270 , class U> \
271struct type_rebinder \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700272 < Ptr<T NDNBOOST_PP_ENUM_TRAILING_PARAMS(n, P)>, U, 0u > \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700273{ \
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700274 typedef Ptr<U NDNBOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
Jeff Thompsona28eed82013-08-22 16:21:10 -0700275}; \
276//
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700277#define NDNBOOST_PP_LOCAL_LIMITS (0, NDNBOOST_INTRUSIVE_MAX_CONSTRUCTOR_PARAMETERS)
278#include NDNBOOST_PP_LOCAL_ITERATE()
Jeff Thompsona28eed82013-08-22 16:21:10 -0700279
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700280#endif //!defined(NDNBOOST_NO_CXX11_VARIADIC_TEMPLATES)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700281
282} //namespace detail {
283} //namespace intrusive {
284} //namespace ndnboost {
285
286#include <ndnboost/intrusive/detail/config_end.hpp>
287
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700288#endif // ! defined(NDNBOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP)