Replace NULL with nullptr
[libcds.git] / tests / test-hdr / ordered_list / hdr_michael.h
1 //$$CDS-header$$
2
3 #include "cppunit/cppunit_proxy.h"
4 #include <cds/container/michael_list_base.h>
5
6 namespace ordlist {
7     namespace cc = cds::container;
8     namespace co = cds::container::opt;
9
10     class MichaelListTestHeader: public CppUnitMini::TestCase
11     {
12     public:
13         struct stat {
14             int nEnsureExistsCall;
15             int nEnsureNewCall;
16
17             stat()
18             {
19                 nEnsureExistsCall
20                     = nEnsureNewCall
21                     = 0;
22             }
23         };
24
25         struct item {
26             int     nKey;
27             int     nVal;
28
29             stat    s;
30
31             item(int key)
32                 : nKey( key )
33                 , nVal( key * 2 )
34                 , s()
35             {}
36
37             item(int key, int val)
38                 : nKey( key )
39                 , nVal(val)
40                 , s()
41             {}
42
43             item( const item& v )
44                 : nKey( v.nKey )
45                 , nVal( v.nVal )
46                 , s()
47             {}
48
49             int key() const
50             {
51                 return nKey;
52             }
53         };
54
55         template <typename T>
56         struct lt
57         {
58             bool operator ()(const T& v1, const T& v2 ) const
59             {
60                 return v1.key() < v2.key();
61             }
62
63             template <typename Q>
64             bool operator ()(const T& v1, const Q& v2 ) const
65             {
66                 return v1.key() < v2;
67             }
68
69             template <typename Q>
70             bool operator ()(const Q& v1, const T& v2 ) const
71             {
72                 return v1 < v2.key();
73             }
74         };
75
76         template <typename T>
77         struct cmp {
78             int operator ()(const T& v1, const T& v2 ) const
79             {
80                 if ( v1.key() < v2.key() )
81                     return -1;
82                 return v1.key() > v2.key() ? 1 : 0;
83             }
84
85             template <typename Q>
86             int operator ()(const T& v1, const Q& v2 ) const
87             {
88                 if ( v1.key() < v2 )
89                     return -1;
90                 return v1.key() > v2 ? 1 : 0;
91             }
92
93             template <typename Q>
94             int operator ()(const Q& v1, const T& v2 ) const
95             {
96                 if ( v1 < v2.key() )
97                     return -1;
98                 return v1 > v2.key() ? 1 : 0;
99             }
100         };
101
102         struct insert_functor {
103             void operator ()( item& i )
104             {
105                 i.nVal = i.nKey * 1033;
106             }
107         };
108         struct dummy_insert_functor {
109             void operator ()( item& i )
110             {
111                 // This functor should not be called
112                 TestCase::current_test()->error( "CPPUNIT_ASSERT", "dummy_insert_functor should not be called", __FILE__, __LINE__ );
113             }
114         };
115
116         struct erase_functor {
117             unsigned int nEraseCall;
118
119             erase_functor()
120                 : nEraseCall(0)
121             {}
122
123             void operator()( item const& /*i*/)
124             {
125                 ++nEraseCall;
126             }
127         };
128
129         static void insert_function( item& i )
130         {
131             i.nVal = i.nKey * 1024;
132         }
133         static void dummy_insert_function( item& i )
134         {
135             // This function should not be called
136             TestCase::current_test()->error( "CPPUNIT_ASSERT", "dummy_insert_function should not be called", __FILE__, __LINE__ );
137         }
138
139
140         struct check_value {
141             unsigned int m_nMultiplier;
142
143             check_value( unsigned int nMultiplier )
144                 : m_nMultiplier( nMultiplier )
145             {}
146
147             check_value( const check_value& s )
148                 : m_nMultiplier( s.m_nMultiplier )
149             {}
150
151             void operator()( item& i, int )
152             {
153                 CPPUNIT_ASSERT_CURRENT( int(i.nKey * m_nMultiplier) == i.nVal );
154             }
155         };
156
157         struct check_exact_value {
158             int m_nExpected;
159
160             check_exact_value( int nExpected )
161                 : m_nExpected( nExpected )
162             {}
163
164             check_exact_value( check_exact_value const& s)
165                 : m_nExpected( s.m_nExpected )
166             {}
167
168             void operator()( item& i, int )
169             {
170                 CPPUNIT_ASSERT_CURRENT( i.nVal == m_nExpected );
171             }
172         };
173
174         struct dummy_check_value {
175             void operator()( item& i, int )
176             {
177                 // This functor should not be called
178                 TestCase::current_test()->error( "CPPUNIT_ASSERT", "dummy_check_value should not be called", __FILE__, __LINE__ );
179             }
180         };
181
182         struct ensure_functor {
183             void operator()( bool bNew, item& i, int n )
184             {
185                 i.nVal = i.nKey * 1024;
186             }
187         };
188
189         static void ensure_func( bool bNew, item& i, int n )
190         {
191             i.nVal = n * 1033;
192         }
193
194         struct other_item
195         {
196             int nKey;
197
198             other_item()
199             {}
200
201             other_item(int n)
202                 : nKey(n)
203             {}
204         };
205
206         struct other_less
207         {
208             template <typename T1, typename T2>
209             bool operator()( T1 const& t1, T2 const& t2 ) const
210             {
211                 return t1.nKey < t2.nKey;
212             }
213         };
214
215     protected:
216         template <class OrdList>
217         void test_with( OrdList& l )
218         {
219             typedef typename OrdList::value_type    value_type;
220
221             // The list should be empty
222             CPPUNIT_ASSERT( l.empty() );
223
224             // insert test
225             CPPUNIT_ASSERT( l.insert( 50 ) );
226             CPPUNIT_ASSERT( l.insert( item( 25 )) );
227             CPPUNIT_ASSERT( l.insert( item( 100 )) );
228
229             // insert failed - such key exists
230             CPPUNIT_ASSERT( !l.insert( 50 ) );
231             CPPUNIT_ASSERT( !l.insert( item( 100 )) );
232
233             // clear test
234
235             // The list should not be empty
236             CPPUNIT_ASSERT( !l.empty() );
237             l.clear();
238             // and now the list is empty
239             CPPUNIT_ASSERT( l.empty() );
240
241             // Test insert with functor
242
243             CPPUNIT_ASSERT( l.insert( 100, insert_functor() ) );
244             // passed by ref
245             {
246                 insert_functor f;
247                 CPPUNIT_ASSERT( l.insert( item(25), boost::ref(f)) );
248                 CPPUNIT_ASSERT( !l.insert( item(100), boost::ref(f)) );
249             }
250             // Test insert with function
251             CPPUNIT_ASSERT( l.insert( 50, insert_function ));
252             CPPUNIT_ASSERT( !l.insert( 25, dummy_insert_function ));
253             CPPUNIT_ASSERT( !l.insert( 100, dummy_insert_functor() ));
254
255             // The list should not be empty
256             CPPUNIT_ASSERT( !l.empty() );
257
258             // Check inserted values
259             {
260                 int i;
261                 i = 100;
262                 CPPUNIT_ASSERT( l.find( 100 ));
263                 CPPUNIT_ASSERT( l.find( i, check_value(1033) ));
264                 {
265                     check_value f(1033);
266                     i = 25;
267                     CPPUNIT_ASSERT( l.find_with( 25, lt<value_type>() ));
268                     CPPUNIT_ASSERT( l.find_with( i, lt<value_type>(), boost::ref(f) ));
269                 }
270                 i = 50;
271                 CPPUNIT_ASSERT( l.find( 50 ));
272                 CPPUNIT_ASSERT( l.find( i, check_value(1024) ));
273
274                 i = 10;
275                 CPPUNIT_ASSERT( !l.find_with( 10, lt<value_type>() ));
276                 CPPUNIT_ASSERT( !l.find_with( i, lt<value_type>(), dummy_check_value() ));
277                 i = 75;
278                 CPPUNIT_ASSERT( !l.find( 75 ));
279                 CPPUNIT_ASSERT( !l.find( i, dummy_check_value() ));
280                 i = 150;
281                 CPPUNIT_ASSERT( !l.find( 150 ));
282                 CPPUNIT_ASSERT( !l.find( i, dummy_check_value() ));
283             }
284
285             // The list should not be empty
286             CPPUNIT_ASSERT( !l.empty() );
287             l.clear();
288             // and now the list is empty
289             CPPUNIT_ASSERT( l.empty() );
290
291             // Ensure test
292             {
293                 std::pair<bool, bool>   ensureResult;
294                 ensure_functor f;
295                 ensureResult = l.ensure( 100, ensure_functor() );
296                 CPPUNIT_ASSERT( ensureResult.first );
297                 CPPUNIT_ASSERT( ensureResult.second );
298
299                 ensureResult = l.ensure( 200, boost::ref(f) );
300                 CPPUNIT_ASSERT( ensureResult.first );
301                 CPPUNIT_ASSERT( ensureResult.second );
302
303                 ensureResult = l.ensure( 50, ensure_func );
304                 CPPUNIT_ASSERT( ensureResult.first );
305                 CPPUNIT_ASSERT( ensureResult.second );
306
307                 int i;
308                 i = 100;
309                 CPPUNIT_ASSERT( l.find( i, check_value(1024) ));
310                 i = 50;
311                 CPPUNIT_ASSERT( l.find( i, check_value(1033) ));
312                 i = 200;
313                 CPPUNIT_ASSERT( l.find( i, check_value(1024) ));
314
315                 // ensure existing key
316                 ensureResult = l.ensure( 200, ensure_func );
317                 CPPUNIT_ASSERT( ensureResult.first );
318                 CPPUNIT_ASSERT( !ensureResult.second );
319                 i = 200;
320                 CPPUNIT_ASSERT( l.find( i, check_value(1033) ));
321
322                 ensureResult = l.ensure( 50, ensure_functor() );
323                 CPPUNIT_ASSERT( ensureResult.first );
324                 CPPUNIT_ASSERT( !ensureResult.second );
325                 i = 50;
326                 CPPUNIT_ASSERT( l.find( i, check_value(1024) ));
327             }
328
329             // erase test (list: 50, 100, 200)
330             CPPUNIT_ASSERT( !l.empty() );
331             CPPUNIT_ASSERT( l.insert(160));
332             CPPUNIT_ASSERT( l.insert(250));
333             CPPUNIT_ASSERT( !l.empty() );
334
335             CPPUNIT_ASSERT( !l.erase( 150 ));
336
337             CPPUNIT_ASSERT( l.erase( 100 ));
338             CPPUNIT_ASSERT( !l.erase( 100 ));
339
340             CPPUNIT_ASSERT( l.erase_with( 200, lt<value_type>() ));
341             CPPUNIT_ASSERT( !l.erase_with( 200, lt<value_type>() ));
342
343             {
344                 erase_functor ef;
345                 CPPUNIT_ASSERT( ef.nEraseCall == 0 );
346                 CPPUNIT_ASSERT( l.erase_with( 160, lt<value_type>(), cds::ref(ef) ));
347                 CPPUNIT_ASSERT( ef.nEraseCall == 1 );
348                 CPPUNIT_ASSERT( !l.erase_with( 160, lt<value_type>(), cds::ref(ef) ));
349                 CPPUNIT_ASSERT( ef.nEraseCall == 1 );
350
351                 CPPUNIT_ASSERT( l.erase( 250, cds::ref(ef) ));
352                 CPPUNIT_ASSERT( ef.nEraseCall == 2 );
353                 CPPUNIT_ASSERT( !l.erase( 250, cds::ref(ef) ));
354                 CPPUNIT_ASSERT( ef.nEraseCall == 2 );
355             }
356
357             CPPUNIT_ASSERT( l.erase( 50 ));
358             CPPUNIT_ASSERT( !l.erase( 50 ));
359
360             CPPUNIT_ASSERT( l.empty() );
361
362             // clear empty list
363             l.clear();
364             CPPUNIT_ASSERT( l.empty() );
365
366 #ifdef CDS_EMPLACE_SUPPORT
367             {
368                 int i;
369
370                 // insert test
371                 CPPUNIT_ASSERT( l.emplace( 501 ) );
372                 CPPUNIT_ASSERT( l.emplace( 251, 152 ));
373                 CPPUNIT_ASSERT( l.emplace( item( 1001 )) );
374
375                 // insert failed - such key exists
376                 CPPUNIT_ASSERT( !l.emplace( 501, 2 ) );
377                 CPPUNIT_ASSERT( !l.emplace( 251, 10) );
378
379                 i = 501;
380                 CPPUNIT_ASSERT( l.find( i, check_exact_value(501*2) ));
381                 i = 251;
382                 CPPUNIT_ASSERT( l.find( i, check_exact_value(152) ));
383                 i = 1001;
384                 CPPUNIT_ASSERT( l.find( i, check_exact_value(1001*2) ));
385
386                 l.clear();
387                 CPPUNIT_ASSERT( l.empty() );
388             }
389 #endif
390
391             // Iterator test
392             {
393                 int nCount = 100;
394                 for ( int i = 0; i < nCount; ++i )
395                     CPPUNIT_ASSERT( l.insert(i) );
396
397                 int i = 0;
398                 for ( typename OrdList::iterator it = l.begin(), itEnd = l.end(); it != itEnd; ++it, ++i ) {
399                     it->nVal = i * 2;
400                     CPPUNIT_ASSERT( it->nKey == i );
401                 }
402
403                 // Check that we have visited all items
404                 for ( int i = 0; i < nCount; ++i )
405                     CPPUNIT_ASSERT( l.find( i, check_value(2) ));
406
407                 l.clear();
408                 CPPUNIT_ASSERT( l.empty() );
409
410                 // Const iterator
411                 for ( int i = 0; i < nCount; ++i )
412                     CPPUNIT_ASSERT( l.insert(i) );
413
414                 i = 0;
415                 const OrdList& rl = l;
416                 for ( typename OrdList::const_iterator it = rl.begin(), itEnd = rl.end(); it != itEnd; ++it, ++i ) {
417                     // it->nVal = i * 2    ;    // not!
418                     CPPUNIT_ASSERT( it->nKey == i );
419                 }
420
421                 // Check that we have visited all items
422                 for ( int i = 0; i < nCount; ++i )
423                     CPPUNIT_ASSERT( l.find( i, check_value(2) ));
424
425                 l.clear();
426                 CPPUNIT_ASSERT( l.empty() );
427             }
428         }
429
430         template <typename OrdList>
431         void test()
432         {
433             typedef typename OrdList::guarded_ptr guarded_ptr;
434             typedef typename OrdList::value_type value_type;
435
436             OrdList l;
437             test_with(l);
438
439             static int const nLimit = 20;
440             int arr[nLimit];
441             for ( int i = 0; i < nLimit; i++ )
442                 arr[i] = i;
443             std::random_shuffle( arr, arr + nLimit );
444
445             // extract/get
446             for ( int i = 0; i < nLimit; ++i )
447                 l.insert( arr[i] );
448             {
449                 guarded_ptr gp;
450                 for ( int i = 0; i < nLimit; ++i ) {
451                     int nKey = arr[i];
452
453                     CPPUNIT_ASSERT( l.get(gp, nKey));
454                     CPPUNIT_ASSERT( !gp.empty());
455                     CPPUNIT_CHECK( gp->nKey == nKey );
456                     CPPUNIT_CHECK( gp->nVal == nKey * 2 );
457                     gp.release();
458
459                     CPPUNIT_ASSERT( l.extract(gp, nKey));
460                     CPPUNIT_ASSERT( !gp.empty());
461                     CPPUNIT_CHECK( gp->nKey == nKey );
462                     CPPUNIT_CHECK( gp->nVal == nKey*2 );
463                     gp.release();
464
465                     CPPUNIT_CHECK( !l.get(gp, nKey));
466                     CPPUNIT_CHECK( gp.empty());
467                     CPPUNIT_CHECK( !l.extract( gp, nKey));
468                     CPPUNIT_CHECK( gp.empty());
469                 }
470                 CPPUNIT_ASSERT( l.empty());
471                 CPPUNIT_CHECK( !l.get(gp, arr[0]));
472                 CPPUNIT_CHECK( gp.empty());
473                 CPPUNIT_CHECK( !l.extract( gp, arr[0]));
474                 CPPUNIT_CHECK( gp.empty());
475             }
476
477             // extract_with/get_with
478             for ( int i = 0; i < nLimit; ++i )
479                 l.insert( arr[i] );
480             {
481                 guarded_ptr gp;
482                 for ( int i = 0; i < nLimit; ++i ) {
483                     int nKey = arr[i];
484                     other_item key( nKey );
485
486                     CPPUNIT_ASSERT( l.get_with(gp, key, other_less()));
487                     CPPUNIT_ASSERT( !gp.empty());
488                     CPPUNIT_CHECK( gp->nKey == nKey );
489                     CPPUNIT_CHECK( gp->nVal == nKey * 2 );
490                     gp.release();
491
492                     CPPUNIT_ASSERT( l.extract_with(gp, key, other_less()));
493                     CPPUNIT_ASSERT( !gp.empty());
494                     CPPUNIT_CHECK( gp->nKey == nKey );
495                     CPPUNIT_CHECK( gp->nVal == nKey*2 );
496                     gp.release();
497
498                     CPPUNIT_CHECK( !l.get_with(gp, key, other_less()));
499                     CPPUNIT_CHECK( gp.empty());
500                     CPPUNIT_CHECK( !l.extract_with( gp, key, other_less()));
501                     CPPUNIT_CHECK( gp.empty());
502                 }
503                 CPPUNIT_ASSERT( l.empty());
504                 CPPUNIT_CHECK( !l.get_with(gp, other_item(arr[0]), other_less()));
505                 CPPUNIT_CHECK( gp.empty());
506                 CPPUNIT_CHECK( !l.extract_with( gp, other_item(arr[0]), other_less()));
507                 CPPUNIT_CHECK( gp.empty());
508             }
509         }
510
511         template <typename OrdList>
512         void test_rcu()
513         {
514             OrdList l;
515             test_with(l);
516
517             static int const nLimit = 20;
518
519             typedef typename OrdList::rcu_lock rcu_lock;
520             typedef typename OrdList::value_type value_type;
521             typedef typename OrdList::gc rcu_type;
522
523             {
524                 int a[nLimit];
525                 for (int i = 0; i < nLimit; ++i)
526                     a[i]=i;
527                 std::random_shuffle( a, a + nLimit );
528
529                 // extract/get
530                 for ( int i = 0; i < nLimit; ++i )
531                     CPPUNIT_ASSERT( l.insert( a[i] ) );
532
533                 typename OrdList::exempt_ptr ep;
534
535                 for ( int i = 0; i < nLimit; ++i ) {
536                     {
537                         rcu_lock lock;
538                         value_type * pGet = l.get( a[i] );
539                         CPPUNIT_ASSERT( pGet != nullptr );
540                         CPPUNIT_CHECK( pGet->nKey == a[i] );
541                         CPPUNIT_CHECK( pGet->nVal == a[i] * 2 );
542
543                         CPPUNIT_ASSERT( l.extract( ep, a[i] ));
544                         CPPUNIT_ASSERT( !ep.empty() );
545                         CPPUNIT_CHECK( ep->nKey == a[i] );
546                         CPPUNIT_CHECK( (*ep).nVal == a[i] * 2 );
547                     }
548                     ep.release();
549                     {
550                         rcu_lock lock;
551                         CPPUNIT_CHECK( l.get( a[i] ) == nullptr );
552                         CPPUNIT_CHECK( !l.extract( ep, a[i] ));
553                         CPPUNIT_CHECK( ep.empty() );
554                     }
555                 }
556                 CPPUNIT_ASSERT( l.empty() );
557
558                 {
559                     rcu_lock lock;
560                     CPPUNIT_CHECK( l.get( a[0] ) == nullptr );
561                     CPPUNIT_CHECK( !l.extract( ep, a[0] ) );
562                     CPPUNIT_CHECK( ep.empty() );
563                 }
564
565                 // extract_with/get_with
566                 for ( int i = 0; i < nLimit; ++i ) {
567                     CPPUNIT_ASSERT( l.insert( a[i] ) );
568                 }
569
570                 for ( int i = 0; i < nLimit; ++i ) {
571                     other_item itm( a[i] );
572                     {
573                         rcu_lock lock;
574                         value_type * pGet = l.get_with( itm, other_less() );
575                         CPPUNIT_ASSERT( pGet != nullptr );
576                         CPPUNIT_CHECK( pGet->nKey == a[i] );
577                         CPPUNIT_CHECK( pGet->nVal == a[i] * 2 );
578
579                         CPPUNIT_ASSERT( l.extract_with( ep, itm, other_less() ));
580                         CPPUNIT_ASSERT( !ep.empty() );
581                         CPPUNIT_CHECK( ep->nKey == a[i] );
582                         CPPUNIT_CHECK( ep->nVal == a[i] * 2 );
583                     }
584                     ep.release();
585                     {
586                         rcu_lock lock;
587                         CPPUNIT_CHECK( l.get_with( itm, other_less() ) == nullptr );
588                         CPPUNIT_CHECK( !l.extract_with( ep, itm, other_less() ));
589                         CPPUNIT_CHECK( ep.empty() );
590                     }
591                 }
592                 CPPUNIT_ASSERT( l.empty() );
593
594                 {
595                     rcu_lock lock;
596                     CPPUNIT_CHECK( l.get_with( other_item( 0 ), other_less() ) == nullptr );
597                     CPPUNIT_CHECK( !l.extract_with( ep, other_item(0), other_less() ));
598                     CPPUNIT_CHECK( ep.empty() );
599                 }
600             }
601
602         }
603
604         template <class OrdList>
605         void nogc_test()
606         {
607             typedef OrdList list;
608             typedef typename list::value_type    value_type;
609             typedef std::pair<typename list::iterator, bool> ensure_result;
610
611             typename list::iterator it;
612
613             list l;
614             CPPUNIT_ASSERT( l.empty() );
615             CPPUNIT_ASSERT( l.insert(50) != l.end() );
616             CPPUNIT_ASSERT( !l.empty() );
617
618             ensure_result eres = l.ensure( item(100, 33) );
619             CPPUNIT_ASSERT( eres.second );
620             CPPUNIT_ASSERT( eres.first != l.end() );
621             CPPUNIT_ASSERT( l.insert( item(150) ) != l.end() );
622
623             CPPUNIT_ASSERT( l.insert(100) == l.end() );
624             eres = l.ensure( item(50, 33) );
625             CPPUNIT_ASSERT( !eres.second );
626             CPPUNIT_ASSERT( eres.first->nVal == eres.first->nKey * 2 );
627             eres.first->nVal = 63;
628
629             it = l.find( 33 );
630             CPPUNIT_ASSERT( it == l.end() );
631
632             it = l.find( 50 );
633             CPPUNIT_ASSERT( it != l.end() );
634             CPPUNIT_ASSERT( it->nKey == 50 );
635             CPPUNIT_ASSERT( it->nVal == 63 );
636
637             it = l.find_with( 100, lt<value_type>() );
638             CPPUNIT_ASSERT( it != l.end() );
639             CPPUNIT_ASSERT( it->nKey == 100 );
640             CPPUNIT_ASSERT( it->nVal == 33 );
641
642             it = l.find( 150 );
643             CPPUNIT_ASSERT( it != l.end() );
644             CPPUNIT_ASSERT( it->nKey == 150 );
645             CPPUNIT_ASSERT( it->nVal == it->nKey * 2 );
646
647             CPPUNIT_ASSERT( !l.empty() );
648             l.clear();
649             CPPUNIT_ASSERT( l.empty() );
650
651 #ifdef CDS_EMPLACE_SUPPORT
652             // insert test
653             CPPUNIT_ASSERT( l.emplace( 501 ) != l.end() );
654             CPPUNIT_ASSERT( l.emplace( 251, 152 ) != l.end());
655             CPPUNIT_ASSERT( l.emplace( item( 1001 )) != l.end() );
656
657             // insert failed - such key exists
658             CPPUNIT_ASSERT( l.emplace( 501, 2 ) == l.end() );
659             CPPUNIT_ASSERT( l.emplace( 251, 10) == l.end() );
660
661             it = l.find( 501 );
662             CPPUNIT_ASSERT( it != l.end() );
663             CPPUNIT_ASSERT( it->nKey == 501 );
664             CPPUNIT_ASSERT( it->nVal == 501 * 2 );
665
666             it = l.find( 251 );
667             CPPUNIT_ASSERT( it != l.end() );
668             CPPUNIT_ASSERT( it->nKey == 251 );
669             CPPUNIT_ASSERT( it->nVal == 152 );
670
671             it = l.find( 1001 );
672             CPPUNIT_ASSERT( it != l.end() );
673             CPPUNIT_ASSERT( it->nKey == 1001 );
674             CPPUNIT_ASSERT( it->nVal == 1001 * 2 );
675
676             l.clear();
677             CPPUNIT_ASSERT( l.empty() );
678 #endif
679         }
680
681         void HP_cmp();
682         void HP_less();
683         void HP_cmpmix();
684         void HP_ic();
685
686         void PTB_cmp();
687         void PTB_less();
688         void PTB_cmpmix();
689         void PTB_ic();
690
691         void HRC_cmp();
692         void HRC_less();
693         void HRC_cmpmix();
694         void HRC_ic();
695
696         void RCU_GPI_cmp();
697         void RCU_GPI_less();
698         void RCU_GPI_cmpmix();
699         void RCU_GPI_ic();
700
701         void RCU_GPB_cmp();
702         void RCU_GPB_less();
703         void RCU_GPB_cmpmix();
704         void RCU_GPB_ic();
705
706         void RCU_GPT_cmp();
707         void RCU_GPT_less();
708         void RCU_GPT_cmpmix();
709         void RCU_GPT_ic();
710
711         void RCU_SHB_cmp();
712         void RCU_SHB_less();
713         void RCU_SHB_cmpmix();
714         void RCU_SHB_ic();
715
716         void RCU_SHT_cmp();
717         void RCU_SHT_less();
718         void RCU_SHT_cmpmix();
719         void RCU_SHT_ic();
720
721         void NOGC_cmp();
722         void NOGC_less();
723         void NOGC_cmpmix();
724         void NOGC_ic();
725
726         CPPUNIT_TEST_SUITE(MichaelListTestHeader)
727             CPPUNIT_TEST(HP_cmp)
728             CPPUNIT_TEST(HP_less)
729             CPPUNIT_TEST(HP_cmpmix)
730             CPPUNIT_TEST(HP_ic)
731
732             CPPUNIT_TEST(PTB_cmp)
733             CPPUNIT_TEST(PTB_less)
734             CPPUNIT_TEST(PTB_cmpmix)
735             CPPUNIT_TEST(PTB_ic)
736
737             CPPUNIT_TEST(HRC_cmp)
738             CPPUNIT_TEST(HRC_less)
739             CPPUNIT_TEST(HRC_cmpmix)
740             CPPUNIT_TEST(HRC_ic)
741
742             CPPUNIT_TEST(RCU_GPI_cmp)
743             CPPUNIT_TEST(RCU_GPI_less)
744             CPPUNIT_TEST(RCU_GPI_cmpmix)
745             CPPUNIT_TEST(RCU_GPI_ic)
746
747             CPPUNIT_TEST(RCU_GPB_cmp)
748             CPPUNIT_TEST(RCU_GPB_less)
749             CPPUNIT_TEST(RCU_GPB_cmpmix)
750             CPPUNIT_TEST(RCU_GPB_ic)
751
752             CPPUNIT_TEST(RCU_GPT_cmp)
753             CPPUNIT_TEST(RCU_GPT_less)
754             CPPUNIT_TEST(RCU_GPT_cmpmix)
755             CPPUNIT_TEST(RCU_GPT_ic)
756
757             CPPUNIT_TEST(RCU_SHB_cmp)
758             CPPUNIT_TEST(RCU_SHB_less)
759             CPPUNIT_TEST(RCU_SHB_cmpmix)
760             CPPUNIT_TEST(RCU_SHB_ic)
761
762             CPPUNIT_TEST(RCU_SHT_cmp)
763             CPPUNIT_TEST(RCU_SHT_less)
764             CPPUNIT_TEST(RCU_SHT_cmpmix)
765             CPPUNIT_TEST(RCU_SHT_ic)
766
767             CPPUNIT_TEST(NOGC_cmp)
768             CPPUNIT_TEST(NOGC_less)
769             CPPUNIT_TEST(NOGC_cmpmix)
770             CPPUNIT_TEST(NOGC_ic)
771         CPPUNIT_TEST_SUITE_END()
772     };
773
774 }   // namespace ordlist