MultiLevelHashSet test, bugfixing
[libcds.git] / tests / unit / set2 / set_type_std.h
1 //$$CDS-header$$
2
3 #ifndef CDSUNIT_SET_TYPE_STD_H
4 #define CDSUNIT_SET_TYPE_STD_H
5
6 #include <unordered_set>
7 #include <set>
8 #include <mutex>    //unique_lock
9
10 #include "set2/set_type.h"
11
12 namespace set2 {
13
14     struct tag_StdSet;
15
16     template <typename Value, typename Hash, typename Less, typename EqualTo, typename Lock,
17         class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<Value>::other
18     >
19     class StdHashSet
20         : public std::unordered_set<
21             Value
22             , Hash
23             , EqualTo
24             , Alloc
25         >
26     {
27     public:
28         Lock m_lock;
29         typedef std::unique_lock<Lock> scoped_lock;
30         typedef std::unordered_set<
31             Value
32             , Hash
33             , EqualTo
34             , Alloc
35         >   base_class;
36
37     public:
38         typedef typename base_class::value_type value_type;
39
40         template <class Config>
41         StdHashSet( Config const& )
42         {}
43
44         template <typename Key>
45         bool contains( const Key& key )
46         {
47             scoped_lock al( m_lock );
48             return base_class::find( value_type(key) ) != base_class::end();
49         }
50
51         template <typename Key>
52         bool insert( Key const& key )
53         {
54             scoped_lock al( m_lock );
55             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( value_type( key ));
56             return pRet.second;
57         }
58
59         template <typename Key, typename Func>
60         bool insert( Key const& key, Func func )
61         {
62             scoped_lock al( m_lock );
63             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( value_type( key ));
64             if ( pRet.second ) {
65                 func( *pRet.first );
66                 return true;
67             }
68             return false;
69         }
70
71         template <typename T, typename Func>
72         std::pair<bool, bool> ensure( const T& key, Func func )
73         {
74             scoped_lock al( m_lock );
75             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( value_type( key ));
76             if ( pRet.second ) {
77                 func( true, *pRet.first, key );
78                 return std::make_pair( true, true );
79             }
80             else {
81                 func( false, *pRet.first, key );
82                 return std::make_pair( true, false );
83             }
84         }
85
86         template <typename Key>
87         bool erase( const Key& key )
88         {
89             scoped_lock al( m_lock );
90             return base_class::erase( value_type(key) ) != 0;
91         }
92
93         template <typename T, typename Func>
94         bool erase( const T& key, Func func )
95         {
96             scoped_lock al( m_lock );
97             typename base_class::iterator it = base_class::find( value_type(key) );
98             if ( it != base_class::end() ) {
99                 func( *it );
100                 return base_class::erase( it ) != base_class::end();
101             }
102             return false;
103         }
104
105         std::ostream& dump( std::ostream& stm ) { return stm; }
106
107         // for testing
108         static CDS_CONSTEXPR bool const c_bExtractSupported = false;
109         static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
110         static CDS_CONSTEXPR bool const c_bEraseExactKey = true;
111     };
112
113     template <typename Value, typename Less, typename Lock,
114         class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<Value>::other
115     >
116     class StdSet: public std::set<Value, Less, Alloc>
117     {
118         Lock m_lock;
119         typedef std::unique_lock<Lock> scoped_lock;
120         typedef std::set<Value, Less, Alloc> base_class;
121     public:
122         typedef typename base_class::key_type value_type;
123
124         template <class Config>
125         StdSet( Config const& )
126         {}
127
128         template <typename Key>
129         bool contains( const Key& key )
130         {
131             value_type v( key );
132             scoped_lock al( m_lock );
133             return base_class::find( v ) != base_class::end();
134         }
135
136         bool insert( value_type const& v )
137         {
138             scoped_lock al( m_lock );
139             return base_class::insert( v ).second;
140         }
141
142         template <typename Key, typename Func>
143         bool insert( Key const& key, Func func )
144         {
145             scoped_lock al( m_lock );
146             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( value_type( key ));
147             if ( pRet.second ) {
148                 func( *pRet.first );
149                 return true;
150             }
151             return false;
152         }
153
154         template <typename T, typename Func>
155         std::pair<bool, bool> ensure( const T& key, Func func )
156         {
157             scoped_lock al( m_lock );
158             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( value_type( key ));
159             if ( pRet.second ) {
160                 func( true, *pRet.first, key );
161                 return std::make_pair( true, true );
162             }
163             else {
164                 func( false, *pRet.first, key );
165                 return std::make_pair( true, false );
166             }
167         }
168
169         template <typename Key>
170         bool erase( const Key& key )
171         {
172             scoped_lock al( m_lock );
173             return base_class::erase( value_type(key) ) != 0;
174         }
175
176         template <typename T, typename Func>
177         bool erase( const T& key, Func func )
178         {
179             scoped_lock al( m_lock );
180             typename base_class::iterator it = base_class::find( value_type(key) );
181             if ( it != base_class::end() ) {
182                 func( *it );
183
184                 base_class::erase( it );
185                 return true;
186             }
187             return false;
188         }
189
190         std::ostream& dump( std::ostream& stm ) { return stm; }
191
192         // for testing
193         static CDS_CONSTEXPR bool const c_bExtractSupported = false;
194         static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
195     };
196
197     template <typename Key, typename Val>
198     struct set_type< tag_StdSet, Key, Val >: public set_type_base< Key, Val >
199     {
200         typedef set_type_base< Key, Val > base_class;
201         typedef typename base_class::key_val key_val;
202         typedef typename base_class::less less;
203         typedef typename base_class::hash hash;
204         typedef typename base_class::equal_to equal_to;
205
206         typedef StdSet< key_val, less, cds::sync::spin > StdSet_Spin;
207         typedef StdSet< key_val, less, std::mutex > StdSet_Mutex;
208         typedef StdSet< key_val, less, lock::NoLock>     StdSet_NoLock;
209
210         typedef StdHashSet< key_val, hash, less, equal_to, cds::sync::spin > StdHashSet_Spin;
211         typedef StdHashSet< key_val, hash, less, equal_to, std::mutex > StdHashSet_Mutex;
212         typedef StdHashSet< key_val, hash, less, equal_to, lock::NoLock >    StdHashSet_NoLock;
213     };
214
215 } // namespace set2
216
217 #endif // #ifndef CDSUNIT_SET_TYPE_STD_H