memory_util.hpp 13 KB

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