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

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