any_hook.hpp 10 KB

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