Improved management of SkipList auxiliary nodes: now aux nodes are allocated from...
[libcds.git] / cds / intrusive / options.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef CDSLIB_INTRUSIVE_OPTIONS_H
32 #define CDSLIB_INTRUSIVE_OPTIONS_H
33
34 #include <cds/opt/options.h>
35 #include <cds/details/allocator.h>
36
37 namespace cds { namespace intrusive {
38
39     /// Common options for intrusive containers
40     /** @ingroup cds_intrusive_helper
41         This namespace contains options for intrusive containers.
42         It imports all definitions from cds::opt namespace and introduces a lot
43         of options specific for intrusive approach.
44     */
45     namespace opt {
46         using namespace cds::opt;
47
48         //@cond
49         struct base_hook_tag;
50         struct member_hook_tag;
51         struct traits_hook_tag;
52         //@endcond
53
54         /// Hook option
55         /**
56             Hook is a class that a user must add as a base class or as a member to make the user class compatible with intrusive containers.
57             \p Hook template parameter strongly depends on the type of intrusive container you use.
58         */
59         template <typename Hook>
60         struct hook {
61             //@cond
62             template <typename Base> struct pack: public Base
63             {
64                 typedef Hook hook;
65             };
66             //@endcond
67         };
68
69         /// Item disposer option setter
70         /**
71             The option specifies a functor that is used for dispose removed items.
72             The interface of \p Type functor is:
73             \code
74             struct myDisposer {
75                 void operator ()( T * val );
76             };
77             \endcode
78
79             Predefined types for \p Type:
80             - \p opt::v::empty_disposer - the disposer that does nothing
81             - \p opt::v::delete_disposer - the disposer that calls operator \p delete
82
83             Usually, the disposer should be stateless default-constructible functor.
84             It is called by garbage collector in deferred mode.
85         */
86         template <typename Type>
87         struct disposer {
88             //@cond
89             template <typename Base> struct pack: public Base
90             {
91                 typedef Type disposer;
92             };
93             //@endcond
94         };
95
96         /// Values of \ref cds::intrusive::opt::link_checker option
97         enum link_check_type {
98             never_check_link,    ///< no link checking performed
99             debug_check_link,    ///< check only in debug build
100             always_check_link    ///< check in debug and release build
101         };
102
103         /// Link checking
104         /**
105             The option specifies a type of link checking.
106             Possible values for \p Value are is one of \ref link_check_type enum:
107             - \ref never_check_link - no link checking performed
108             - \ref debug_check_link - check only in debug build
109             - \ref always_check_link - check in debug and release build (not yet implemented for release mode).
110
111             When link checking is on, the container tests that the node's link fields
112             must be \p nullptr before inserting the item. If the link is not \p nullptr an assertion is generated
113         */
114         template <link_check_type Value>
115         struct link_checker {
116             //@cond
117             template <typename Base> struct pack: public Base
118             {
119                 static const link_check_type link_checker = Value;
120             };
121             //@endcond
122         };
123
124         /// Predefined option values
125         namespace v {
126             using namespace cds::opt::v;
127
128             //@cond
129             /// No link checking
130             template <typename Node>
131             struct empty_link_checker
132             {
133                 //@cond
134                 typedef Node node_type;
135
136                 static void is_empty( const node_type * /*pNode*/ )
137                 {}
138                 //@endcond
139             };
140             //@endcond
141
142             /// Empty item disposer
143             /**
144                 The disposer does nothing.
145                 This is one of possible values of opt::disposer option.
146             */
147             struct empty_disposer
148             {
149                 /// Empty dispose functor
150                 template <typename T>
151                 void operator ()( T * )
152                 {}
153             };
154
155             /// Deletion item disposer
156             /**
157                 Analogue of operator \p delete call.
158                 The disposer that calls \p T destructor and deallocates the item via \p Alloc allocator.
159             */
160             template <typename Alloc = CDS_DEFAULT_ALLOCATOR >
161             struct delete_disposer
162             {
163                 /// Dispose functor
164                 template <typename T>
165                 void operator ()( T * p )
166                 {
167                     cds::details::Allocator<T, Alloc> alloc;
168                     alloc.Delete( p );
169                 }
170             };
171         }   // namespace v
172
173         //@cond
174         // Lazy-list specific option (for split-list support)
175         template <typename Type>
176         struct boundary_node_type {
177             //@cond
178             template <typename Base> struct pack: public Base
179             {
180                 typedef Type boundary_node_type;
181             };
182             //@endcond
183         };
184         //@endcond
185     } // namespace opt
186
187 }} // namespace cds::intrusive
188
189 #endif // #ifndef CDSLIB_INTRUSIVE_OPTIONS_H