1/////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Olaf Krzikalla 2004-2006.
4// (C) Copyright Ion Gaztanaga 2006-2013
5//
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)
9//
10// See http://www.boost.org/libs/intrusive for documentation.
11//
12/////////////////////////////////////////////////////////////////////////////
13
14#ifndef BOOST_INTRUSIVE_SLIST_HOOK_HPP
15#define BOOST_INTRUSIVE_SLIST_HOOK_HPP
16
17#include <boost/intrusive/detail/config_begin.hpp>
18#include <boost/intrusive/intrusive_fwd.hpp>
19
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>
25
26#if defined(BOOST_HAS_PRAGMA_ONCE)
27# pragma once
28#endif
29
30namespace boost {
31namespace intrusive {
32
33//! Helper metafunction to define a \c slist_base_hook that yields to the same
34//! type when the same options (either explicitly or implicitly) are used.
35#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
36template<class ...Options>
37#else
38template<class O1 = void, class O2 = void, class O3 = void>
39#endif
40struct make_slist_base_hook
41{
42 /// @cond
43 typedef typename pack_options
44 < hook_defaults,
45 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
46 O1, O2, O3
47 #else
48 Options...
49 #endif
50 >::type packed_options;
51
52 typedef generic_hook
53 < circular_slist_algorithms<slist_node_traits<typename packed_options::void_pointer> >
54 , typename packed_options::tag
55 , packed_options::link_mode
56 , SlistBaseHookId
57 > implementation_defined;
58 /// @endcond
59 typedef implementation_defined type;
60};
61
62//! Derive a class from slist_base_hook in order to store objects in
63//! in an list. slist_base_hook holds the data necessary to maintain the
64//! list and provides an appropriate value_traits class for list.
65//!
66//! The hook admits the following options: \c tag<>, \c void_pointer<> and
67//! \c link_mode<>.
68//!
69//! \c tag<> defines a tag to identify the node.
70//! The same tag value can be used in different classes, but if a class is
71//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
72//! unique tag.
73//!
74//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
75//! \c auto_unlink or \c safe_link).
76//!
77//! \c void_pointer<> is the pointer type that will be used internally in the hook
78//! and the container configured to use this hook.
79#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
80template<class ...Options>
81#else
82template<class O1, class O2, class O3>
83#endif
84class slist_base_hook
85 : public make_slist_base_hook<
86 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
87 O1, O2, O3
88 #else
89 Options...
90 #endif
91 >::type
92{
93 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
94 public:
95 //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
96 //! initializes the node to an unlinked state.
97 //!
98 //! <b>Throws</b>: Nothing.
99 slist_base_hook();
100
101 //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
102 //! initializes the node to an unlinked state. The argument is ignored.
103 //!
104 //! <b>Throws</b>: Nothing.
105 //!
106 //! <b>Rationale</b>: Providing a copy-constructor
107 //! makes classes using the hook STL-compliant without forcing the
108 //! user to do some additional work. \c swap can be used to emulate
109 //! move-semantics.
110 slist_base_hook(const slist_base_hook& );
111
112 //! <b>Effects</b>: Empty function. The argument is ignored.
113 //!
114 //! <b>Throws</b>: Nothing.
115 //!
116 //! <b>Rationale</b>: Providing an assignment operator
117 //! makes classes using the hook STL-compliant without forcing the
118 //! user to do some additional work. \c swap can be used to emulate
119 //! move-semantics.
120 slist_base_hook& operator=(const slist_base_hook& );
121
122 //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
123 //! nothing (ie. no code is generated). If link_mode is \c safe_link and the
124 //! object is stored in an slist an assertion is raised. If link_mode is
125 //! \c auto_unlink and \c is_linked() is true, the node is unlinked.
126 //!
127 //! <b>Throws</b>: Nothing.
128 ~slist_base_hook();
129
130 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
131 //! related to those nodes in one or two containers. That is, if the node
132 //! this is part of the element e1, the node x is part of the element e2
133 //! and both elements are included in the containers s1 and s2, then after
134 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
135 //! at the position of e1. If one element is not in a container, then
136 //! after the swap-operation the other element is not in a container.
137 //! Iterators to e1 and e2 related to those nodes are invalidated.
138 //!
139 //! <b>Complexity</b>: Constant
140 //!
141 //! <b>Throws</b>: Nothing.
142 void swap_nodes(slist_base_hook &other);
143
144 //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
145 //!
146 //! <b>Returns</b>: true, if the node belongs to a container, false
147 //! otherwise. This function can be used to test whether \c slist::iterator_to
148 //! will return a valid iterator.
149 //!
150 //! <b>Complexity</b>: Constant
151 bool is_linked() const;
152
153 //! <b>Effects</b>: Removes the node if it's inserted in a container.
154 //! This function is only allowed if link_mode is \c auto_unlink.
155 //!
156 //! <b>Throws</b>: Nothing.
157 void unlink();
158 #endif
159};
160
161//! Helper metafunction to define a \c slist_member_hook that yields to the same
162//! type when the same options (either explicitly or implicitly) are used.
163#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
164template<class ...Options>
165#else
166template<class O1 = void, class O2 = void, class O3 = void>
167#endif
168struct make_slist_member_hook
169{
170 /// @cond
171 typedef typename pack_options
172 < hook_defaults,
173 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
174 O1, O2, O3
175 #else
176 Options...
177 #endif
178 >::type packed_options;
179
180 typedef generic_hook
181 < circular_slist_algorithms<slist_node_traits<typename packed_options::void_pointer> >
182 , member_tag
183 , packed_options::link_mode
184 , NoBaseHookId
185 > implementation_defined;
186 /// @endcond
187 typedef implementation_defined type;
188};
189
190//! Put a public data member slist_member_hook in order to store objects of this class in
191//! an list. slist_member_hook holds the data necessary for maintaining the list and
192//! provides an appropriate value_traits class for list.
193//!
194//! The hook admits the following options: \c void_pointer<> and
195//! \c link_mode<>.
196//!
197//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
198//! \c auto_unlink or \c safe_link).
199//!
200//! \c void_pointer<> is the pointer type that will be used internally in the hook
201//! and the container configured to use this hook.
202#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
203template<class ...Options>
204#else
205template<class O1, class O2, class O3>
206#endif
207class slist_member_hook
208 : public make_slist_member_hook<
209 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
210 O1, O2, O3
211 #else
212 Options...
213 #endif
214 >::type
215{
216 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
217 public:
218 //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
219 //! initializes the node to an unlinked state.
220 //!
221 //! <b>Throws</b>: Nothing.
222 slist_member_hook();
223
224 //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
225 //! initializes the node to an unlinked state. The argument is ignored.
226 //!
227 //! <b>Throws</b>: Nothing.
228 //!
229 //! <b>Rationale</b>: Providing a copy-constructor
230 //! makes classes using the hook STL-compliant without forcing the
231 //! user to do some additional work. \c swap can be used to emulate
232 //! move-semantics.
233 slist_member_hook(const slist_member_hook& );
234
235 //! <b>Effects</b>: Empty function. The argument is ignored.
236 //!
237 //! <b>Throws</b>: Nothing.
238 //!
239 //! <b>Rationale</b>: Providing an assignment operator
240 //! makes classes using the hook STL-compliant without forcing the
241 //! user to do some additional work. \c swap can be used to emulate
242 //! move-semantics.
243 slist_member_hook& operator=(const slist_member_hook& );
244
245 //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
246 //! nothing (ie. no code is generated). If link_mode is \c safe_link and the
247 //! object is stored in an slist an assertion is raised. If link_mode is
248 //! \c auto_unlink and \c is_linked() is true, the node is unlinked.
249 //!
250 //! <b>Throws</b>: Nothing.
251 ~slist_member_hook();
252
253 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
254 //! related to those nodes in one or two containers. That is, if the node
255 //! this is part of the element e1, the node x is part of the element e2
256 //! and both elements are included in the containers s1 and s2, then after
257 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
258 //! at the position of e1. If one element is not in a container, then
259 //! after the swap-operation the other element is not in a container.
260 //! Iterators to e1 and e2 related to those nodes are invalidated.
261 //!
262 //! <b>Complexity</b>: Constant
263 //!
264 //! <b>Throws</b>: Nothing.
265 void swap_nodes(slist_member_hook &other);
266
267 //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
268 //!
269 //! <b>Returns</b>: true, if the node belongs to a container, false
270 //! otherwise. This function can be used to test whether \c slist::iterator_to
271 //! will return a valid iterator.
272 //!
273 //! <b>Complexity</b>: Constant
274 bool is_linked() const;
275
276 //! <b>Effects</b>: Removes the node if it's inserted in a container.
277 //! This function is only allowed if link_mode is \c auto_unlink.
278 //!
279 //! <b>Throws</b>: Nothing.
280 void unlink();
281 #endif
282};
283
284} //namespace intrusive
285} //namespace boost
286
287#include <boost/intrusive/detail/config_end.hpp>
288
289#endif //BOOST_INTRUSIVE_SLIST_HOOK_HPP
290

source code of boost/boost/intrusive/slist_hook.hpp