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