hook_traits.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2006-2014
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/intrusive for documentation.
  10. //
  11. /////////////////////////////////////////////////////////////////////////////
  12. #ifndef BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP
  13. #define BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP
  14. #ifndef BOOST_CONFIG_HPP
  15. # include <boost/config.hpp>
  16. #endif
  17. #if defined(BOOST_HAS_PRAGMA_ONCE)
  18. # pragma once
  19. #endif
  20. #include <boost/intrusive/detail/workaround.hpp>
  21. #include <boost/intrusive/pointer_traits.hpp>
  22. #include <boost/intrusive/detail/parent_from_member.hpp>
  23. #include <boost/intrusive/link_mode.hpp>
  24. #include <boost/intrusive/detail/mpl.hpp>
  25. #include <boost/move/detail/to_raw_pointer.hpp>
  26. #include <boost/intrusive/detail/node_holder.hpp>
  27. namespace boost {
  28. namespace intrusive {
  29. template<class T, class NodePtr, class Tag, unsigned int Type>
  30. struct bhtraits_base
  31. {
  32. public:
  33. typedef NodePtr node_ptr;
  34. typedef typename pointer_traits<node_ptr>::element_type node;
  35. typedef node_holder<node, Tag, Type> node_holder_type;
  36. typedef T value_type;
  37. typedef typename pointer_traits<node_ptr>::
  38. template rebind_pointer<const node>::type const_node_ptr;
  39. typedef typename pointer_traits<node_ptr>::
  40. template rebind_pointer<T>::type pointer;
  41. typedef typename pointer_traits<node_ptr>::
  42. template rebind_pointer<const T>::type const_pointer;
  43. //typedef typename pointer_traits<pointer>::reference reference;
  44. //typedef typename pointer_traits<const_pointer>::reference const_reference;
  45. typedef T & reference;
  46. typedef const T & const_reference;
  47. typedef node_holder_type & node_holder_reference;
  48. typedef const node_holder_type & const_node_holder_reference;
  49. typedef node& node_reference;
  50. typedef const node & const_node_reference;
  51. BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n)
  52. {
  53. pointer p = pointer_traits<pointer>::pointer_to
  54. (static_cast<reference>(static_cast<node_holder_reference>(*n)));
  55. BOOST_ASSERT(!!p);
  56. return p;
  57. }
  58. BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n)
  59. {
  60. const_pointer p = pointer_traits<const_pointer>::pointer_to
  61. (static_cast<const_reference>(static_cast<const_node_holder_reference>(*n)));
  62. BOOST_ASSERT(!!p);
  63. return p;
  64. }
  65. BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value)
  66. {
  67. node_ptr p = pointer_traits<node_ptr>::pointer_to
  68. (static_cast<node_reference>(static_cast<node_holder_reference>(value)));
  69. BOOST_ASSERT(!!p);
  70. return p;
  71. }
  72. BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value)
  73. {
  74. const_node_ptr p = pointer_traits<const_node_ptr>::pointer_to
  75. (static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value)));
  76. BOOST_ASSERT(!!p);
  77. return p;
  78. }
  79. };
  80. template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, unsigned int Type>
  81. struct bhtraits
  82. : public bhtraits_base<T, typename NodeTraits::node_ptr, Tag, Type>
  83. {
  84. static const link_mode_type link_mode = LinkMode;
  85. typedef NodeTraits node_traits;
  86. };
  87. template<class T, class Hook, Hook T::* P>
  88. struct mhtraits
  89. {
  90. public:
  91. typedef Hook hook_type;
  92. typedef typename hook_type::hooktags::node_traits node_traits;
  93. typedef typename node_traits::node node;
  94. typedef T value_type;
  95. typedef typename node_traits::node_ptr node_ptr;
  96. typedef typename node_traits::const_node_ptr const_node_ptr;
  97. typedef typename pointer_traits<node_ptr>::
  98. template rebind_pointer<T>::type pointer;
  99. typedef typename pointer_traits<node_ptr>::
  100. template rebind_pointer<const T>::type const_pointer;
  101. typedef T & reference;
  102. typedef const T & const_reference;
  103. typedef node& node_reference;
  104. typedef const node & const_node_reference;
  105. typedef hook_type& hook_reference;
  106. typedef const hook_type & const_hook_reference;
  107. static const link_mode_type link_mode = Hook::hooktags::link_mode;
  108. BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value)
  109. {
  110. return pointer_traits<node_ptr>::pointer_to
  111. (static_cast<node_reference>(static_cast<hook_reference>(value.*P)));
  112. }
  113. BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value)
  114. {
  115. return pointer_traits<const_node_ptr>::pointer_to
  116. (static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P)));
  117. }
  118. BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n)
  119. {
  120. return pointer_traits<pointer>::pointer_to
  121. (*detail::parent_from_member<T, Hook>
  122. (static_cast<Hook*>(boost::movelib::to_raw_pointer(n)), P));
  123. }
  124. BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n)
  125. {
  126. return pointer_traits<const_pointer>::pointer_to
  127. (*detail::parent_from_member<T, Hook>
  128. (static_cast<const Hook*>(boost::movelib::to_raw_pointer(n)), P));
  129. }
  130. };
  131. template<class Functor>
  132. struct fhtraits
  133. {
  134. public:
  135. typedef typename Functor::hook_type hook_type;
  136. typedef typename Functor::hook_ptr hook_ptr;
  137. typedef typename Functor::const_hook_ptr const_hook_ptr;
  138. typedef typename hook_type::hooktags::node_traits node_traits;
  139. typedef typename node_traits::node node;
  140. typedef typename Functor::value_type value_type;
  141. typedef typename node_traits::node_ptr node_ptr;
  142. typedef typename node_traits::const_node_ptr const_node_ptr;
  143. typedef typename pointer_traits<node_ptr>::
  144. template rebind_pointer<value_type>::type pointer;
  145. typedef typename pointer_traits<node_ptr>::
  146. template rebind_pointer<const value_type>::type const_pointer;
  147. typedef value_type & reference;
  148. typedef const value_type & const_reference;
  149. static const link_mode_type link_mode = hook_type::hooktags::link_mode;
  150. static node_ptr to_node_ptr(reference value)
  151. { return static_cast<node*>(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); }
  152. static const_node_ptr to_node_ptr(const_reference value)
  153. { return static_cast<const node*>(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); }
  154. static pointer to_value_ptr(const node_ptr & n)
  155. { return Functor::to_value_ptr(to_hook_ptr(n)); }
  156. static const_pointer to_value_ptr(const const_node_ptr & n)
  157. { return Functor::to_value_ptr(to_hook_ptr(n)); }
  158. private:
  159. static hook_ptr to_hook_ptr(const node_ptr & n)
  160. { return hook_ptr(&*static_cast<hook_type*>(&*n)); }
  161. static const_hook_ptr to_hook_ptr(const const_node_ptr & n)
  162. { return const_hook_ptr(&*static_cast<const hook_type*>(&*n)); }
  163. };
  164. } //namespace intrusive
  165. } //namespace boost
  166. #endif //BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP