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