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