get_value_traits.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2014-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_GET_VALUE_TRAITS_HPP
  13. #define BOOST_INTRUSIVE_DETAIL_GET_VALUE_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/config_begin.hpp>
  21. #include <boost/intrusive/detail/mpl.hpp>
  22. #include <boost/intrusive/detail/hook_traits.hpp>
  23. namespace boost {
  24. namespace intrusive {
  25. #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
  26. template<class SupposedValueTraits>
  27. struct is_default_hook_tag
  28. { static const bool value = false; };
  29. namespace detail{
  30. template <class T, class BaseHook>
  31. struct concrete_hook_base_value_traits
  32. {
  33. typedef typename BaseHook::hooktags tags;
  34. typedef bhtraits
  35. < T
  36. , typename tags::node_traits
  37. , tags::link_mode
  38. , typename tags::tag
  39. , tags::type> type;
  40. };
  41. template <class BaseHook>
  42. struct concrete_hook_base_value_traits<void, BaseHook>
  43. {
  44. typedef typename BaseHook::hooktags type;
  45. };
  46. template <class T, class AnyToSomeHook_ProtoValueTraits>
  47. struct any_hook_base_value_traits
  48. {
  49. //AnyToSomeHook value_traits derive from a generic_hook
  50. //The generic_hook is configured with any_node_traits
  51. //and AnyToSomeHook::value_traits with the correct
  52. //node traits for the container, so use node_traits
  53. //from AnyToSomeHook_ProtoValueTraits and the rest of
  54. //elements from the hooktags member of the generic_hook
  55. typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
  56. typedef typename pointer_rebind
  57. < typename basic_hook_t::hooktags::node_traits::node_ptr
  58. , void>::type void_pointer;
  59. typedef typename AnyToSomeHook_ProtoValueTraits::template
  60. node_traits_from_voidptr<void_pointer>::type node_traits;
  61. typedef bhtraits
  62. < T
  63. , node_traits
  64. , basic_hook_t::hooktags::link_mode
  65. , typename basic_hook_t::hooktags::tag
  66. , basic_hook_t::hooktags::type
  67. > type;
  68. };
  69. template <class AnyToSomeHook_ProtoValueTraits>
  70. struct any_hook_base_value_traits<void, AnyToSomeHook_ProtoValueTraits>
  71. {
  72. typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
  73. typedef typename pointer_rebind
  74. < typename basic_hook_t::hooktags::node_traits::node_ptr
  75. , void>::type void_pointer;
  76. struct type
  77. {
  78. typedef typename AnyToSomeHook_ProtoValueTraits::template
  79. node_traits_from_voidptr<void_pointer>::type node_traits;
  80. };
  81. };
  82. template<class MemberHook>
  83. struct get_member_value_traits
  84. {
  85. typedef typename MemberHook::member_value_traits type;
  86. };
  87. BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook)
  88. BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook)
  89. template <class T>
  90. struct internal_member_value_traits
  91. {
  92. template <class U> static yes_type test(...);
  93. template <class U> static no_type test(typename U::member_value_traits* = 0);
  94. static const bool value = sizeof(test<T>(0)) == sizeof(no_type);
  95. };
  96. template<class SupposedValueTraits, class T, bool = is_default_hook_tag<SupposedValueTraits>::value>
  97. struct supposed_value_traits;
  98. template<class T, class BaseHook, bool = internal_any_hook_bool_is_true<BaseHook>::value>
  99. struct get_base_value_traits;
  100. template<class SupposedValueTraits, class T, bool = internal_base_hook_bool_is_true<SupposedValueTraits>::value>
  101. struct supposed_base_value_traits;
  102. template<class SupposedValueTraits, bool = internal_member_value_traits<SupposedValueTraits>::value>
  103. struct supposed_member_value_traits;
  104. template<class SupposedValueTraits, bool = internal_any_hook_bool_is_true<SupposedValueTraits>::value>
  105. struct any_or_concrete_value_traits;
  106. //Base any hook
  107. template<class T, class BaseHook>
  108. struct get_base_value_traits<T, BaseHook, true>
  109. : any_hook_base_value_traits<T, BaseHook>
  110. {};
  111. //Non-any base hook
  112. template<class T, class BaseHook>
  113. struct get_base_value_traits<T, BaseHook, false>
  114. : concrete_hook_base_value_traits<T, BaseHook>
  115. {};
  116. //...It's a default hook
  117. template<class SupposedValueTraits, class T>
  118. struct supposed_value_traits<SupposedValueTraits, T, true>
  119. { typedef typename SupposedValueTraits::template apply<T>::type type; };
  120. //...Not a default hook
  121. template<class SupposedValueTraits, class T>
  122. struct supposed_value_traits<SupposedValueTraits, T, false>
  123. { typedef SupposedValueTraits type; };
  124. //...It's a base hook
  125. template<class BaseHook, class T>
  126. struct supposed_base_value_traits<BaseHook, T, true>
  127. : get_base_value_traits<T, BaseHook>
  128. {};
  129. //...Not a base hook, try if it's a member or value_traits
  130. template<class SupposedValueTraits, class T>
  131. struct supposed_base_value_traits<SupposedValueTraits, T, false>
  132. : supposed_member_value_traits<SupposedValueTraits>
  133. {};
  134. //...It's a member hook
  135. template<class MemberHook>
  136. struct supposed_member_value_traits<MemberHook, true>
  137. : get_member_value_traits<MemberHook>
  138. {};
  139. //...Not a member hook
  140. template<class SupposedValueTraits>
  141. struct supposed_member_value_traits<SupposedValueTraits, false>
  142. : any_or_concrete_value_traits<SupposedValueTraits>
  143. {};
  144. template<class AnyToSomeHook_ProtoValueTraits>
  145. struct any_or_concrete_value_traits<AnyToSomeHook_ProtoValueTraits, true>
  146. {
  147. //A hook node (non-base, e.g.: member or other value traits
  148. typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t;
  149. typedef typename pointer_rebind
  150. <typename basic_hook_t::node_ptr, void>::type void_pointer;
  151. typedef typename AnyToSomeHook_ProtoValueTraits::template
  152. node_traits_from_voidptr<void_pointer>::type any_node_traits;
  153. struct type : basic_hook_t
  154. {
  155. typedef any_node_traits node_traits;
  156. };
  157. };
  158. template<class SupposedValueTraits>
  159. struct any_or_concrete_value_traits<SupposedValueTraits, false>
  160. {
  161. typedef SupposedValueTraits type;
  162. };
  163. ////////////////////////////////////////
  164. // get_value_traits / get_node_traits
  165. ////////////////////////////////////////
  166. template<class T, class SupposedValueTraits>
  167. struct get_value_traits
  168. : supposed_base_value_traits<typename supposed_value_traits<SupposedValueTraits, T>::type, T>
  169. {};
  170. template<class SupposedValueTraits>
  171. struct get_node_traits
  172. {
  173. typedef typename get_value_traits<void, SupposedValueTraits>::type::node_traits type;
  174. };
  175. } //namespace detail{
  176. #endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
  177. } //namespace intrusive {
  178. } //namespace boost {
  179. #include <boost/intrusive/detail/config_end.hpp>
  180. #endif //#ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP