28c388874eb1f34058ec6ddb8035ecfad1090b76
[libcds.git] / tests / test-hdr / ordered_list / hdr_lazy.h
1 //$$CDS-header$$
2
3 #include "cppunit/cppunit_proxy.h"
4 #include <cds/container/details/lazy_list_base.h>
5
6 namespace ordlist {
7     namespace cc = cds::container;
8     namespace co = cds::container::opt;
9
10     class LazyListTestHeader: 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( item const& 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         static void insert_function( item& i )
117         {
118             i.nVal = i.nKey * 1024;
119         }
120         static void dummy_insert_function( item& /*i*/ )
121         {
122             // This function should not be called
123             TestCase::current_test()->error( "CPPUNIT_ASSERT", "dummy_insert_function should not be called", __FILE__, __LINE__ );
124         }
125
126         struct erase_functor {
127             unsigned int nEraseCall;
128
129             erase_functor()
130                 : nEraseCall(0)
131             {}
132
133             void operator()( item const& /*i*/)
134             {
135                 ++nEraseCall;
136             }
137         };
138
139         struct check_value {
140             unsigned int m_nMultiplier;
141
142             check_value( unsigned int nMultiplier )
143                 : m_nMultiplier( nMultiplier )
144             {}
145
146             check_value( const check_value& s )
147                 : m_nMultiplier( s.m_nMultiplier )
148             {}
149
150             void operator()( item& i, int )
151             {
152                 CPPUNIT_ASSERT_CURRENT( int(i.nKey * m_nMultiplier) == i.nVal );
153             }
154         };
155
156         struct check_exact_value {
157             int m_nExpected;
158
159             check_exact_value( int nExpected )
160                 : m_nExpected( nExpected )
161             {}
162
163             check_exact_value( check_exact_value const& s)
164                 : m_nExpected( s.m_nExpected )
165             {}
166
167             void operator()( item& i, int )
168             {
169                 CPPUNIT_ASSERT_CURRENT( i.nVal == m_nExpected );
170             }
171         };
172
173         struct dummy_check_value {
174             void operator()( item& /*i*/, int )
175             {
176                 // This functor should not be called
177                 TestCase::current_test()->error( "CPPUNIT_ASSERT", "dummy_check_value should not be called", __FILE__, __LINE__ );
178             }
179         };
180
181         struct ensure_functor {
182             void operator()( bool /*bNew*/, item& i, int /*n*/ )
183             {
184                 i.nVal = i.nKey * 1024;
185             }
186         };
187
188         static void ensure_func( bool /*bNew*/, item& i, int n )
189         {
190             i.nVal = n * 1033;
191         }
192
193         struct other_item
194         {
195             int nKey;
196
197             other_item()
198             {}
199
200             other_item(int n)
201                 : nKey(n)
202             {}
203         };
204
205         struct other_less
206         {
207             template <typename T1, typename T2>
208             bool operator()( T1 const& t1, T2 const& t2 ) const
209             {
210                 return t1.nKey < t2.nKey;
211             }
212         };
213
214     protected:
215         template <class OrdList>
216         void test_with( OrdList& l )
217         {
218             typedef typename OrdList::value_type    value_type;
219
220             // The list should be empty
221             CPPUNIT_ASSERT( l.empty() );
222
223             // insert test
224             CPPUNIT_ASSERT( l.insert( 50 ) );
225             CPPUNIT_ASSERT( l.insert( item( 25 )) );
226             CPPUNIT_ASSERT( l.insert( item( 100 )) );
227
228             // insert failed - such key exists
229             CPPUNIT_ASSERT( !l.insert( 50 ) );
230             CPPUNIT_ASSERT( !l.insert( item( 100 )) );
231
232             // clear test
233
234             // The list should not be empty
235             CPPUNIT_ASSERT( !l.empty() );
236             l.clear();
237             // and now the list is empty
238             CPPUNIT_ASSERT( l.empty() );
239
240             // Test insert with functor
241
242             CPPUNIT_ASSERT( l.insert( 100, insert_functor() ) );
243             // passed by ref
244             {
245                 insert_functor f;
246                 CPPUNIT_ASSERT( l.insert( item( 25 ), std::ref( f ) ) );
247                 CPPUNIT_ASSERT( !l.insert( item( 100 ), std::ref( f ) ) );
248             }
249             // Test insert with function
250             CPPUNIT_ASSERT( l.insert( 50, insert_function ));
251             CPPUNIT_ASSERT( !l.insert( 25, dummy_insert_function ));
252             CPPUNIT_ASSERT( !l.insert( 100, dummy_insert_functor() ));
253
254             // The list should not be empty
255             CPPUNIT_ASSERT( !l.empty() );
256
257             // Check inserted values
258             {
259                 int i;
260                 i = 100;
261
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>(), std::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, std::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>(), std::ref(ef) ));
347                 CPPUNIT_ASSERT( ef.nEraseCall == 1 );
348                 CPPUNIT_ASSERT( !l.erase_with( 160, lt<value_type>(), std::ref(ef) ));
349                 CPPUNIT_ASSERT( ef.nEraseCall == 1 );
350
351                 CPPUNIT_ASSERT( l.erase( 250, std::ref(ef) ));
352                 CPPUNIT_ASSERT( ef.nEraseCall == 2 );
353                 CPPUNIT_ASSERT( !l.erase( 250, std::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             {
367                 int i;
368                 // insert test
369                 CPPUNIT_ASSERT( l.emplace( 501 ) );
370                 CPPUNIT_ASSERT( l.emplace( 251, 152 ));
371                 CPPUNIT_ASSERT( l.emplace( item( 1001 )) );
372
373                 // insert failed - such key exists
374                 CPPUNIT_ASSERT( !l.emplace( 501, 2 ) );
375                 CPPUNIT_ASSERT( !l.emplace( 251, 10) );
376
377                 i = 501;
378                 CPPUNIT_ASSERT( l.find( i, check_exact_value(501*2) ));
379                 i = 251;
380                 CPPUNIT_ASSERT( l.find( i, check_exact_value(152) ));
381                 i = 1001;
382                 CPPUNIT_ASSERT( l.find( i, check_exact_value(1001*2) ));
383
384                 l.clear();
385                 CPPUNIT_ASSERT( l.empty() );
386             }
387
388             // Iterator test
389             {
390                 int nCount = 100;
391                 for ( int i = 0; i < nCount; ++i )
392                     CPPUNIT_ASSERT( l.insert( i ) );
393
394                 {
395                     typename OrdList::iterator it( l.begin() );
396                     typename OrdList::const_iterator cit( l.cbegin() );
397                     CPPUNIT_CHECK( it == cit );
398                     CPPUNIT_CHECK( it != l.end() );
399                     CPPUNIT_CHECK( it != l.cend() );
400                     CPPUNIT_CHECK( cit != l.end() );
401                     CPPUNIT_CHECK( cit != l.cend() );
402                     ++it;
403                     CPPUNIT_CHECK( it != cit );
404                     CPPUNIT_CHECK( it != l.end() );
405                     CPPUNIT_CHECK( it != l.cend() );
406                     CPPUNIT_CHECK( cit != l.end() );
407                     CPPUNIT_CHECK( cit != l.cend() );
408                     ++cit;
409                     CPPUNIT_CHECK( it == cit );
410                     CPPUNIT_CHECK( it != l.end() );
411                     CPPUNIT_CHECK( it != l.cend() );
412                     CPPUNIT_CHECK( cit != l.end() );
413                     CPPUNIT_CHECK( cit != l.cend() );
414                 }
415
416                 int i = 0;
417                 for ( typename OrdList::iterator it = l.begin(), itEnd = l.end(); it != itEnd; ++it, ++i ) {
418                     it->nVal = i * 2;
419                     CPPUNIT_ASSERT( it->nKey == i );
420                 }
421
422                 // Check that we have visited all items
423                 for ( int i = 0; i < nCount; ++i )
424                     CPPUNIT_ASSERT( l.find( i, check_value(2) ));
425
426                 l.clear();
427                 CPPUNIT_ASSERT( l.empty() );
428
429                 // Const iterator
430                 for ( int i = 0; i < nCount; ++i )
431                     CPPUNIT_ASSERT( l.insert(i) );
432
433                 i = 0;
434                 const OrdList& rl = l;
435                 for ( typename OrdList::const_iterator it = rl.begin(), itEnd = rl.end(); it != itEnd; ++it, ++i ) {
436                     // it->nVal = i * 2    ;    // not!
437                     CPPUNIT_ASSERT( it->nKey == i );
438                 }
439
440                 // Check that we have visited all items
441                 for ( int i = 0; i < nCount; ++i )
442                     CPPUNIT_ASSERT( l.find_with( i, lt<value_type>(), check_value(2) ));
443
444                 l.clear();
445                 CPPUNIT_ASSERT( l.empty() );
446             }
447         }
448
449         template <class OrdList>
450         void test()
451         {
452             typedef typename OrdList::guarded_ptr guarded_ptr;
453             typedef typename OrdList::value_type value_type;
454
455             OrdList l;
456             test_with( l );
457
458             static int const nLimit = 20;
459             int arr[nLimit];
460             for ( int i = 0; i < nLimit; i++ )
461                 arr[i] = i;
462             std::random_shuffle( arr, arr + nLimit );
463
464             // extract/get
465             for ( int i = 0; i < nLimit; ++i )
466                 l.insert( arr[i] );
467             {
468                 guarded_ptr gp;
469                 for ( int i = 0; i < nLimit; ++i ) {
470                     int nKey = arr[i];
471
472                     gp = l.get( nKey );
473                     CPPUNIT_ASSERT( gp );
474                     CPPUNIT_ASSERT( !gp.empty());
475                     CPPUNIT_CHECK( gp->nKey == nKey );
476                     CPPUNIT_CHECK( gp->nVal == nKey * 2 );
477                     gp.release();
478
479                     gp = l.extract( nKey );
480                     CPPUNIT_ASSERT( gp );
481                     CPPUNIT_ASSERT( !gp.empty());
482                     CPPUNIT_CHECK( gp->nKey == nKey );
483                     CPPUNIT_CHECK( gp->nVal == nKey*2 );
484                     gp.release();
485
486                     gp = l.get( nKey );
487                     CPPUNIT_CHECK( !gp );
488                     CPPUNIT_CHECK( gp.empty());
489                     CPPUNIT_CHECK( !l.extract( nKey));
490                     CPPUNIT_CHECK( gp.empty());
491                 }
492                 CPPUNIT_ASSERT( l.empty());
493                 CPPUNIT_CHECK( !l.get(arr[0]));
494                 CPPUNIT_CHECK( gp.empty());
495                 CPPUNIT_CHECK( !l.extract( arr[0]));
496                 CPPUNIT_CHECK( gp.empty());
497             }
498
499             // extract_with/get_with
500             for ( int i = 0; i < nLimit; ++i )
501                 l.insert( arr[i] );
502             {
503                 guarded_ptr gp;
504                 for ( int i = 0; i < nLimit; ++i ) {
505                     int nKey = arr[i];
506                     other_item key( nKey );
507
508                     gp = l.get_with( key, other_less() );
509                     CPPUNIT_ASSERT( gp );
510                     CPPUNIT_ASSERT( !gp.empty());
511                     CPPUNIT_CHECK( gp->nKey == nKey );
512                     CPPUNIT_CHECK( gp->nVal == nKey * 2 );
513                     gp.release();
514
515                     gp = l.extract_with( key, other_less() );
516                     CPPUNIT_ASSERT( gp );
517                     CPPUNIT_ASSERT( !gp.empty());
518                     CPPUNIT_CHECK( gp->nKey == nKey );
519                     CPPUNIT_CHECK( gp->nVal == nKey*2 );
520                     gp.release();
521
522                     gp = l.get_with( key, other_less() );
523                     CPPUNIT_CHECK( !gp );
524                     CPPUNIT_CHECK( gp.empty());
525                     CPPUNIT_CHECK( !l.extract_with( key, other_less()));
526                     CPPUNIT_CHECK( gp.empty());
527                 }
528                 CPPUNIT_ASSERT( l.empty());
529                 CPPUNIT_CHECK( !l.get_with(other_item(arr[0]), other_less()));
530                 CPPUNIT_CHECK( gp.empty());
531                 CPPUNIT_CHECK( !l.extract_with( other_item(arr[0]), other_less()));
532                 CPPUNIT_CHECK( gp.empty());
533             }
534
535         }
536
537         template <class OrdList>
538         void test_rcu()
539         {
540             OrdList l;
541             test_with( l );
542
543             static int const nLimit = 20;
544
545             typedef typename OrdList::rcu_lock rcu_lock;
546             typedef typename OrdList::value_type value_type;
547             typedef typename OrdList::gc rcu_type;
548
549             {
550                 int a[nLimit];
551                 for (int i = 0; i < nLimit; ++i)
552                     a[i]=i;
553                 std::random_shuffle( a, a + nLimit );
554
555                 // extract/get
556                 for ( int i = 0; i < nLimit; ++i )
557                     CPPUNIT_ASSERT( l.insert( a[i] ) );
558
559                 typename OrdList::exempt_ptr ep;
560
561                 for ( int i = 0; i < nLimit; ++i ) {
562                     {
563                         rcu_lock lock;
564                         value_type * pGet = l.get( a[i] );
565                         CPPUNIT_ASSERT( pGet != nullptr );
566                         CPPUNIT_CHECK( pGet->nKey == a[i] );
567                         CPPUNIT_CHECK( pGet->nVal == a[i] * 2 );
568
569                         ep = l.extract( a[i] );
570                         CPPUNIT_ASSERT( ep );
571                         CPPUNIT_ASSERT( !ep.empty() );
572                         CPPUNIT_CHECK( ep->nKey == a[i] );
573                         CPPUNIT_CHECK( (*ep).nVal == a[i] * 2 );
574                     }
575                     ep.release();
576                     {
577                         rcu_lock lock;
578                         CPPUNIT_CHECK( l.get( a[i] ) == nullptr );
579                         CPPUNIT_CHECK( !l.extract( a[i] ));
580                     }
581                 }
582                 CPPUNIT_ASSERT( l.empty() );
583
584                 {
585                     rcu_lock lock;
586                     CPPUNIT_CHECK( l.get( a[0] ) == nullptr );
587                     ep = l.extract( a[0] );
588                     CPPUNIT_CHECK( !ep );
589                     CPPUNIT_CHECK( ep.empty() );
590                 }
591
592                 // extract_with/get_with
593                 for ( int i = 0; i < nLimit; ++i ) {
594                     CPPUNIT_ASSERT( l.insert( a[i] ) );
595                 }
596
597                 for ( int i = 0; i < nLimit; ++i ) {
598                     other_item itm( a[i] );
599                     {
600                         rcu_lock lock;
601                         value_type * pGet = l.get_with( itm, other_less() );
602                         CPPUNIT_ASSERT( pGet != nullptr );
603                         CPPUNIT_CHECK( pGet->nKey == a[i] );
604                         CPPUNIT_CHECK( pGet->nVal == a[i] * 2 );
605
606                         ep = l.extract_with( itm, other_less() );
607                         CPPUNIT_ASSERT( ep );
608                         CPPUNIT_ASSERT( !ep.empty() );
609                         CPPUNIT_CHECK( ep->nKey == a[i] );
610                         CPPUNIT_CHECK( ep->nVal == a[i] * 2 );
611                     }
612                     ep.release();
613                     {
614                         rcu_lock lock;
615                         CPPUNIT_CHECK( l.get_with( itm, other_less() ) == nullptr );
616                         ep = l.extract_with( itm, other_less() );
617                         CPPUNIT_CHECK( !ep );
618                         CPPUNIT_CHECK( ep.empty() );
619                     }
620                 }
621                 CPPUNIT_ASSERT( l.empty() );
622
623                 {
624                     rcu_lock lock;
625                     CPPUNIT_CHECK( l.get_with( other_item( 0 ), other_less() ) == nullptr );
626                     CPPUNIT_CHECK( !l.extract_with( other_item(0), other_less() ));
627                     CPPUNIT_CHECK( ep.empty() );
628                 }
629             }
630         }
631
632         template <class OrdList>
633         void nogc_test()
634         {
635             typedef OrdList list;
636             typedef typename list::value_type    value_type;
637             typedef std::pair<typename list::iterator, bool> ensure_result;
638
639             typename list::iterator it;
640
641             list l;
642             CPPUNIT_ASSERT( l.empty() );
643             CPPUNIT_ASSERT( l.insert(50) != l.end() );
644             CPPUNIT_ASSERT( !l.empty() );
645
646             ensure_result eres = l.ensure( item(100, 33) );
647             CPPUNIT_ASSERT( eres.second );
648             CPPUNIT_ASSERT( eres.first != l.end() );
649             CPPUNIT_ASSERT( l.insert( item(150) ) != l.end() );
650
651             CPPUNIT_ASSERT( l.insert(100) == l.end() );
652             eres = l.ensure( item(50, 33) );
653             CPPUNIT_ASSERT( !eres.second );
654             CPPUNIT_ASSERT( eres.first->nVal == eres.first->nKey * 2 );
655             eres.first->nVal = 63;
656
657             it = l.find( 33 );
658             CPPUNIT_ASSERT( it == l.end() );
659
660             it = l.find( 50 );
661             CPPUNIT_ASSERT( it != l.end() );
662             CPPUNIT_ASSERT( it->nKey == 50 );
663             CPPUNIT_ASSERT( it->nVal == 63 );
664
665             it = l.find( 100 );
666             CPPUNIT_ASSERT( it != l.end() );
667             CPPUNIT_ASSERT( it->nKey == 100 );
668             CPPUNIT_ASSERT( it->nVal == 33 );
669
670             it = l.find_with( 150, lt<value_type>() );
671             CPPUNIT_ASSERT( it != l.end() );
672             CPPUNIT_ASSERT( it->nKey == 150 );
673             CPPUNIT_ASSERT( it->nVal == it->nKey * 2 );
674
675             CPPUNIT_ASSERT( !l.empty() );
676             l.clear();
677             CPPUNIT_ASSERT( l.empty() );
678
679             // insert test
680             CPPUNIT_ASSERT( l.emplace( 501 ) != l.end());
681             CPPUNIT_ASSERT( l.emplace( 251, 152 ) != l.end());
682             CPPUNIT_ASSERT( l.emplace( item( 1001 )) != l.end());
683
684             // insert failed - such key exists
685             CPPUNIT_ASSERT( l.emplace( 501, 2 ) == l.end());
686             CPPUNIT_ASSERT( l.emplace( 251, 10) == l.end());
687
688             it = l.find( 501 );
689             CPPUNIT_ASSERT( it != l.end() );
690             CPPUNIT_ASSERT( it->nKey == 501 );
691             CPPUNIT_ASSERT( it->nVal == 501 * 2 );
692
693             it = l.find_with( 251, lt<value_type>() );
694             CPPUNIT_ASSERT( it != l.end() );
695             CPPUNIT_ASSERT( it->nKey == 251 );
696             CPPUNIT_ASSERT( it->nVal == 152 );
697
698             it = l.find( 1001 );
699             CPPUNIT_ASSERT( it != l.end() );
700             CPPUNIT_ASSERT( it->nKey == 1001 );
701             CPPUNIT_ASSERT( it->nVal == 1001 * 2 );
702
703             {
704                 typename OrdList::iterator it( l.begin() );
705                 typename OrdList::const_iterator cit( l.cbegin() );
706                 CPPUNIT_CHECK( it == cit );
707                 CPPUNIT_CHECK( it != l.end() );
708                 CPPUNIT_CHECK( it != l.cend() );
709                 CPPUNIT_CHECK( cit != l.end() );
710                 CPPUNIT_CHECK( cit != l.cend() );
711                 ++it;
712                 CPPUNIT_CHECK( it != cit );
713                 CPPUNIT_CHECK( it != l.end() );
714                 CPPUNIT_CHECK( it != l.cend() );
715                 CPPUNIT_CHECK( cit != l.end() );
716                 CPPUNIT_CHECK( cit != l.cend() );
717                 ++cit;
718                 CPPUNIT_CHECK( it == cit );
719                 CPPUNIT_CHECK( it != l.end() );
720                 CPPUNIT_CHECK( it != l.cend() );
721                 CPPUNIT_CHECK( cit != l.end() );
722                 CPPUNIT_CHECK( cit != l.cend() );
723             }
724
725
726             l.clear();
727             CPPUNIT_ASSERT( l.empty() );
728         }
729
730         void HP_cmp();
731         void HP_less();
732         void HP_cmpmix();
733         void HP_ic();
734
735         void DHP_cmp();
736         void DHP_less();
737         void DHP_cmpmix();
738         void DHP_ic();
739
740         void RCU_GPI_cmp();
741         void RCU_GPI_less();
742         void RCU_GPI_cmpmix();
743         void RCU_GPI_ic();
744
745         void RCU_GPB_cmp();
746         void RCU_GPB_less();
747         void RCU_GPB_cmpmix();
748         void RCU_GPB_ic();
749
750         void RCU_GPT_cmp();
751         void RCU_GPT_less();
752         void RCU_GPT_cmpmix();
753         void RCU_GPT_ic();
754
755         void RCU_SHB_cmp();
756         void RCU_SHB_less();
757         void RCU_SHB_cmpmix();
758         void RCU_SHB_ic();
759
760         void RCU_SHT_cmp();
761         void RCU_SHT_less();
762         void RCU_SHT_cmpmix();
763         void RCU_SHT_ic();
764
765         void NOGC_cmp();
766         void NOGC_less();
767         void NOGC_cmpmix();
768         void NOGC_ic();
769
770         CPPUNIT_TEST_SUITE(LazyListTestHeader)
771             CPPUNIT_TEST(HP_cmp)
772             CPPUNIT_TEST(HP_less)
773             CPPUNIT_TEST(HP_cmpmix)
774             CPPUNIT_TEST(HP_ic)
775
776             CPPUNIT_TEST(DHP_cmp)
777             CPPUNIT_TEST(DHP_less)
778             CPPUNIT_TEST(DHP_cmpmix)
779             CPPUNIT_TEST(DHP_ic)
780
781             CPPUNIT_TEST(RCU_GPI_cmp)
782             CPPUNIT_TEST(RCU_GPI_less)
783             CPPUNIT_TEST(RCU_GPI_cmpmix)
784             CPPUNIT_TEST(RCU_GPI_ic)
785
786             CPPUNIT_TEST(RCU_GPB_cmp)
787             CPPUNIT_TEST(RCU_GPB_less)
788             CPPUNIT_TEST(RCU_GPB_cmpmix)
789             CPPUNIT_TEST(RCU_GPB_ic)
790
791             CPPUNIT_TEST(RCU_GPT_cmp)
792             CPPUNIT_TEST(RCU_GPT_less)
793             CPPUNIT_TEST(RCU_GPT_cmpmix)
794             CPPUNIT_TEST(RCU_GPT_ic)
795
796             CPPUNIT_TEST(RCU_SHB_cmp)
797             CPPUNIT_TEST(RCU_SHB_less)
798             CPPUNIT_TEST(RCU_SHB_cmpmix)
799             CPPUNIT_TEST(RCU_SHB_ic)
800
801             CPPUNIT_TEST(RCU_SHT_cmp)
802             CPPUNIT_TEST(RCU_SHT_less)
803             CPPUNIT_TEST(RCU_SHT_cmpmix)
804             CPPUNIT_TEST(RCU_SHT_ic)
805
806             CPPUNIT_TEST(NOGC_cmp)
807             CPPUNIT_TEST(NOGC_less)
808             CPPUNIT_TEST(NOGC_cmpmix)
809             CPPUNIT_TEST(NOGC_ic)
810         CPPUNIT_TEST_SUITE_END()
811     };
812
813 }   // namespace ordlist