any_hook.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2006-2013
  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_ANY_HOOK_HPP
  13. #define BOOST_INTRUSIVE_ANY_HOOK_HPP
  14. #include <boost/intrusive/detail/config_begin.hpp>
  15. #include <boost/intrusive/intrusive_fwd.hpp>
  16. #include <boost/intrusive/detail/utilities.hpp>
  17. #include <boost/intrusive/detail/any_node_and_algorithms.hpp>
  18. #include <boost/intrusive/options.hpp>
  19. #include <boost/intrusive/detail/generic_hook.hpp>
  20. #include <boost/intrusive/pointer_traits.hpp>
  21. namespace boost {
  22. namespace intrusive {
  23. /// @cond
  24. template<class VoidPointer>
  25. struct get_any_node_algo
  26. {
  27. typedef any_algorithms<VoidPointer> type;
  28. };
  29. /// @endcond
  30. //! Helper metafunction to define a \c \c any_base_hook that yields to the same
  31. //! type when the same options (either explicitly or implicitly) are used.
  32. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  33. template<class ...Options>
  34. #else
  35. template<class O1 = void, class O2 = void, class O3 = void>
  36. #endif
  37. struct make_any_base_hook
  38. {
  39. /// @cond
  40. typedef typename pack_options
  41. < hook_defaults,
  42. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  43. O1, O2, O3
  44. #else
  45. Options...
  46. #endif
  47. >::type packed_options;
  48. typedef generic_hook
  49. < get_any_node_algo<typename packed_options::void_pointer>
  50. , typename packed_options::tag
  51. , packed_options::link_mode
  52. , AnyBaseHookId
  53. > implementation_defined;
  54. /// @endcond
  55. typedef implementation_defined type;
  56. };
  57. //! Derive a class from this hook in order to store objects of that class
  58. //! in an intrusive container.
  59. //!
  60. //! The hook admits the following options: \c tag<>, \c void_pointer<> and
  61. //! \c link_mode<>.
  62. //!
  63. //! \c tag<> defines a tag to identify the node.
  64. //! The same tag value can be used in different classes, but if a class is
  65. //! derived from more than one \c any_base_hook, then each \c any_base_hook needs its
  66. //! unique tag.
  67. //!
  68. //! \c link_mode<> will specify the linking mode of the hook (\c normal_link, \c safe_link).
  69. //!
  70. //! \c void_pointer<> is the pointer type that will be used internally in the hook
  71. //! and the the container configured to use this hook.
  72. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  73. template<class ...Options>
  74. #else
  75. template<class O1, class O2, class O3>
  76. #endif
  77. class any_base_hook
  78. : public make_any_base_hook
  79. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  80. <O1, O2, O3>
  81. #else
  82. <Options...>
  83. #endif
  84. ::type
  85. {
  86. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  87. public:
  88. //! <b>Effects</b>: If link_mode is or \c safe_link
  89. //! initializes the node to an unlinked state.
  90. //!
  91. //! <b>Throws</b>: Nothing.
  92. any_base_hook();
  93. //! <b>Effects</b>: If link_mode is or \c safe_link
  94. //! initializes the node to an unlinked state. The argument is ignored.
  95. //!
  96. //! <b>Throws</b>: Nothing.
  97. //!
  98. //! <b>Rationale</b>: Providing a copy-constructor
  99. //! makes classes using the hook STL-compliant without forcing the
  100. //! user to do some additional work. \c swap can be used to emulate
  101. //! move-semantics.
  102. any_base_hook(const any_base_hook& );
  103. //! <b>Effects</b>: Empty function. The argument is ignored.
  104. //!
  105. //! <b>Throws</b>: Nothing.
  106. //!
  107. //! <b>Rationale</b>: Providing an assignment operator
  108. //! makes classes using the hook STL-compliant without forcing the
  109. //! user to do some additional work. \c swap can be used to emulate
  110. //! move-semantics.
  111. any_base_hook& operator=(const any_base_hook& );
  112. //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
  113. //! nothing (ie. no code is generated). If link_mode is \c safe_link and the
  114. //! object is stored in a container an assertion is raised.
  115. //!
  116. //! <b>Throws</b>: Nothing.
  117. ~any_base_hook();
  118. //! <b>Precondition</b>: link_mode must be \c safe_link.
  119. //!
  120. //! <b>Returns</b>: true, if the node belongs to a container, false
  121. //! otherwise. This function can be used to test whether \c container::iterator_to
  122. //! will return a valid iterator.
  123. //!
  124. //! <b>Complexity</b>: Constant
  125. bool is_linked() const;
  126. #endif
  127. };
  128. //! Helper metafunction to define a \c \c any_member_hook that yields to the same
  129. //! type when the same options (either explicitly or implicitly) are used.
  130. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  131. template<class ...Options>
  132. #else
  133. template<class O1 = void, class O2 = void, class O3 = void>
  134. #endif
  135. struct make_any_member_hook
  136. {
  137. /// @cond
  138. typedef typename pack_options
  139. < hook_defaults,
  140. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  141. O1, O2, O3
  142. #else
  143. Options...
  144. #endif
  145. >::type packed_options;
  146. typedef generic_hook
  147. < get_any_node_algo<typename packed_options::void_pointer>
  148. , member_tag
  149. , packed_options::link_mode
  150. , NoBaseHookId
  151. > implementation_defined;
  152. /// @endcond
  153. typedef implementation_defined type;
  154. };
  155. //! Store this hook in a class to be inserted
  156. //! in an intrusive container.
  157. //!
  158. //! The hook admits the following options: \c void_pointer<> and
  159. //! \c link_mode<>.
  160. //!
  161. //! \c link_mode<> will specify the linking mode of the hook (\c normal_link or \c safe_link).
  162. //!
  163. //! \c void_pointer<> is the pointer type that will be used internally in the hook
  164. //! and the the container configured to use this hook.
  165. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  166. template<class ...Options>
  167. #else
  168. template<class O1, class O2, class O3>
  169. #endif
  170. class any_member_hook
  171. : public make_any_member_hook
  172. #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
  173. <O1, O2, O3>
  174. #else
  175. <Options...>
  176. #endif
  177. ::type
  178. {
  179. #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
  180. public:
  181. //! <b>Effects</b>: If link_mode is or \c safe_link
  182. //! initializes the node to an unlinked state.
  183. //!
  184. //! <b>Throws</b>: Nothing.
  185. any_member_hook();
  186. //! <b>Effects</b>: If link_mode is or \c safe_link
  187. //! initializes the node to an unlinked state. The argument is ignored.
  188. //!
  189. //! <b>Throws</b>: Nothing.
  190. //!
  191. //! <b>Rationale</b>: Providing a copy-constructor
  192. //! makes classes using the hook STL-compliant without forcing the
  193. //! user to do some additional work. \c swap can be used to emulate
  194. //! move-semantics.
  195. any_member_hook(const any_member_hook& );
  196. //! <b>Effects</b>: Empty function. The argument is ignored.
  197. //!
  198. //! <b>Throws</b>: Nothing.
  199. //!
  200. //! <b>Rationale</b>: Providing an assignment operator
  201. //! makes classes using the hook STL-compliant without forcing the
  202. //! user to do some additional work. \c swap can be used to emulate
  203. //! move-semantics.
  204. any_member_hook& operator=(const any_member_hook& );
  205. //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
  206. //! nothing (ie. no code is generated). If link_mode is \c safe_link and the
  207. //! object is stored in a container an assertion is raised.
  208. //!
  209. //! <b>Throws</b>: Nothing.
  210. ~any_member_hook();
  211. //! <b>Precondition</b>: link_mode must be \c safe_link.
  212. //!
  213. //! <b>Returns</b>: true, if the node belongs to a container, false
  214. //! otherwise. This function can be used to test whether \c container::iterator_to
  215. //! will return a valid iterator.
  216. //!
  217. //! <b>Complexity</b>: Constant
  218. bool is_linked() const;
  219. #endif
  220. };
  221. /// @cond
  222. namespace detail{
  223. template<class ValueTraits>
  224. struct any_to_get_base_pointer_type
  225. {
  226. typedef typename pointer_traits<typename ValueTraits::hooktags::node_traits::node_ptr>::template
  227. rebind_pointer<void>::type type;
  228. };
  229. template<class ValueTraits>
  230. struct any_to_get_member_pointer_type
  231. {
  232. typedef typename pointer_traits
  233. <typename ValueTraits::node_ptr>::template rebind_pointer<void>::type type;
  234. };
  235. //!This option setter specifies that the container
  236. //!must use the specified base hook
  237. template<class BaseHook, template <class> class NodeTraits>
  238. struct any_to_some_hook
  239. {
  240. typedef typename BaseHook::template pack<empty>::proto_value_traits old_proto_value_traits;
  241. template<class Base>
  242. struct pack : public Base
  243. {
  244. struct proto_value_traits : public old_proto_value_traits
  245. {
  246. static const bool is_any_hook = true;
  247. typedef typename detail::eval_if_c
  248. < detail::internal_base_hook_bool_is_true<old_proto_value_traits>::value
  249. , any_to_get_base_pointer_type<old_proto_value_traits>
  250. , any_to_get_member_pointer_type<old_proto_value_traits>
  251. >::type void_pointer;
  252. typedef NodeTraits<void_pointer> node_traits;
  253. };
  254. };
  255. };
  256. } //namespace detail{
  257. /// @endcond
  258. //!This option setter specifies that
  259. //!any hook should behave as an slist hook
  260. template<class BaseHook>
  261. struct any_to_slist_hook
  262. /// @cond
  263. : public detail::any_to_some_hook<BaseHook, any_slist_node_traits>
  264. /// @endcond
  265. {};
  266. //!This option setter specifies that
  267. //!any hook should behave as an list hook
  268. template<class BaseHook>
  269. struct any_to_list_hook
  270. /// @cond
  271. : public detail::any_to_some_hook<BaseHook, any_list_node_traits>
  272. /// @endcond
  273. {};
  274. //!This option setter specifies that
  275. //!any hook should behave as a set hook
  276. template<class BaseHook>
  277. struct any_to_set_hook
  278. /// @cond
  279. : public detail::any_to_some_hook<BaseHook, any_rbtree_node_traits>
  280. /// @endcond
  281. {};
  282. //!This option setter specifies that
  283. //!any hook should behave as an avl_set hook
  284. template<class BaseHook>
  285. struct any_to_avl_set_hook
  286. /// @cond
  287. : public detail::any_to_some_hook<BaseHook, any_avltree_node_traits>
  288. /// @endcond
  289. {};
  290. //!This option setter specifies that any
  291. //!hook should behave as a bs_set hook
  292. template<class BaseHook>
  293. struct any_to_bs_set_hook
  294. /// @cond
  295. : public detail::any_to_some_hook<BaseHook, any_tree_node_traits>
  296. /// @endcond
  297. {};
  298. //!This option setter specifies that any hook
  299. //!should behave as an unordered set hook
  300. template<class BaseHook>
  301. struct any_to_unordered_set_hook
  302. /// @cond
  303. : public detail::any_to_some_hook<BaseHook, any_unordered_node_traits>
  304. /// @endcond
  305. {};
  306. } //namespace intrusive
  307. } //namespace boost
  308. #include <boost/intrusive/detail/config_end.hpp>
  309. #endif //BOOST_INTRUSIVE_ANY_HOOK_HPP