Refactored Set_InsDelFind MT-test
[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     };
111
112     template <typename Value, typename Less, typename Lock,
113         class Alloc = typename CDS_DEFAULT_ALLOCATOR::template rebind<Value>::other
114     >
115     class StdSet: public std::set<Value, Less, Alloc>
116     {
117         Lock m_lock;
118         typedef std::unique_lock<Lock> scoped_lock;
119         typedef std::set<Value, Less, Alloc> base_class;
120     public:
121         typedef typename base_class::key_type value_type;
122
123         template <class Config>
124         StdSet( Config const& )
125         {}
126
127         template <typename Key>
128         bool contains( const Key& key )
129         {
130             value_type v( key );
131             scoped_lock al( m_lock );
132             return base_class::find( v ) != base_class::end();
133         }
134
135         bool insert( value_type const& v )
136         {
137             scoped_lock al( m_lock );
138             return base_class::insert( v ).second;
139         }
140
141         template <typename Key, typename Func>
142         bool insert( Key const& key, Func func )
143         {
144             scoped_lock al( m_lock );
145             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( value_type( key ));
146             if ( pRet.second ) {
147                 func( *pRet.first );
148                 return true;
149             }
150             return false;
151         }
152
153         template <typename T, typename Func>
154         std::pair<bool, bool> ensure( const T& key, Func func )
155         {
156             scoped_lock al( m_lock );
157             std::pair<typename base_class::iterator, bool> pRet = base_class::insert( value_type( key ));
158             if ( pRet.second ) {
159                 func( true, *pRet.first, key );
160                 return std::make_pair( true, true );
161             }
162             else {
163                 func( false, *pRet.first, key );
164                 return std::make_pair( true, false );
165             }
166         }
167
168         template <typename Key>
169         bool erase( const Key& key )
170         {
171             scoped_lock al( m_lock );
172             return base_class::erase( value_type(key) ) != 0;
173         }
174
175         template <typename T, typename Func>
176         bool erase( const T& key, Func func )
177         {
178             scoped_lock al( m_lock );
179             typename base_class::iterator it = base_class::find( value_type(key) );
180             if ( it != base_class::end() ) {
181                 func( *it );
182
183                 base_class::erase( it );
184                 return true;
185             }
186             return false;
187         }
188
189         std::ostream& dump( std::ostream& stm ) { return stm; }
190
191         // for testing
192         static CDS_CONSTEXPR bool const c_bExtractSupported = false;
193         static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
194     };
195
196     template <typename Key, typename Val>
197     struct set_type< tag_StdSet, Key, Val >: public set_type_base< Key, Val >
198     {
199         typedef set_type_base< Key, Val > base_class;
200         typedef typename base_class::key_val key_val;
201         typedef typename base_class::less less;
202         typedef typename base_class::hash hash;
203         typedef typename base_class::equal_to equal_to;
204
205         typedef StdSet< key_val, less, cds::sync::spin > StdSet_Spin;
206         typedef StdSet< key_val, less, std::mutex > StdSet_Mutex;
207         typedef StdSet< key_val, less, lock::NoLock>     StdSet_NoLock;
208
209         typedef StdHashSet< key_val, hash, less, equal_to, cds::sync::spin > StdHashSet_Spin;
210         typedef StdHashSet< key_val, hash, less, equal_to, std::mutex > StdHashSet_Mutex;
211         typedef StdHashSet< key_val, hash, less, equal_to, lock::NoLock >    StdHashSet_NoLock;
212     };
213
214 } // namespace set2
215
216 #endif // #ifndef CDSUNIT_SET_TYPE_STD_H