5149f0ef494fa304725da55efa90fc3b3671edd8
[libcds.git] / cds / container / details / make_split_list_set.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_CONTAINER_DETAILS_MAKE_SPLIT_LIST_SET_H
4 #define __CDS_CONTAINER_DETAILS_MAKE_SPLIT_LIST_SET_H
5
6 #include <cds/container/details/split_list_base.h>
7 #include <cds/details/allocator.h>
8 #include <cds/details/binary_functor_wrapper.h>
9
10 //@cond
11 namespace cds { namespace container {
12
13     // Forward declaration
14     struct michael_list_tag;
15     struct lazy_list_tag;
16
17     namespace details {
18
19 #ifdef __CDS_CONTAINER_DETAILS_MICHAEL_LIST_BASE_H
20         // if michael_list included
21
22         template <typename GC, typename T, typename Traits>
23         struct make_split_list_set< GC, T, michael_list_tag, Traits >
24         {
25             typedef GC      gc;
26             typedef T       value_type;
27             typedef Traits  original_traits;
28
29             typedef typename cds::opt::select_default<
30                 typename original_traits::ordered_list_traits,
31                 cds::container::michael_list::traits
32             >::type         original_ordered_list_traits;
33
34             typedef cds::intrusive::split_list::node< cds::intrusive::michael_list::node<gc> > primary_node_type;
35             struct node_type: public primary_node_type
36             {
37                 value_type  m_Value;
38
39                 template <typename Q>
40                 explicit node_type( Q const& v )
41                     : m_Value(v)
42                 {}
43                 template <typename Q, typename... Args>
44                 explicit node_type( Q&& q, Args&&... args )
45                     : m_Value( std::forward<Q>(q), std::forward<Args>(args)... )
46                 {}
47
48                 node_type() = delete;
49             };
50
51             typedef typename cds::opt::select_default<
52                 typename original_traits::ordered_list_traits,
53                 typename original_traits::allocator,
54                 typename cds::opt::select_default<
55                     typename original_traits::ordered_list_traits::allocator,
56                     typename original_traits::allocator
57                 >::type
58             >::type node_allocator_;
59
60             typedef typename node_allocator_::template rebind<node_type>::other node_allocator_type;
61
62             typedef cds::details::Allocator< node_type, node_allocator_type >   cxx_node_allocator;
63             struct node_deallocator
64             {
65                 void operator ()( node_type * pNode )
66                 {
67                     cxx_node_allocator().Delete( pNode );
68                 }
69             };
70
71             typedef typename opt::details::make_comparator< value_type, original_ordered_list_traits >::type key_comparator;
72
73             typedef typename original_traits::key_accessor key_accessor;
74
75             struct value_accessor
76             {
77                 typename key_accessor::key_type const& operator()( node_type const& node ) const
78                 {
79                     return key_accessor()(node.m_Value);
80                 }
81             };
82
83             template <typename Predicate>
84             struct predicate_wrapper {
85                 typedef cds::details::predicate_wrapper< node_type, Predicate, value_accessor > type;
86             };
87
88             struct ordered_list_traits: public original_ordered_list_traits
89             {
90                 typedef cds::intrusive::michael_list::base_hook<
91                     opt::gc<gc>
92                 >   hook;
93                 typedef cds::atomicity::empty_item_counter item_counter;
94                 typedef node_deallocator  disposer;
95                 typedef cds::details::compare_wrapper< node_type, key_comparator, value_accessor > compare;
96                 static CDS_CONSTEXPR const opt::link_check_type link_checker = cds::intrusive::michael_list::traits::link_checker;
97             };
98
99             struct traits: public original_traits
100             {
101                 struct hash: public original_traits::hash
102                 {
103                     typedef typename original_traits::hash  base_class;
104
105                     size_t operator()(node_type const& v ) const
106                     {
107                         return base_class::operator()( key_accessor()( v.m_Value ) );
108                     }
109                     template <typename Q>
110                     size_t operator()( Q const& k ) const
111                     {
112                         return base_class::operator()( k );
113                     }
114                 };
115             };
116
117             class ordered_list: public cds::intrusive::MichaelList< gc, node_type, ordered_list_traits >
118             {};
119             //typedef cds::intrusive::MichaelList< gc, node_type, ordered_list_traits > ordered_list;
120             typedef cds::intrusive::SplitListSet< gc, ordered_list, traits > type;
121         };
122 #endif  // ifdef __CDS_CONTAINER_DETAILS_MICHAEL_LIST_BASE_H
123
124 #ifdef __CDS_CONTAINER_DETAILS_LAZY_LIST_BASE_H
125         // if lazy_list included
126         template <typename GC, typename T, typename Traits>
127         struct make_split_list_set< GC, T, lazy_list_tag, Traits >
128         {
129             typedef GC      gc;
130             typedef T       value_type;
131             typedef Traits  original_traits;
132
133             typedef typename cds::opt::select_default<
134                 typename original_traits::ordered_list_traits,
135                 cds::container::lazy_list::traits
136             >::type         original_ordered_list_traits;
137
138             typedef typename cds::opt::select_default<
139                 typename original_ordered_list_traits::lock_type,
140                 typename cds::container::lazy_list::traits::lock_type
141             >::type   lock_type;
142
143             typedef cds::intrusive::split_list::node< cds::intrusive::lazy_list::node<gc, lock_type > > primary_node_type;
144             struct node_type: public primary_node_type
145             {
146                 value_type  m_Value;
147
148                 template <typename Q>
149                 explicit node_type( const Q& v )
150                     : m_Value(v)
151                 {}
152
153                 template <typename Q, typename... Args>
154                 explicit node_type( Q&& q, Args&&... args )
155                     : m_Value( std::forward<Q>(q), std::forward<Args>(args)... )
156                 {}
157
158                 node_type() = delete;
159             };
160
161             typedef typename cds::opt::select_default<
162                 typename original_traits::ordered_list_traits,
163                 typename original_traits::allocator,
164                 typename cds::opt::select_default<
165                     typename original_traits::ordered_list_traits::allocator,
166                     typename original_traits::allocator
167                 >::type
168             >::type node_allocator_;
169
170             typedef typename node_allocator_::template rebind<node_type>::other node_allocator_type;
171
172             typedef cds::details::Allocator< node_type, node_allocator_type >   cxx_node_allocator;
173             struct node_deallocator
174             {
175                 void operator ()( node_type * pNode )
176                 {
177                     cxx_node_allocator().Delete( pNode );
178                 }
179             };
180
181             typedef typename opt::details::make_comparator< value_type, original_ordered_list_traits >::type key_comparator;
182
183             typedef typename original_traits::key_accessor key_accessor;
184
185             struct value_accessor
186             {
187                 typename key_accessor::key_type const & operator()( node_type const & node ) const
188                 {
189                     return key_accessor()(node.m_Value);
190                 }
191             };
192
193             template <typename Predicate>
194             struct predicate_wrapper {
195                 typedef cds::details::predicate_wrapper< node_type, Predicate, value_accessor > type;
196             };
197
198             struct ordered_list_traits: public original_ordered_list_traits
199             {
200                 typedef cds::intrusive::lazy_list::base_hook<
201                     opt::gc<gc>
202                     ,opt::lock_type< lock_type >
203                 >  hook;
204                 typedef cds::atomicity::empty_item_counter item_counter;
205                 typedef node_deallocator                disposer;
206                 typedef cds::details::compare_wrapper< node_type, key_comparator, value_accessor > compare;
207                 static CDS_CONSTEXPR const opt::link_check_type link_checker = cds::intrusive::lazy_list::traits::link_checker;
208             };
209
210             struct traits: public original_traits
211             {
212                 struct hash: public original_traits::hash
213                 {
214                     typedef typename original_traits::hash  base_class;
215
216                     size_t operator()(node_type const& v ) const
217                     {
218                         return base_class::operator()( key_accessor()( v.m_Value ));
219                     }
220                     template <typename Q>
221                     size_t operator()( Q const& k ) const
222                     {
223                         return base_class::operator()( k );
224                     }
225                 };
226             };
227
228             class ordered_list: public cds::intrusive::LazyList< gc, node_type, ordered_list_traits >
229             {};
230             //typedef cds::intrusive::LazyList< gc, node_type, ordered_list_traits >  ordered_list;
231             typedef cds::intrusive::SplitListSet< gc, ordered_list, traits >   type;
232         };
233 #endif  // ifdef __CDS_CONTAINER_DETAILS_LAZY_LIST_BASE_H
234
235     }   // namespace details
236 }}  // namespace cds::container
237 //@endcond
238
239 #endif // #ifndef __CDS_CONTAINER_DETAILS_MAKE_SPLIT_LIST_SET_H