Imported Upstream version 1.49.0
[platform/upstream/boost.git] / boost / intrusive / slist_hook.hpp
1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Olaf Krzikalla 2004-2006.
4 // (C) Copyright Ion Gaztanaga  2006-2009
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 #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>
25
26 namespace boost {
27 namespace intrusive {
28
29 /// @cond
30 template<class VoidPointer>
31 struct get_slist_node_algo
32 {
33    typedef circular_slist_algorithms<slist_node_traits<VoidPointer> > type;
34 };
35
36 /// @endcond
37
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>
42 #else
43 template<class O1 = none, class O2 = none, class O3 = none>
44 #endif
45 struct make_slist_base_hook
46 {
47    /// @cond
48    typedef typename pack_options
49       < hook_defaults, 
50          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
51          O1, O2, O3
52          #else
53          Options...
54          #endif
55       >::type packed_options;
56
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;
63    /// @endcond
64    typedef implementation_defined type;
65 };
66
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.
70 //! 
71 //! The hook admits the following options: \c tag<>, \c void_pointer<> and
72 //! \c link_mode<>.
73 //!
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 
77 //! unique tag.
78 //!
79 //! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
80 //! \c auto_unlink or \c safe_link).
81 //!
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>
86 #else
87 template<class O1, class O2, class O3>
88 #endif
89 class slist_base_hook
90    :  public make_slist_base_hook<
91          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
92          O1, O2, O3
93          #else
94          Options...
95          #endif
96       >::type
97 {
98    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
99    public:
100    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
101    //!   initializes the node to an unlinked state.
102    //! 
103    //! <b>Throws</b>: Nothing. 
104    slist_base_hook();
105
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.
108    //! 
109    //! <b>Throws</b>: Nothing. 
110    //! 
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
114    //!   move-semantics.
115    slist_base_hook(const slist_base_hook& );
116
117    //! <b>Effects</b>: Empty function. The argument is ignored.
118    //! 
119    //! <b>Throws</b>: Nothing. 
120    //! 
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
124    //!   move-semantics.
125    slist_base_hook& operator=(const slist_base_hook& );
126
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.
131    //! 
132    //! <b>Throws</b>: Nothing. 
133    ~slist_base_hook();
134
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. 
143    //!
144    //! <b>Complexity</b>: Constant 
145    //!
146    //! <b>Throws</b>: Nothing. 
147    void swap_nodes(slist_base_hook &other);
148
149    //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
150    //!
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. 
154    //!
155    //! <b>Complexity</b>: Constant 
156    bool is_linked() const;
157
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.
160    //! 
161    //! <b>Throws</b>: Nothing. 
162    void unlink();
163    #endif
164 };
165
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>
170 #else
171 template<class O1 = none, class O2 = none, class O3 = none>
172 #endif
173 struct make_slist_member_hook
174 {
175    /// @cond
176    typedef typename pack_options
177       < hook_defaults, 
178          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
179          O1, O2, O3
180          #else
181          Options...
182          #endif
183       >::type packed_options;
184
185    typedef detail::generic_hook
186    < get_slist_node_algo<typename packed_options::void_pointer>
187    , member_tag
188    , packed_options::link_mode
189    , detail::NoBaseHook
190    > implementation_defined;
191    /// @endcond
192    typedef implementation_defined type;
193 };
194
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.
198 //! 
199 //! The hook admits the following options: \c void_pointer<> and
200 //! \c link_mode<>.
201 //! 
202 //! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
203 //! \c auto_unlink or \c safe_link).
204 //!
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>
209 #else
210 template<class O1, class O2, class O3>
211 #endif
212 class slist_member_hook
213    :  public make_slist_member_hook<
214          #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
215          O1, O2, O3
216          #else
217          Options...
218          #endif
219       >::type
220 {
221    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
222    public:
223    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
224    //!   initializes the node to an unlinked state.
225    //! 
226    //! <b>Throws</b>: Nothing. 
227    slist_member_hook();
228
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.
231    //! 
232    //! <b>Throws</b>: Nothing. 
233    //! 
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
237    //!   move-semantics.
238    slist_member_hook(const slist_member_hook& );
239
240    //! <b>Effects</b>: Empty function. The argument is ignored.
241    //! 
242    //! <b>Throws</b>: Nothing. 
243    //! 
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
247    //!   move-semantics.
248    slist_member_hook& operator=(const slist_member_hook& );
249
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.
254    //! 
255    //! <b>Throws</b>: Nothing. 
256    ~slist_member_hook();
257
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. 
266    //!
267    //! <b>Complexity</b>: Constant 
268    //!
269    //! <b>Throws</b>: Nothing. 
270    void swap_nodes(slist_member_hook &other);
271
272    //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
273    //!
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. 
277    //!
278    //! <b>Complexity</b>: Constant 
279    bool is_linked() const;
280
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.
283    //! 
284    //! <b>Throws</b>: Nothing. 
285    void unlink();
286    #endif
287 };
288
289 } //namespace intrusive 
290 } //namespace boost 
291
292 #include <boost/intrusive/detail/config_end.hpp>
293
294 #endif //BOOST_INTRUSIVE_SLIST_HOOK_HPP