1 /////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Olaf Krzikalla 2004-2006.
4 // (C) Copyright Ion Gaztanaga 2006-2009
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
10 // See http://www.boost.org/libs/intrusive for documentation.
12 /////////////////////////////////////////////////////////////////////////////
14 #ifndef BOOST_INTRUSIVE_SLIST_HOOK_HPP
15 #define BOOST_INTRUSIVE_SLIST_HOOK_HPP
17 #include <boost/intrusive/detail/config_begin.hpp>
18 #include <boost/intrusive/intrusive_fwd.hpp>
19 #include <boost/intrusive/detail/utilities.hpp>
20 #include <boost/intrusive/detail/slist_node.hpp>
21 #include <boost/intrusive/circular_slist_algorithms.hpp>
22 #include <boost/intrusive/link_mode.hpp>
23 #include <boost/intrusive/options.hpp>
24 #include <boost/intrusive/detail/generic_hook.hpp>
30 template<class VoidPointer>
31 struct get_slist_node_algo
33 typedef circular_slist_algorithms<slist_node_traits<VoidPointer> > type;
38 //! Helper metafunction to define a \c slist_base_hook that yields to the same
39 //! type when the same options (either explicitly or implicitly) are used.
40 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
41 template<class ...Options>
43 template<class O1 = none, class O2 = none, class O3 = none>
45 struct make_slist_base_hook
48 typedef typename pack_options
50 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
55 >::type packed_options;
57 typedef detail::generic_hook
58 < get_slist_node_algo<typename packed_options::void_pointer>
59 , typename packed_options::tag
60 , packed_options::link_mode
61 , detail::SlistBaseHook
62 > implementation_defined;
64 typedef implementation_defined type;
67 //! Derive a class from slist_base_hook in order to store objects in
68 //! in an list. slist_base_hook holds the data necessary to maintain the
69 //! list and provides an appropriate value_traits class for list.
71 //! The hook admits the following options: \c tag<>, \c void_pointer<> and
74 //! \c tag<> defines a tag to identify the node.
75 //! The same tag value can be used in different classes, but if a class is
76 //! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
79 //! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
80 //! \c auto_unlink or \c safe_link).
82 //! \c void_pointer<> is the pointer type that will be used internally in the hook
83 //! and the the container configured to use this hook.
84 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
85 template<class ...Options>
87 template<class O1, class O2, class O3>
90 : public make_slist_base_hook<
91 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
98 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
100 //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
101 //! initializes the node to an unlinked state.
103 //! <b>Throws</b>: Nothing.
106 //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
107 //! initializes the node to an unlinked state. The argument is ignored.
109 //! <b>Throws</b>: Nothing.
111 //! <b>Rationale</b>: Providing a copy-constructor
112 //! makes classes using the hook STL-compliant without forcing the
113 //! user to do some additional work. \c swap can be used to emulate
115 slist_base_hook(const slist_base_hook& );
117 //! <b>Effects</b>: Empty function. The argument is ignored.
119 //! <b>Throws</b>: Nothing.
121 //! <b>Rationale</b>: Providing an assignment operator
122 //! makes classes using the hook STL-compliant without forcing the
123 //! user to do some additional work. \c swap can be used to emulate
125 slist_base_hook& operator=(const slist_base_hook& );
127 //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
128 //! nothing (ie. no code is generated). If link_mode is \c safe_link and the
129 //! object is stored in an slist an assertion is raised. If link_mode is
130 //! \c auto_unlink and \c is_linked() is true, the node is unlinked.
132 //! <b>Throws</b>: Nothing.
135 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
136 //! related to those nodes in one or two containers. That is, if the node
137 //! this is part of the element e1, the node x is part of the element e2
138 //! and both elements are included in the containers s1 and s2, then after
139 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
140 //! at the position of e1. If one element is not in a container, then
141 //! after the swap-operation the other element is not in a container.
142 //! Iterators to e1 and e2 related to those nodes are invalidated.
144 //! <b>Complexity</b>: Constant
146 //! <b>Throws</b>: Nothing.
147 void swap_nodes(slist_base_hook &other);
149 //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
151 //! <b>Returns</b>: true, if the node belongs to a container, false
152 //! otherwise. This function can be used to test whether \c slist::iterator_to
153 //! will return a valid iterator.
155 //! <b>Complexity</b>: Constant
156 bool is_linked() const;
158 //! <b>Effects</b>: Removes the node if it's inserted in a container.
159 //! This function is only allowed if link_mode is \c auto_unlink.
161 //! <b>Throws</b>: Nothing.
166 //! Helper metafunction to define a \c slist_member_hook that yields to the same
167 //! type when the same options (either explicitly or implicitly) are used.
168 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
169 template<class ...Options>
171 template<class O1 = none, class O2 = none, class O3 = none>
173 struct make_slist_member_hook
176 typedef typename pack_options
178 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
183 >::type packed_options;
185 typedef detail::generic_hook
186 < get_slist_node_algo<typename packed_options::void_pointer>
188 , packed_options::link_mode
190 > implementation_defined;
192 typedef implementation_defined type;
195 //! Put a public data member slist_member_hook in order to store objects of this class in
196 //! an list. slist_member_hook holds the data necessary for maintaining the list and
197 //! provides an appropriate value_traits class for list.
199 //! The hook admits the following options: \c void_pointer<> and
202 //! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
203 //! \c auto_unlink or \c safe_link).
205 //! \c void_pointer<> is the pointer type that will be used internally in the hook
206 //! and the the container configured to use this hook.
207 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
208 template<class ...Options>
210 template<class O1, class O2, class O3>
212 class slist_member_hook
213 : public make_slist_member_hook<
214 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
221 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
223 //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
224 //! initializes the node to an unlinked state.
226 //! <b>Throws</b>: Nothing.
229 //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
230 //! initializes the node to an unlinked state. The argument is ignored.
232 //! <b>Throws</b>: Nothing.
234 //! <b>Rationale</b>: Providing a copy-constructor
235 //! makes classes using the hook STL-compliant without forcing the
236 //! user to do some additional work. \c swap can be used to emulate
238 slist_member_hook(const slist_member_hook& );
240 //! <b>Effects</b>: Empty function. The argument is ignored.
242 //! <b>Throws</b>: Nothing.
244 //! <b>Rationale</b>: Providing an assignment operator
245 //! makes classes using the hook STL-compliant without forcing the
246 //! user to do some additional work. \c swap can be used to emulate
248 slist_member_hook& operator=(const slist_member_hook& );
250 //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
251 //! nothing (ie. no code is generated). If link_mode is \c safe_link and the
252 //! object is stored in an slist an assertion is raised. If link_mode is
253 //! \c auto_unlink and \c is_linked() is true, the node is unlinked.
255 //! <b>Throws</b>: Nothing.
256 ~slist_member_hook();
258 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
259 //! related to those nodes in one or two containers. That is, if the node
260 //! this is part of the element e1, the node x is part of the element e2
261 //! and both elements are included in the containers s1 and s2, then after
262 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
263 //! at the position of e1. If one element is not in a container, then
264 //! after the swap-operation the other element is not in a container.
265 //! Iterators to e1 and e2 related to those nodes are invalidated.
267 //! <b>Complexity</b>: Constant
269 //! <b>Throws</b>: Nothing.
270 void swap_nodes(slist_member_hook &other);
272 //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
274 //! <b>Returns</b>: true, if the node belongs to a container, false
275 //! otherwise. This function can be used to test whether \c slist::iterator_to
276 //! will return a valid iterator.
278 //! <b>Complexity</b>: Constant
279 bool is_linked() const;
281 //! <b>Effects</b>: Removes the node if it's inserted in a container.
282 //! This function is only allowed if link_mode is \c auto_unlink.
284 //! <b>Throws</b>: Nothing.
289 } //namespace intrusive
292 #include <boost/intrusive/detail/config_end.hpp>
294 #endif //BOOST_INTRUSIVE_SLIST_HOOK_HPP