container::SplitListSet refactoring
[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             typedef cds::intrusive::MichaelList< gc, node_type, ordered_list_traits > ordered_list;
118             typedef cds::intrusive::SplitListSet< gc, ordered_list, traits > type;
119         };
120 #endif  // ifdef __CDS_CONTAINER_DETAILS_MICHAEL_LIST_BASE_H
121
122 #ifdef __CDS_CONTAINER_DETAILS_LAZY_LIST_BASE_H
123         // if lazy_list included
124         template <typename GC, typename T, typename Traits>
125         struct make_split_list_set< GC, T, lazy_list_tag, Traits >
126         {
127             typedef GC      gc;
128             typedef T       value_type;
129             typedef Traits  original_traits;
130
131             typedef typename cds::opt::select_default<
132                 typename original_traits::ordered_list_traits,
133                 cds::container::lazy_list::traits
134             >::type         original_ordered_list_traits;
135
136             typedef typename cds::opt::select_default<
137                 typename original_ordered_list_traits::lock_type,
138                 typename cds::container::lazy_list::traits::lock_type
139             >::type   lock_type;
140
141             typedef cds::intrusive::split_list::node< cds::intrusive::lazy_list::node<gc, lock_type > > primary_node_type;
142             struct node_type: public primary_node_type
143             {
144                 value_type  m_Value;
145
146                 template <typename Q>
147                 explicit node_type( const Q& v )
148                     : m_Value(v)
149                 {}
150
151                 template <typename Q, typename... Args>
152                 explicit node_type( Q&& q, Args&&... args )
153                     : m_Value( std::forward<Q>(q), std::forward<Args>(args)... )
154                 {}
155
156                 node_type() = delete;
157             };
158
159             typedef typename cds::opt::select_default<
160                 typename original_traits::ordered_list_traits,
161                 typename original_traits::allocator,
162                 typename cds::opt::select_default<
163                     typename original_traits::ordered_list_traits::allocator,
164                     typename original_traits::allocator
165                 >::type
166             >::type node_allocator_;
167
168             typedef typename node_allocator_::template rebind<node_type>::other node_allocator_type;
169
170             typedef cds::details::Allocator< node_type, node_allocator_type >   cxx_node_allocator;
171             struct node_deallocator
172             {
173                 void operator ()( node_type * pNode )
174                 {
175                     cxx_node_allocator().Delete( pNode );
176                 }
177             };
178
179             typedef typename opt::details::make_comparator< value_type, original_ordered_list_traits >::type key_comparator;
180
181             typedef typename original_traits::key_accessor key_accessor;
182
183             struct value_accessor
184             {
185                 typename key_accessor::key_type const & operator()( node_type const & node ) const
186                 {
187                     return key_accessor()(node.m_Value);
188                 }
189             };
190
191             template <typename Predicate>
192             struct predicate_wrapper {
193                 typedef cds::details::predicate_wrapper< node_type, Predicate, value_accessor > type;
194             };
195
196             struct ordered_list_traits: public original_ordered_list_traits
197             {
198                 typedef cds::intrusive::lazy_list::base_hook<
199                     opt::gc<gc>
200                     ,opt::lock_type< lock_type >
201                 >  hook;
202                 typedef cds::atomicity::empty_item_counter item_counter;
203                 typedef node_deallocator                disposer;
204                 typedef cds::details::compare_wrapper< node_type, key_comparator, value_accessor > compare;
205                 static CDS_CONSTEXPR const opt::link_check_type link_checker = cds::intrusive::lazy_list::traits::link_checker;
206             };
207
208             struct traits: public original_traits
209             {
210                 struct hash: public original_traits::hash
211                 {
212                     typedef typename original_traits::hash  base_class;
213
214                     size_t operator()(node_type const& v ) const
215                     {
216                         return base_class::operator()( key_accessor()( v.m_Value ));
217                     }
218                     template <typename Q>
219                     size_t operator()( Q const& k ) const
220                     {
221                         return base_class::operator()( k );
222                     }
223                 };
224             };
225
226             typedef cds::intrusive::LazyList< gc, node_type, ordered_list_traits >  ordered_list;
227             typedef cds::intrusive::SplitListSet< gc, ordered_list, traits >   type;
228         };
229 #endif  // ifdef __CDS_CONTAINER_DETAILS_LAZY_LIST_BASE_H
230
231     }   // namespace details
232 }}  // namespace cds::container
233 //@endcond
234
235 #endif // #ifndef __CDS_CONTAINER_DETAILS_MAKE_SPLIT_LIST_SET_H