Merged branch 'master' of https://github.com/Nemo1369/libcds
[libcds.git] / test / stress / set / set_type.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef CDSUNIT_SET_TYPE_H
32 #define CDSUNIT_SET_TYPE_H
33
34 #include <cds/urcu/general_instant.h>
35 #include <cds/urcu/general_buffered.h>
36 #include <cds/urcu/general_threaded.h>
37 #include <cds/urcu/signal_buffered.h>
38 #include <cds/urcu/signal_threaded.h>
39
40 #include <cds/opt/hash.h>
41 #include <cds/sync/spinlock.h>
42
43 #include <cds_test/stress_test.h>
44
45 namespace set {
46     namespace cc = cds::container;
47     namespace co = cds::opt;
48
49     typedef cds::urcu::gc< cds::urcu::general_instant_stripped >   rcu_gpi;
50     typedef cds::urcu::gc< cds::urcu::general_buffered_stripped >  rcu_gpb;
51     typedef cds::urcu::gc< cds::urcu::general_threaded_stripped >  rcu_gpt;
52 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
53     typedef cds::urcu::gc< cds::urcu::signal_buffered_stripped >  rcu_shb;
54     typedef cds::urcu::gc< cds::urcu::signal_threaded_stripped >  rcu_sht;
55 #endif
56
57     template <typename Key>
58     struct less;
59
60     template <typename Key>
61     struct cmp
62     {
63         int operator ()(Key const& k1, Key const& k2) const
64         {
65             if ( less<Key>( k1, k2 ))
66                 return -1;
67             return less<Key>( k2, k1 ) ? 1 : 0;
68         }
69     };
70
71     template <typename Key>
72     struct hash;
73
74 #define CDSUNIT_INT_COMPARE(t)  template <> struct cmp<t> { int operator()( t k1, t k2 ){ return (int)(k1 - k2); } }
75     CDSUNIT_INT_COMPARE(char);
76     CDSUNIT_INT_COMPARE(unsigned char);
77     CDSUNIT_INT_COMPARE(int);
78     CDSUNIT_INT_COMPARE(unsigned int);
79     CDSUNIT_INT_COMPARE(long);
80     CDSUNIT_INT_COMPARE(unsigned long);
81     CDSUNIT_INT_COMPARE(long long);
82     CDSUNIT_INT_COMPARE(unsigned long long);
83 #undef CDSUNIT_INT_COMPARE
84
85 #define CDSUNIT_INT_LESS(t)  template <> struct less<t> { bool operator()( t k1, t k2 ){ return k1 < k2; } }
86     CDSUNIT_INT_LESS( char );
87     CDSUNIT_INT_LESS( unsigned char );
88     CDSUNIT_INT_LESS( int );
89     CDSUNIT_INT_LESS( unsigned int );
90     CDSUNIT_INT_LESS( long );
91     CDSUNIT_INT_LESS( unsigned long );
92     CDSUNIT_INT_LESS( long long );
93     CDSUNIT_INT_LESS( unsigned long long );
94 #undef CDSUNIT_INT_LESS
95
96     template <>
97     struct cmp<std::string>
98     {
99         int operator()(std::string const& s1, std::string const& s2)
100         {
101             return s1.compare( s2 );
102         }
103         int operator()(std::string const& s1, char const * s2)
104         {
105             return s1.compare( s2 );
106         }
107         int operator()(char const * s1, std::string const& s2)
108         {
109             return -s2.compare( s1 );
110         }
111     };
112
113     template <>
114     struct less<std::string>
115     {
116         bool operator ()( std::string const& k1, std::string const& k2 ) const
117         {
118             return cmp<std::string>()( k1, k2 ) < 0;
119         }
120         bool operator ()( std::string const& k1, char const* k2 ) const
121         {
122             return cmp<std::string>()( k1, k2 ) < 0;
123         }
124         bool operator ()( char const* k1, std::string const& k2 ) const
125         {
126             return cmp<std::string>()( k1, k2 ) < 0;
127         }
128     };
129
130     template <typename T>
131     struct hash
132     {
133         typedef size_t result_type;
134         typedef T      argument_type;
135
136         size_t operator()( T const& k ) const
137         {
138             return std::hash<size_t>()(k.nKey);
139         }
140
141         size_t operator()( size_t k ) const
142         {
143             return std::hash<size_t>()(k);
144         }
145     };
146
147     template <>
148     struct hash<size_t>
149     {
150         typedef size_t result_type;
151         typedef size_t argument_type;
152
153         size_t operator()( size_t k ) const
154         {
155             return std::hash<size_t>()(k);
156         }
157     };
158
159     template <>
160     struct hash<std::string>
161     {
162         typedef size_t result_type;
163         typedef std::string argument_type;
164
165         size_t operator()( std::string const& k ) const
166         {
167             return std::hash<std::string>()(k);
168         }
169     };
170
171     // forward
172     template <typename ImplSelector, typename Key, typename Value>
173     struct set_type;
174
175     template <typename Key, typename Value>
176     struct set_type_base
177     {
178         typedef Key     key_type;
179         typedef Value   value_type;
180
181         struct key_val {
182             key_type    key;
183             value_type  val;
184
185             explicit key_val( key_type const& k ): key(k), val() {}
186             key_val( key_type const& k, value_type const& v ): key(k), val(v) {}
187
188             template <typename K>
189             explicit key_val( K const& k ): key(k) {}
190
191             template <typename K, typename T>
192             key_val( K const& k, T const& v ): key(k), val(v) {}
193         };
194
195         typedef set::hash<key_type>   key_hash;
196         typedef set::less<key_type>   key_less;
197         typedef set::cmp<key_type>    key_compare;
198
199         struct less {
200             bool operator()( key_val const& k1, key_val const& k2 ) const
201             {
202                 return key_less()( k1.key, k2.key );
203             }
204             bool operator()( key_type const& k1, key_val const& k2 ) const
205             {
206                 return key_less()( k1, k2.key );
207             }
208             bool operator()( key_val const& k1, key_type const& k2 ) const
209             {
210                 return key_less()( k1.key, k2 );
211             }
212         };
213
214         struct compare {
215             int operator()( key_val const& k1, key_val const& k2 ) const
216             {
217                 return key_compare()( k1.key, k2.key );
218             }
219             int operator()( key_type const& k1, key_val const& k2 ) const
220             {
221                 return key_compare()( k1, k2.key );
222             }
223             int operator()( key_val const& k1, key_type const& k2 ) const
224             {
225                 return key_compare()( k1.key, k2 );
226             }
227         };
228
229         struct equal_to {
230             bool operator()( key_val const& k1, key_val const& k2 ) const
231             {
232                 return key_compare()( k1.key, k2.key ) == 0;
233             }
234             bool operator()( key_type const& k1, key_val const& k2 ) const
235             {
236                 return key_compare()( k1, k2.key ) == 0;
237             }
238             bool operator()( key_val const& k1, key_type const& k2 ) const
239             {
240                 return key_compare()( k1.key, k2 ) == 0;
241             }
242         };
243
244
245         struct hash: public key_hash
246         {
247             size_t operator()( key_val const& v ) const
248             {
249                 return key_hash::operator()( v.key );
250             }
251             size_t operator()( key_type const& key ) const
252             {
253                 return key_hash::operator()( key );
254             }
255             template <typename Q>
256             size_t operator()( Q const& k ) const
257             {
258                 return key_hash::operator()( k );
259             }
260         };
261
262         struct hash2: public hash
263         {
264             size_t operator()( key_val const& k ) const
265             {
266                 size_t h = hash::operator ()( k.key );
267                 size_t seed = ~h;
268                 seed ^= h + 0x9e3779b9 + (seed << 6) + (seed >> 2);
269                 return seed;
270             }
271             size_t operator()( key_type const& k ) const
272             {
273                 size_t h = hash::operator ()( k );
274                 size_t seed = ~h;
275                 seed ^= h + 0x9e3779b9 + (seed << 6) + (seed >> 2);
276                 return seed;
277             }
278             template <typename Q>
279             size_t operator()( Q const& k ) const
280             {
281                 return key_hash::operator()( k );
282             }
283         };
284     };
285
286
287     // *************************************************
288     // print_stat
289     // *************************************************
290
291     struct empty_stat {};
292     static inline cds_test::property_stream& operator <<( cds_test::property_stream& o, empty_stat const& )
293     {
294         return o;
295     }
296
297     template <typename Set>
298     static inline void print_stat( cds_test::property_stream& o, Set const& s )
299     {
300         o << s.statistics();
301     }
302
303
304     //*******************************************************
305     // additional_check
306     //*******************************************************
307
308     template <typename Set>
309     static inline void additional_check( Set& /*set*/ )
310     {}
311
312     template <typename Set>
313     static inline void additional_cleanup( Set& /*set*/ )
314     {}
315
316     //*******************************************************
317     // check_before_clear
318     //*******************************************************
319
320     template <typename Set>
321     static inline void check_before_clear( Set& /*s*/ )
322     {}
323
324 } // namespace set
325
326
327 #endif // ifndef CDSUNIT_SET_TYPE_H