3d7ec4036486b881cae4bb97a919b87611dbe55c
[libcds.git] / cds / intrusive / options.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_INTRUSIVE_OPTIONS_H
4 #define __CDS_INTRUSIVE_OPTIONS_H
5
6 #include <cds/opt/options.h>
7 #include <cds/details/allocator.h>
8
9 namespace cds { namespace intrusive {
10
11     /// Common options for intrusive containers
12     /** @ingroup cds_intrusive_helper
13         This namespace contains options for intrusive containers.
14         It imports all definitions from cds::opt namespace and introduces a lot
15         of options specific for intrusive approach.
16     */
17     namespace opt {
18         using namespace cds::opt;
19
20         //@cond
21         struct base_hook_tag;
22         struct member_hook_tag;
23         struct traits_hook_tag;
24         //@endcond
25
26         /// Hook option
27         /**
28             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.
29             \p Hook template parameter strongly depends on the type of intrusive container you use.
30         */
31         template <typename Hook>
32         struct hook {
33             //@cond
34             template <typename Base> struct pack: public Base
35             {
36                 typedef Hook hook;
37             };
38             //@endcond
39         };
40
41         /// Item disposer option setter
42         /**
43             The option specifies a functor that is used for dispose removed items.
44             The interface of \p Type functor is:
45             \code
46             struct myDisposer {
47                 void operator ()( T * val );
48             };
49             \endcode
50
51             Predefined types for \p Type:
52             - opt::v::empty_disposer - the disposer that does nothing
53             - opt::v::delete_disposer - the disposer that calls operator \p delete
54
55             Usually, the disposer should be stateless default-constructible functor.
56             It is called by garbage collector in deferred mode.
57         */
58         template <typename Type>
59         struct disposer {
60             //@cond
61             template <typename Base> struct pack: public Base
62             {
63                 typedef Type disposer;
64             };
65             //@endcond
66         };
67
68         /// Values of \ref cds::intrusive::opt::link_checker option
69         enum link_check_type {
70             never_check_link,    ///< no link checking performed
71             debug_check_link,    ///< check only in debug build
72             always_check_link    ///< check in debug and release build
73         };
74
75         /// Link checking
76         /**
77             The option specifies a type of link checking.
78             Possible values for \p Value are is one of \ref link_check_type enum:
79             - \ref never_check_link - no link checking performed
80             - \ref debug_check_link - check only in debug build
81             - \ref always_check_link - check in debug and release build (not yet implemented for release mode).
82
83             When link checking is on, the container tests that the node's link fields
84             must be \p nullptr before inserting the item. If the link is not \p nullptr an assertion is generated
85         */
86         template <link_check_type Value>
87         struct link_checker {
88             //@cond
89             template <typename Base> struct pack: public Base
90             {
91                 static const link_check_type link_checker = Value;
92             };
93             //@endcond
94         };
95
96         /// Predefined option values
97         namespace v {
98             using namespace cds::opt::v;
99
100             //@cond
101             /// No link checking
102             template <typename Node>
103             struct empty_link_checker
104             {
105                 //@cond
106                 typedef Node node_type;
107
108                 static void is_empty( const node_type * pNode )
109                 {}
110                 //@endcond
111             };
112             //@endcond
113
114             /// Empty item disposer
115             /**
116                 The disposer does nothing.
117                 This is one of possible values of opt::disposer option.
118             */
119             struct empty_disposer
120             {
121                 /// Empty dispose functor
122                 template <typename T>
123                 void operator ()( T * )
124                 {}
125             };
126
127             /// Deletion item disposer
128             /**
129                 Analogue of operator \p delete call.
130                 The disposer that calls \p T destructor and deallocates the item via \p Alloc allocator.
131             */
132             template <typename Alloc = CDS_DEFAULT_ALLOCATOR >
133             struct delete_disposer
134             {
135                 /// Dispose functor
136                 template <typename T>
137                 void operator ()( T * p )
138                 {
139                     cds::details::Allocator<T, Alloc> alloc;
140                     alloc.Delete( p );
141                 }
142             };
143         }   // namespace v
144
145         //@cond
146         // Lazy-list specific option (for split-list support)
147         template <typename Type>
148         struct boundary_node_type {
149             //@cond
150             template <typename Base> struct pack: public Base
151             {
152                 typedef Type boundary_node_type;
153             };
154             //@endcond
155         };
156         //@endcond
157     } // namespace opt
158
159 }} // namespace cds::intrusive
160
161 #endif // #ifndef __CDS_INTRUSIVE_OPTIONS_H