]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 |