Move libcds 1.6.0 from SVN
[libcds.git] / tests / test-hdr / deque / hdr_deque.h
1 //$$CDS-header$$
2
3 #include "cppunit/cppunit_proxy.h"
4 #include "cppunit/test_beans.h"
5
6 namespace deque {
7
8     class DequeHeaderTest: public CppUnitMini::TestCase
9     {
10     public:
11         struct value_type {
12             int     nVal;
13
14             value_type()
15             {}
16             value_type( int i )
17                 : nVal(i)
18                 {}
19         };
20
21         struct assign_functor
22         {
23             template <typename T>
24             void operator()( value_type& dest, T i ) const
25             {
26                 dest.nVal = i;
27             }
28         };
29
30         struct pop_functor
31         {
32             template <typename T>
33             void operator()( T& dest, value_type const& v )
34             {
35                 dest = v.nVal;
36             }
37         };
38
39         static void assign_func( value_type& dest, int i )
40         {
41             dest.nVal = i;
42         }
43         static void pop_func( int& dest, value_type const& v )
44         {
45             dest = v.nVal;
46         }
47
48         template <class Deque>
49         void test()
50         {
51             test_beans::check_item_counter<typename Deque::item_counter> check_ic;
52
53             Deque q;
54             value_type v;
55             int i;
56
57             CPPUNIT_ASSERT( q.empty() );
58             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
59
60             // push_right/pop_right
61             CPPUNIT_ASSERT( q.push_back( value_type(5) ));
62             CPPUNIT_ASSERT( !q.empty() );
63             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
64
65             CPPUNIT_ASSERT( q.push_back( 10, assign_functor() )) ; // functor
66             CPPUNIT_ASSERT( !q.empty() );
67             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
68
69             CPPUNIT_ASSERT( q.push_back( 20, assign_func )) ;     // function
70             CPPUNIT_ASSERT( !q.empty() );
71             CPPUNIT_ASSERT( check_ic( q.size(), 3 ));
72
73             CPPUNIT_ASSERT( q.pop_back(v) );
74             CPPUNIT_ASSERT( v.nVal == 20 );
75             CPPUNIT_ASSERT( !q.empty() );
76             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
77
78             CPPUNIT_ASSERT( q.pop_back( i, pop_functor()) );
79             CPPUNIT_ASSERT( i == 10 );
80             CPPUNIT_ASSERT( !q.empty() );
81             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
82
83             CPPUNIT_ASSERT( q.pop_back(i, pop_func) );
84             CPPUNIT_ASSERT( i == 5 );
85             CPPUNIT_ASSERT( q.empty() );
86             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
87
88             v.nVal = -1;
89             CPPUNIT_ASSERT( !q.pop_back(v) );
90             CPPUNIT_ASSERT( v.nVal == -1 );
91             CPPUNIT_ASSERT( q.empty() );
92             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
93
94 #ifdef CDS_EMPLACE_SUPPORT
95             CPPUNIT_ASSERT( q.emplace_back( 157 ));
96             CPPUNIT_ASSERT( !q.empty() );
97             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
98
99             CPPUNIT_ASSERT( q.emplace_back( 158 ));
100             CPPUNIT_ASSERT( !q.empty() );
101             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
102
103             CPPUNIT_ASSERT( q.pop_back(i, pop_func) );
104             CPPUNIT_ASSERT( i == 158 );
105             CPPUNIT_ASSERT( !q.empty() );
106             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
107
108             CPPUNIT_ASSERT( q.pop_back(i, pop_functor()) );
109             CPPUNIT_ASSERT( i == 157 );
110             CPPUNIT_ASSERT( q.empty() );
111             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
112 #endif
113
114 #ifdef CDS_CXX11_LAMBDA_SUPPORT
115             CPPUNIT_ASSERT( q.push_back( value_type(511), [](value_type& dest, value_type const& i){ dest.nVal = i.nVal * 2; } ));
116             CPPUNIT_ASSERT( !q.empty() );
117             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
118
119             CPPUNIT_ASSERT( q.push_back( 512, [](value_type& dest, int i){ dest.nVal = i; } ));
120             CPPUNIT_ASSERT( !q.empty() );
121             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
122
123             CPPUNIT_ASSERT( q.pop_back( i, []( int& dest, value_type const& v){ dest = v.nVal; } ) );
124             CPPUNIT_ASSERT( i == 512 );
125             CPPUNIT_ASSERT( !q.empty() );
126             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
127
128             v.nVal = i = 0;
129             CPPUNIT_ASSERT( q.pop_back( i, [&v]( int& dest, value_type const& val){ dest = -val.nVal; v.nVal = val.nVal; }) );
130             CPPUNIT_ASSERT( i == -511 * 2 );
131             CPPUNIT_ASSERT( v.nVal == 511 * 2);
132             CPPUNIT_ASSERT( q.empty() );
133             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
134 #endif
135
136             // push_right/pop_left
137             CPPUNIT_ASSERT( q.push_back( value_type(5) ));
138             CPPUNIT_ASSERT( !q.empty() );
139             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
140
141             CPPUNIT_ASSERT( q.push_back( 10, assign_functor() )) ; // functor
142             CPPUNIT_ASSERT( !q.empty() );
143             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
144
145             CPPUNIT_ASSERT( q.push_back( 20, assign_func )) ;     // function
146             CPPUNIT_ASSERT( !q.empty() );
147             CPPUNIT_ASSERT( check_ic( q.size(), 3 ));
148
149             CPPUNIT_ASSERT( q.pop_front(v) );
150             CPPUNIT_ASSERT( v.nVal == 5 );
151             CPPUNIT_ASSERT( !q.empty() );
152             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
153
154             CPPUNIT_ASSERT( q.pop_front(i, pop_functor() ) );
155             CPPUNIT_ASSERT( i == 10 );
156             CPPUNIT_ASSERT( !q.empty() );
157             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
158
159             CPPUNIT_ASSERT( q.pop_front( i, pop_func ) );
160             CPPUNIT_ASSERT( i == 20 );
161             CPPUNIT_ASSERT( q.empty() );
162             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
163
164             v.nVal = -1;
165             CPPUNIT_ASSERT( !q.pop_back(v) );
166             CPPUNIT_ASSERT( v.nVal == -1 );
167             CPPUNIT_ASSERT( q.empty() );
168             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
169
170 #ifdef CDS_EMPLACE_SUPPORT
171             CPPUNIT_ASSERT( q.emplace_back( 157 ));
172             CPPUNIT_ASSERT( !q.empty() );
173             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
174
175             CPPUNIT_ASSERT( q.emplace_back( 158 ));
176             CPPUNIT_ASSERT( !q.empty() );
177             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
178
179             CPPUNIT_ASSERT( q.pop_front(i, pop_func) );
180             CPPUNIT_ASSERT( i == 157 );
181             CPPUNIT_ASSERT( !q.empty() );
182             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
183
184             CPPUNIT_ASSERT( q.pop_front(i, pop_functor()) );
185             CPPUNIT_ASSERT( i == 158 );
186             CPPUNIT_ASSERT( q.empty() );
187             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
188 #endif
189
190 #ifdef CDS_CXX11_LAMBDA_SUPPORT
191             CPPUNIT_ASSERT( q.push_back( value_type(511), [](value_type& dest, value_type const& i){ dest.nVal = i.nVal * 2; } ));
192             CPPUNIT_ASSERT( !q.empty() );
193             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
194
195             CPPUNIT_ASSERT( q.push_back( 512, [](value_type& dest, int i){ dest.nVal = i; } ));
196             CPPUNIT_ASSERT( !q.empty() );
197             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
198
199             CPPUNIT_ASSERT( q.pop_front( i, []( int& dest, value_type const& v){ dest = v.nVal; } ) );
200             CPPUNIT_ASSERT( i == 511 * 2 );
201             CPPUNIT_ASSERT( !q.empty() );
202             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
203
204             v.nVal = i = 0;
205             CPPUNIT_ASSERT( q.pop_front( i, [&v]( int& dest, value_type const& val){ dest = -val.nVal; v.nVal = val.nVal; }) );
206             CPPUNIT_ASSERT( i == -512 );
207             CPPUNIT_ASSERT( v.nVal == 512);
208             CPPUNIT_ASSERT( q.empty() );
209             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
210 #endif
211
212
213             // push_left/pop_left
214             CPPUNIT_ASSERT( q.push_front( value_type(5) ));
215             CPPUNIT_ASSERT( !q.empty() );
216             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
217
218             CPPUNIT_ASSERT( q.push_front( 10, assign_functor() )) ; // functor
219             CPPUNIT_ASSERT( !q.empty() );
220             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
221
222             CPPUNIT_ASSERT( q.push_front( 20, assign_func )) ;     // function
223             CPPUNIT_ASSERT( !q.empty() );
224             CPPUNIT_ASSERT( check_ic( q.size(), 3 ));
225
226             CPPUNIT_ASSERT( q.pop_front(v) );
227             CPPUNIT_ASSERT( v.nVal == 20 );
228             CPPUNIT_ASSERT( !q.empty() );
229             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
230
231             CPPUNIT_ASSERT( q.pop_front(v) );
232             CPPUNIT_ASSERT( v.nVal == 10 );
233             CPPUNIT_ASSERT( !q.empty() );
234             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
235
236             CPPUNIT_ASSERT( q.pop_front(v) );
237             CPPUNIT_ASSERT( v.nVal == 5 );
238             CPPUNIT_ASSERT( q.empty() );
239             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
240
241 #ifdef CDS_EMPLACE_SUPPORT
242             CPPUNIT_ASSERT( q.emplace_front( 157 ));
243             CPPUNIT_ASSERT( !q.empty() );
244             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
245
246             CPPUNIT_ASSERT( q.emplace_front( 158 ));
247             CPPUNIT_ASSERT( !q.empty() );
248             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
249
250             CPPUNIT_ASSERT( q.pop_front(i, pop_func) );
251             CPPUNIT_ASSERT( i == 158 );
252             CPPUNIT_ASSERT( !q.empty() );
253             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
254
255             CPPUNIT_ASSERT( q.pop_front(i, pop_functor()) );
256             CPPUNIT_ASSERT( i == 157 );
257             CPPUNIT_ASSERT( q.empty() );
258             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
259 #endif
260
261 #ifdef CDS_CXX11_LAMBDA_SUPPORT
262             CPPUNIT_ASSERT( q.push_front( value_type(511), [](value_type& dest, value_type const& i){ dest.nVal = i.nVal * 2; } ));
263             CPPUNIT_ASSERT( !q.empty() );
264             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
265
266             CPPUNIT_ASSERT( q.push_front( 512, [](value_type& dest, int i){ dest.nVal = i; } ));
267             CPPUNIT_ASSERT( !q.empty() );
268             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
269
270             CPPUNIT_ASSERT( q.pop_front( i, []( int& dest, value_type const& v){ dest = v.nVal; } ) );
271             CPPUNIT_ASSERT( i == 512 );
272             CPPUNIT_ASSERT( !q.empty() );
273             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
274
275             v.nVal = i = 0;
276             CPPUNIT_ASSERT( q.pop_front( i, [&v]( int& dest, value_type const& val){ dest = -val.nVal; v.nVal = val.nVal; }) );
277             CPPUNIT_ASSERT( i == -511 * 2 );
278             CPPUNIT_ASSERT( v.nVal == 511 * 2);
279             CPPUNIT_ASSERT( q.empty() );
280             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
281 #endif
282
283             // push_left/pop_right
284             CPPUNIT_ASSERT( q.push_front( value_type(5) ));
285             CPPUNIT_ASSERT( !q.empty() );
286             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
287
288             CPPUNIT_ASSERT( q.push_front( 10, assign_functor() )) ; // functor
289             CPPUNIT_ASSERT( !q.empty() );
290             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
291
292             CPPUNIT_ASSERT( q.push_front( 20, assign_func )) ;     // function
293             CPPUNIT_ASSERT( !q.empty() );
294             CPPUNIT_ASSERT( check_ic( q.size(), 3 ));
295
296             CPPUNIT_ASSERT( q.pop_back(v) );
297             CPPUNIT_ASSERT( v.nVal == 5 );
298             CPPUNIT_ASSERT( !q.empty() );
299             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
300
301             CPPUNIT_ASSERT( q.pop_back(v) );
302             CPPUNIT_ASSERT( v.nVal == 10 );
303             CPPUNIT_ASSERT( !q.empty() );
304             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
305
306             CPPUNIT_ASSERT( q.pop_back(v) );
307             CPPUNIT_ASSERT( v.nVal == 20 );
308             CPPUNIT_ASSERT( q.empty() );
309             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
310
311 #ifdef CDS_EMPLACE_SUPPORT
312             CPPUNIT_ASSERT( q.emplace_front( 157 ));
313             CPPUNIT_ASSERT( !q.empty() );
314             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
315
316             CPPUNIT_ASSERT( q.emplace_front( 158 ));
317             CPPUNIT_ASSERT( !q.empty() );
318             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
319
320             CPPUNIT_ASSERT( q.pop_back(i, pop_func) );
321             CPPUNIT_ASSERT( i == 157 );
322             CPPUNIT_ASSERT( !q.empty() );
323             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
324
325             CPPUNIT_ASSERT( q.pop_back(i, pop_functor()) );
326             CPPUNIT_ASSERT( i == 158 );
327             CPPUNIT_ASSERT( q.empty() );
328             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
329 #endif
330
331 #ifdef CDS_CXX11_LAMBDA_SUPPORT
332             CPPUNIT_ASSERT( q.push_front( value_type(511), [](value_type& dest, value_type const& i){ dest.nVal = i.nVal * 2; } ));
333             CPPUNIT_ASSERT( !q.empty() );
334             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
335
336             CPPUNIT_ASSERT( q.push_front( 512, [](value_type& dest, int i){ dest.nVal = i * 3; } ));
337             CPPUNIT_ASSERT( !q.empty() );
338             CPPUNIT_ASSERT( check_ic( q.size(), 2 ));
339
340             CPPUNIT_ASSERT( q.pop_back( i, []( int& dest, value_type const& v){ dest = v.nVal; } ) );
341             CPPUNIT_ASSERT( i == 511 * 2 );
342             CPPUNIT_ASSERT( !q.empty() );
343             CPPUNIT_ASSERT( check_ic( q.size(), 1 ));
344
345             v.nVal = i = 0;
346             CPPUNIT_ASSERT( q.pop_back( i, [&v]( int& dest, value_type const& val){ dest = -val.nVal; v.nVal = val.nVal; }) );
347             CPPUNIT_ASSERT( i == -512 * 3 );
348             CPPUNIT_ASSERT( v.nVal == 512 * 3);
349             CPPUNIT_ASSERT( q.empty() );
350             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
351 #endif
352
353             // clear test
354             for ( int i = 0; i < 1000; i++ ) {
355                 CPPUNIT_ASSERT( q.push_back( value_type(i) ));
356                 CPPUNIT_ASSERT( q.push_front( value_type(i * 1024) ));
357             }
358             CPPUNIT_ASSERT( !q.empty() );
359             CPPUNIT_ASSERT( check_ic( q.size(), 2000 ));
360             q.clear();
361             CPPUNIT_ASSERT( q.empty() );
362             CPPUNIT_ASSERT( check_ic( q.size(), 0 ));
363
364         }
365
366         void test_MichaelDeque_HP();
367         void test_MichaelDeque_HP_ic();
368         void test_MichaelDeque_HP_stat();
369         void test_MichaelDeque_HP_noalign();
370
371         void test_MichaelDeque_PTB();
372         void test_MichaelDeque_PTB_ic();
373         void test_MichaelDeque_PTB_stat();
374         void test_MichaelDeque_PTB_noalign();
375
376         CPPUNIT_TEST_SUITE(DequeHeaderTest)
377             CPPUNIT_TEST( test_MichaelDeque_HP);
378             CPPUNIT_TEST( test_MichaelDeque_HP_ic);
379             CPPUNIT_TEST( test_MichaelDeque_HP_stat);
380             CPPUNIT_TEST( test_MichaelDeque_HP_noalign);
381
382             CPPUNIT_TEST( test_MichaelDeque_PTB);
383             CPPUNIT_TEST( test_MichaelDeque_PTB_ic);
384             CPPUNIT_TEST( test_MichaelDeque_PTB_stat);
385             CPPUNIT_TEST( test_MichaelDeque_PTB_noalign);
386
387         CPPUNIT_TEST_SUITE_END()
388
389     };
390 }   // namespace deque