MultiLevelHashSet test, bugfixing
[libcds.git] / cds / container / details / multilevel_hashset_base.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_CONTAINER_DETAILS_MULTILEVEL_HASHSET_BASE_H
4 #define CDSLIB_CONTAINER_DETAILS_MULTILEVEL_HASHSET_BASE_H
5
6 #include <cds/intrusive/details/multilevel_hashset_base.h>
7 #include <cds/container/details/base.h>
8
9 namespace cds { namespace container {
10     /// \p MultiLevelHashSet related definitions
11     /** @ingroup cds_nonintrusive_helper
12     */
13     namespace multilevel_hashset {
14         /// Hash accessor option
15         /**
16             @copydetails cds::intrusive::multilevel_hashset::traits::hash_accessor
17         */
18         template <typename Accessor>
19         using hash_accessor = cds::intrusive::multilevel_hashset::hash_accessor< Accessor >;
20
21         /// \p MultiLevelHashSet internal statistics, see cds::intrusive::multilevel_hashset::stat
22         template <typename EventCounter = cds::atomicity::event_counter>
23         using stat = cds::intrusive::multilevel_hashset::stat< EventCounter >;
24
25         /// \p MultiLevelHashSet empty internal statistics
26         typedef cds::intrusive::multilevel_hashset::empty_stat empty_stat;
27
28         /// Bit-wise memcmp-based comparator for hash value \p T
29         template <typename T>
30         using bitwise_compare = cds::intrusive::multilevel_hashset::bitwise_compare< T >;
31
32         /// \p MultiLevelHashSet traits
33         struct traits
34         {
35             /// Mandatory functor to get hash value from data node
36             /**
37                 @copydetails cds::intrusive::multilevel_hashset::traits::hash_accessor
38             */
39             typedef cds::opt::none hash_accessor;
40
41             /// Hash comparing functor
42             /**
43                 @copydetails cds::intrusive::multilevel_hashset::traits::compare
44             */
45             typedef cds::opt::none compare;
46
47             /// Specifies binary predicate used for hash compare.
48             /**
49                 @copydetails cds::intrusive::multilevel_hashset::traits::less
50             */
51             typedef cds::opt::none less;
52
53             /// Item counter
54             /**
55                 @copydetails cds::intrusive::multilevel_hashset::traits::item_counter
56             */
57             typedef cds::atomicity::item_counter item_counter;
58
59             /// Item allocator
60             /**
61                 Default is \ref CDS_DEFAULT_ALLOCATOR
62             */
63             typedef CDS_DEFAULT_ALLOCATOR allocator;
64
65             /// Array node allocator
66             /**
67                 @copydetails cds::intrusive::multilevel_hashset::traits::node_allocator
68             */
69             typedef CDS_DEFAULT_ALLOCATOR node_allocator;
70
71             /// C++ memory ordering model
72             /**
73                 @copydetails cds::intrusive::multilevel_hashset::traits::memory_model
74             */
75             typedef cds::opt::v::relaxed_ordering memory_model;
76
77             /// Back-off strategy
78             typedef cds::backoff::Default back_off;
79
80             /// Internal statistics
81             /**
82                 @copydetails cds::intrusive::multilevel_hashset::traits::stat
83             */
84             typedef empty_stat stat;
85
86             /// RCU deadlock checking policy (only for \ref cds_container_MultilevelHashSet_rcu "RCU-based MultilevelHashSet")
87             /**
88                 @copydetails cds::intrusive::multilevel_hashset::traits::rcu_check_deadlock
89             */
90             typedef cds::opt::v::rcu_throw_deadlock rcu_check_deadlock;
91         };
92
93         /// Metafunction converting option list to \p multilevel_hashset::traits
94         /**
95             Supported \p Options are:
96             - \p multilevel_hashset::hash_accessor - mandatory option, hash accessor functor.
97                 @copydetails traits::hash_accessor
98             - \p opt::allocator - item allocator
99                 @copydetails traits::allocator
100             - \p opt::node_allocator - array node allocator.
101                 @copydetails traits::node_allocator
102             - \p opt::compare - hash comparison functor. No default functor is provided.
103                 If the option is not specified, the \p opt::less is used.
104             - \p opt::less - specifies binary predicate used for hash comparison.
105                 @copydetails cds::container::multilevel_hashset::traits::less
106             - \p opt::back_off - back-off strategy used. If the option is not specified, the \p cds::backoff::Default is used.
107             - \p opt::item_counter - the type of item counting feature.
108                 @copydetails cds::intrusive::multilevel_hashset::traits::item_counter
109             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
110                 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
111             - \p opt::stat - internal statistics. By default, it is disabled (\p multilevel_hashset::empty_stat).
112                 To enable it use \p multilevel_hashset::stat
113             - \p opt::rcu_check_deadlock - a deadlock checking policy for \ref cds_intrusive_MultilevelHashSet_rcu "RCU-based MultilevelHashSet"
114                 Default is \p opt::v::rcu_throw_deadlock
115         */
116         template <typename... Options>
117         struct make_traits
118         {
119 #   ifdef CDS_DOXYGEN_INVOKED
120             typedef implementation_defined type ;   ///< Metafunction result
121 #   else
122             typedef typename cds::opt::make_options<
123                 typename cds::opt::find_type_traits< traits, Options... >::type
124                 ,Options...
125             >::type   type;
126 #   endif
127         };
128     } // namespace multilevel_hashset
129
130     //@cond
131     // Forward declaration
132     template < class GC, typename T, class Traits = cds::container::multilevel_hashset::traits >
133     class MultiLevelHashSet;
134     //@endcond
135
136     //@cond
137     namespace details {
138
139         template <typename GC, typename T, typename Traits>
140         struct make_multilevel_hashset
141         {
142             typedef GC      gc;
143             typedef T       value_type;
144             typedef Traits  original_traits;
145
146             typedef cds::details::Allocator< value_type, typename original_traits::allocator > cxx_node_allocator;
147
148             struct node_disposer
149             {
150                 void operator()( value_type * p ) const
151                 {
152                     cxx_node_allocator().Delete( p );
153                 }
154             };
155
156             struct intrusive_traits: public original_traits
157             {
158                 typedef node_disposer disposer;
159             };
160
161             // Metafunction result
162             typedef cds::intrusive::MultiLevelHashSet< GC, T, intrusive_traits > type;
163         };
164     } // namespace details
165     //@endcond
166
167 }} // namespace cds::container
168
169 #endif // #ifndef CDSLIB_CONTAINER_DETAILS_MULTILEVEL_HASHSET_BASE_H