3 #ifndef CDSTEST_HDR_INTRUSIVE_LAZY_H
4 #define CDSTEST_HDR_INTRUSIVE_LAZY_H
6 #include "cppunit/cppunit_proxy.h"
7 #include <cds/intrusive/details/lazy_list_base.h>
10 namespace ci = cds::intrusive;
11 namespace co = cds::opt;
13 class IntrusiveLazyListHeaderTest: public CppUnitMini::TestCase
19 int nEnsureExistsCall;
26 , nEnsureExistsCall(0)
37 stat& operator =(const stat& s)
39 memcpy( this, &s, sizeof(s));
44 template <typename GC>
45 struct base_int_item: public ci::lazy_list::node< GC >
55 base_int_item(int key, int val)
61 base_int_item(const base_int_item& v )
67 const int& key() const
73 template <typename GC>
74 struct member_int_item
79 ci::lazy_list::node< GC > hMember;
86 member_int_item(int key, int val)
92 member_int_item(const member_int_item& v )
98 const int& key() const
104 template <typename T>
107 bool operator ()(const T& v1, const T& v2 ) const
109 return v1.key() < v2.key();
112 template <typename Q>
113 bool operator ()(const T& v1, const Q& v2 ) const
115 return v1.key() < v2;
118 template <typename Q>
119 bool operator ()(const Q& v1, const T& v2 ) const
121 return v1 < v2.key();
125 template <typename T>
127 int operator ()(const T& v1, const T& v2 ) const
129 if ( v1.key() < v2.key() )
131 return v1.key() > v2.key() ? 1 : 0;
134 template <typename Q>
135 int operator ()(const T& v1, const Q& v2 ) const
139 return v1.key() > v2 ? 1 : 0;
142 template <typename Q>
143 int operator ()(const Q& v1, const T& v2 ) const
147 return v1 > v2.key() ? 1 : 0;
160 template <typename T, typename Q>
161 bool operator()( T const& i1, Q const& i2) const
163 return i1.nKey < i2.nKey;
167 struct faked_disposer
169 template <typename T>
170 void operator ()( T * p )
172 ++p->s.nDisposeCount;
176 struct ensure_functor
178 template <typename T>
179 void operator ()(bool bNew, T& item, T& /*val*/ )
182 ++item.s.nEnsureNewCall;
184 ++item.s.nEnsureExistsCall;
190 template <typename T, typename Q>
191 void operator ()( T& item, Q& /*val*/ )
199 template <typename T>
200 void operator()( T const& item )
206 template <class OrdList>
207 void test_int_common()
209 typedef typename OrdList::value_type value_type;
211 value_type v1( 10, 50 );
212 value_type v2( 5, 25 );
213 value_type v3( 20, 100 );
216 CPPUNIT_ASSERT( l.empty() );
218 CPPUNIT_ASSERT( l.insert( v1 )) ; // true
219 CPPUNIT_ASSERT( l.find( v1.key() ));
221 CPPUNIT_ASSERT( v1.s.nFindCall == 0 );
222 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
223 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
225 CPPUNIT_ASSERT( !l.find_with( v2.key(), less<value_type>() ));
226 CPPUNIT_ASSERT( !l.find( v3.key(), find_functor() ));
227 CPPUNIT_ASSERT( !l.empty() );
229 //CPPUNIT_ASSERT( !l.insert( v1 )) ; // assertion "is_empty" is raised
233 CPPUNIT_ASSERT( !l.insert( v )) ; // false
236 std::pair<bool, bool> ret = l.ensure( v2, ensure_functor() );
237 CPPUNIT_ASSERT( ret.first );
238 CPPUNIT_ASSERT( ret.second );
239 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
240 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 0 );
242 //CPPUNIT_ASSERT( !l.insert( v2 )) ; // assertion "is_empty"
244 CPPUNIT_ASSERT( l.find( v1.key() )) ; // true
246 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
247 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
248 CPPUNIT_ASSERT( v1.s.nFindCall == 2 );
250 CPPUNIT_ASSERT( l.find( v2.key() ));
252 CPPUNIT_ASSERT( v2.s.nFindCall == 0 );
253 CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>(), find_functor() ));
254 CPPUNIT_ASSERT( v2.s.nFindCall == 1 );
256 CPPUNIT_ASSERT( !l.find( v3.key() ));
259 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 0 );
260 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
263 ret = l.ensure( v, ensure_functor() );
265 CPPUNIT_ASSERT( ret.first );
266 CPPUNIT_ASSERT( !ret.second );
267 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 1 );
268 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
269 CPPUNIT_ASSERT( v.s.nEnsureExistsCall == 0 );
270 CPPUNIT_ASSERT( v.s.nEnsureNewCall == 0 );
273 CPPUNIT_ASSERT( !l.empty() );
275 CPPUNIT_ASSERT( l.insert( v3 )) ; // true
276 CPPUNIT_ASSERT( l.find( v3.key() ));
278 CPPUNIT_ASSERT( v3.s.nFindCall == 0 );
279 CPPUNIT_ASSERT( l.find( v3.key(), find_functor() ));
280 CPPUNIT_ASSERT( v3.s.nFindCall == 1 );
282 CPPUNIT_ASSERT( l.unlink( v2 ) );
283 CPPUNIT_ASSERT( l.find( v1.key() )) ; // true
284 CPPUNIT_ASSERT( !l.find( v2.key() )) ; // true
285 CPPUNIT_ASSERT( l.find( v3.key() )) ; // true
286 CPPUNIT_ASSERT( !l.empty() );
287 CPPUNIT_ASSERT( !l.unlink( v2 ) );
290 // v1 key is in the list but v NODE is not in the list
292 CPPUNIT_ASSERT( !l.unlink( v ) );
295 CPPUNIT_ASSERT( l.unlink( v1 ) );
296 CPPUNIT_ASSERT( !l.unlink( v1 ) );
297 CPPUNIT_ASSERT( !l.find( v1.key() ));
298 CPPUNIT_ASSERT( !l.find( v2.key() ));
299 CPPUNIT_ASSERT( l.find( v3.key() ));
300 CPPUNIT_ASSERT( !l.empty() );
301 CPPUNIT_ASSERT( !l.unlink( v1 ) );
302 CPPUNIT_ASSERT( !l.unlink( v2 ) );
304 CPPUNIT_ASSERT( l.unlink( v3 ) );
305 CPPUNIT_ASSERT( !l.find( v1.key() ));
306 CPPUNIT_ASSERT( !l.find_with( v2.key(), less<value_type>() ));
307 CPPUNIT_ASSERT( !l.find( v3.key() ));
308 CPPUNIT_ASSERT( l.empty() );
309 CPPUNIT_ASSERT( !l.unlink( v1 ) );
310 CPPUNIT_ASSERT( !l.unlink( v2 ) );
311 CPPUNIT_ASSERT( !l.unlink( v3 ) );
313 // Apply retired pointer to clean links
314 OrdList::gc::force_dispose();
317 ret = l.ensure( v3, ensure_functor() );
318 CPPUNIT_ASSERT( ret.first );
319 CPPUNIT_ASSERT( ret.second );
320 CPPUNIT_ASSERT( v3.s.nEnsureNewCall == s.nEnsureNewCall + 1);
321 CPPUNIT_ASSERT( v3.s.nEnsureExistsCall == s.nEnsureExistsCall );
322 CPPUNIT_ASSERT( !l.empty() );
325 ret = l.ensure( v2, ensure_functor() );
326 CPPUNIT_ASSERT( ret.first );
327 CPPUNIT_ASSERT( ret.second );
328 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == s.nEnsureNewCall + 1);
329 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == s.nEnsureExistsCall );
330 CPPUNIT_ASSERT( !l.empty() );
333 ret = l.ensure( v1, ensure_functor() );
334 CPPUNIT_ASSERT( ret.first );
335 CPPUNIT_ASSERT( ret.second );
336 CPPUNIT_ASSERT( v1.s.nEnsureNewCall == s.nEnsureNewCall + 1);
337 CPPUNIT_ASSERT( v1.s.nEnsureExistsCall == s.nEnsureExistsCall );
338 CPPUNIT_ASSERT( !l.empty() );
341 CPPUNIT_ASSERT( l.erase( v1.key()) );
342 //CPPUNIT_ASSERT( v1.s.nDisposeCount == 0 );
343 CPPUNIT_ASSERT( !l.empty() );
345 CPPUNIT_ASSERT( v2.s.nEraseCall == 0 );
346 CPPUNIT_ASSERT( l.erase_with( v2.key(), less<value_type>(), erase_functor()) );
347 CPPUNIT_ASSERT( v2.s.nEraseCall == 1 );
348 CPPUNIT_ASSERT( !l.erase_with( v2.key(), less<value_type>()));
349 CPPUNIT_ASSERT( v2.s.nEraseCall == 1 );
350 //CPPUNIT_ASSERT( v2.s.nDisposeCount == 0 );
351 CPPUNIT_ASSERT( !l.empty() );
353 CPPUNIT_ASSERT( !l.erase( v2 ));
354 CPPUNIT_ASSERT( !l.erase( v1 ));
355 //CPPUNIT_ASSERT( v2.s.nDisposeCount == 0 );
356 CPPUNIT_ASSERT( !l.empty() );
358 CPPUNIT_ASSERT( v3.s.nEraseCall == 0 );
359 CPPUNIT_ASSERT( l.erase( v3, erase_functor() ));
360 CPPUNIT_ASSERT( v3.s.nEraseCall == 1 );
361 //CPPUNIT_ASSERT( v3.s.nDisposeCount == 0 );
362 CPPUNIT_ASSERT( l.empty() );
364 // Apply retired pointer to clean links
365 OrdList::gc::force_dispose();
368 CPPUNIT_ASSERT( l.insert( v1 ));
369 CPPUNIT_ASSERT( l.insert( v3 ));
370 CPPUNIT_ASSERT( !l.empty() );
371 CPPUNIT_ASSERT( !l.unlink( v2 ));
372 CPPUNIT_ASSERT( l.unlink( v1 ));
373 CPPUNIT_ASSERT( !l.unlink( v1 ));
374 CPPUNIT_ASSERT( l.unlink( v3 ));
375 CPPUNIT_ASSERT( !l.unlink( v3 ));
376 CPPUNIT_ASSERT( l.empty() );
378 // Apply retired pointer
379 OrdList::gc::force_dispose();
380 CPPUNIT_ASSERT( v1.s.nDisposeCount == 3 );
381 CPPUNIT_ASSERT( v2.s.nDisposeCount == 2 );
382 CPPUNIT_ASSERT( v3.s.nDisposeCount == 3 );
384 // Destructor test (call disposer)
385 CPPUNIT_ASSERT( l.insert( v1 ));
386 CPPUNIT_ASSERT( l.insert( v3 ));
387 CPPUNIT_ASSERT( l.insert( v2 ));
391 typename OrdList::iterator it = l.begin();
392 typename OrdList::const_iterator cit = l.cbegin();
393 CPPUNIT_ASSERT( it != l.end() );
394 CPPUNIT_ASSERT( it != l.cend() );
395 CPPUNIT_ASSERT( cit != l.end() );
396 CPPUNIT_ASSERT( cit != l.cend() );
397 CPPUNIT_ASSERT( cit == it );
399 CPPUNIT_ASSERT( it->nKey == v2.nKey );
400 CPPUNIT_ASSERT( it->nVal == v2.nVal );
401 CPPUNIT_ASSERT( ++it != l.end() );
402 CPPUNIT_ASSERT( it->nKey == v1.nKey );
403 CPPUNIT_ASSERT( it->nVal == v1.nVal );
404 CPPUNIT_ASSERT( ++it != l.end() );
405 CPPUNIT_ASSERT( it->nKey == v3.nKey );
406 CPPUNIT_ASSERT( it->nVal == v3.nVal );
407 CPPUNIT_ASSERT( ++it == l.end() );
411 OrdList const & lref = l;
412 typename OrdList::const_iterator it = lref.begin();
413 CPPUNIT_ASSERT( it != l.end() );
414 CPPUNIT_ASSERT( it->nKey == v2.nKey );
415 CPPUNIT_ASSERT( it->nVal == v2.nVal );
416 CPPUNIT_ASSERT( ++it != lref.end() );
417 CPPUNIT_ASSERT( it->nKey == v1.nKey );
418 CPPUNIT_ASSERT( it->nVal == v1.nVal );
419 CPPUNIT_ASSERT( ++it != l.end() );
420 CPPUNIT_ASSERT( it->nKey == v3.nKey );
421 CPPUNIT_ASSERT( it->nVal == v3.nVal );
422 CPPUNIT_ASSERT( ++it == l.end() );
426 // Apply retired pointer
427 OrdList::gc::force_dispose();
429 CPPUNIT_ASSERT( v1.s.nDisposeCount == 4 );
430 CPPUNIT_ASSERT( v2.s.nDisposeCount == 3 );
431 CPPUNIT_ASSERT( v3.s.nDisposeCount == 4 );
434 template <class OrdList>
437 test_int_common<OrdList>();
440 typename OrdList::guarded_ptr gp;
442 static int const nLimit = 20;
443 typename OrdList::value_type arrItem[nLimit];
447 for (int i = 0; i < nLimit; ++i)
449 std::random_shuffle( a, a + nLimit );
451 for (int i = 0; i < nLimit; ++i) {
452 arrItem[i].nKey = a[i];
453 arrItem[i].nVal = a[i] * 2;
457 for ( int i = 0; i < nLimit; ++i )
458 CPPUNIT_ASSERT( l.insert( arrItem[i] ) );
460 for ( int i=0; i < nLimit; ++i ) {
461 gp = l.get( arrItem[i].nKey );
462 CPPUNIT_ASSERT( gp );
463 CPPUNIT_ASSERT( !gp.empty());
464 CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey );
465 CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal );
467 gp = l.extract( arrItem[i].nKey );
468 CPPUNIT_ASSERT( gp );
469 CPPUNIT_ASSERT( !gp.empty());
470 CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey );
471 CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal );
473 gp = l.get( arrItem[i].nKey );
474 CPPUNIT_ASSERT( !gp );
475 CPPUNIT_ASSERT( gp.empty());
476 CPPUNIT_ASSERT( !l.extract( arrItem[i].nKey ));
477 CPPUNIT_ASSERT( gp.empty());
479 CPPUNIT_ASSERT( l.empty() );
480 CPPUNIT_ASSERT( !l.get( nLimit/2 ));
481 CPPUNIT_ASSERT( !l.extract( nLimit/2 ));
483 // Apply retired pointer
484 OrdList::gc::force_dispose();
486 // extract_with/get_with
487 for ( int i = 0; i < nLimit; ++i )
488 CPPUNIT_ASSERT( l.insert( arrItem[i] ) );
490 for ( int i=0; i < nLimit; ++i ) {
491 other_item itm( arrItem[i].nKey );
492 gp = l.get_with( itm, other_less() );
493 CPPUNIT_ASSERT( gp );
494 CPPUNIT_ASSERT( !gp.empty());
495 CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey );
496 CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal );
498 gp = l.extract_with( itm, other_less() );
499 CPPUNIT_ASSERT( gp );
500 CPPUNIT_ASSERT( !gp.empty());
501 CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey );
502 CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal );
504 gp = l.get_with( itm, other_less() );
505 CPPUNIT_ASSERT( !gp );
506 CPPUNIT_ASSERT( gp.empty());
507 CPPUNIT_ASSERT( !l.extract_with( itm, other_less() ));
508 CPPUNIT_ASSERT( gp.empty());
510 CPPUNIT_ASSERT( l.empty() );
511 CPPUNIT_ASSERT( !l.get_with( other_item(nLimit/2), other_less() ));
512 CPPUNIT_ASSERT( gp.empty());
513 CPPUNIT_ASSERT( !l.extract_with( other_item(nLimit/2), other_less() ));
514 CPPUNIT_ASSERT( gp.empty());
516 // Apply retired pointer
517 OrdList::gc::force_dispose();
519 for ( int i=0; i < nLimit; i++ ) {
520 CPPUNIT_ASSERT( arrItem[i].s.nDisposeCount == 2 );
525 template <class OrdList>
528 test_int_common<OrdList>();
531 static int const nLimit = 20;
532 typename OrdList::value_type arrItem[nLimit];
534 typedef typename OrdList::rcu_lock rcu_lock;
535 typedef typename OrdList::value_type value_type;
536 typedef typename OrdList::gc rcu_type;
540 for (int i = 0; i < nLimit; ++i)
542 std::random_shuffle( a, a + nLimit );
544 for (int i = 0; i < nLimit; ++i) {
545 arrItem[i].nKey = a[i];
546 arrItem[i].nVal = a[i] * 2;
549 typename OrdList::exempt_ptr ep;
552 for ( int i = 0; i < nLimit; ++i )
553 CPPUNIT_ASSERT( l.insert( arrItem[i] ) );
555 for ( int i = 0; i < nLimit; ++i ) {
558 value_type * pGet = l.get( a[i] );
559 CPPUNIT_ASSERT( pGet != nullptr );
560 CPPUNIT_CHECK( pGet->nKey == a[i] );
561 CPPUNIT_CHECK( pGet->nVal == a[i] * 2 );
563 ep = l.extract( a[i] );
564 CPPUNIT_ASSERT( ep );
565 CPPUNIT_ASSERT( !ep.empty() );
566 CPPUNIT_CHECK( ep->nKey == a[i] );
567 CPPUNIT_CHECK( (*ep).nVal == a[i] * 2 );
572 CPPUNIT_CHECK( l.get( a[i] ) == nullptr );
573 CPPUNIT_CHECK( !l.extract( a[i] ) );
574 CPPUNIT_CHECK( ep.empty() );
577 CPPUNIT_ASSERT( l.empty() );
581 CPPUNIT_CHECK( l.get( a[0] ) == nullptr );
582 ep = l.extract( a[0] );
583 CPPUNIT_CHECK( !ep );
584 CPPUNIT_CHECK( ep.empty() );
586 // Apply retired pointer
587 OrdList::gc::force_dispose();
589 // extract_with/get_with
590 for ( int i = 0; i < nLimit; ++i ) {
591 CPPUNIT_ASSERT( l.insert( arrItem[i] ) );
594 for ( int i = 0; i < nLimit; ++i ) {
595 other_item itm( a[i] );
598 value_type * pGet = l.get_with( itm, other_less() );
599 CPPUNIT_ASSERT( pGet != nullptr );
600 CPPUNIT_CHECK( pGet->nKey == a[i] );
601 CPPUNIT_CHECK( pGet->nVal == a[i] * 2 );
603 ep = l.extract_with( itm, other_less() );
604 CPPUNIT_ASSERT( ep );
605 CPPUNIT_ASSERT( !ep.empty() );
606 CPPUNIT_CHECK( ep->nKey == a[i] );
607 CPPUNIT_CHECK( ep->nVal == a[i] * 2 );
612 CPPUNIT_CHECK( l.get_with( itm, other_less() ) == nullptr );
613 ep = l.extract_with( itm, other_less() );
614 CPPUNIT_CHECK( !ep );
615 CPPUNIT_CHECK( ep.empty() );
618 CPPUNIT_ASSERT( l.empty() );
622 CPPUNIT_CHECK( l.get_with( other_item( 0 ), other_less() ) == nullptr );
623 CPPUNIT_CHECK( !l.extract_with( other_item(0), other_less() ));
624 CPPUNIT_CHECK( ep.empty() );
626 // Apply retired pointer
627 OrdList::gc::force_dispose();
631 template <class OrdList>
634 typedef typename OrdList::value_type value_type;
636 value_type v1( 10, 50 );
637 value_type v2( 5, 25 );
638 value_type v3( 20, 100 );
641 CPPUNIT_ASSERT( l.empty() );
643 CPPUNIT_ASSERT( l.insert( v1 )) ; // true
644 CPPUNIT_ASSERT( l.find( v1.key() ) == &v1 );
646 CPPUNIT_ASSERT( v1.s.nFindCall == 0 );
647 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
648 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
650 CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>() ) == nullptr );
651 CPPUNIT_ASSERT( l.find( v3.key() ) == nullptr );
652 CPPUNIT_ASSERT( !l.empty() );
654 //CPPUNIT_ASSERT( !l.insert( v1 )) ; // assertion "is_empty" is raised
658 CPPUNIT_ASSERT( !l.insert( v )) ; // false
661 std::pair<bool, bool> ret = l.ensure( v2, ensure_functor() );
662 CPPUNIT_ASSERT( ret.first );
663 CPPUNIT_ASSERT( ret.second );
664 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
665 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 0 );
667 //CPPUNIT_ASSERT( !l.insert( v2 )) ; // assertion "is_empty"
669 CPPUNIT_ASSERT( l.find( v1.key() ) == &v1 ) ; // true
671 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
672 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
673 CPPUNIT_ASSERT( v1.s.nFindCall == 2 );
675 CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>() ) == &v2 );
677 CPPUNIT_ASSERT( v2.s.nFindCall == 0 );
678 CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>(), find_functor() ));
679 CPPUNIT_ASSERT( v2.s.nFindCall == 1 );
681 CPPUNIT_ASSERT( !l.find( v3.key() ));
685 ret = l.ensure( v, ensure_functor() );
687 CPPUNIT_ASSERT( ret.first );
688 CPPUNIT_ASSERT( !ret.second );
689 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 1 );
690 CPPUNIT_ASSERT( v.s.nEnsureExistsCall == 0 && v.s.nEnsureNewCall == 0 );
693 CPPUNIT_ASSERT( !l.empty() );
695 CPPUNIT_ASSERT( l.insert( v3 )) ; // true
696 CPPUNIT_ASSERT( l.find( v3.key() ) == &v3 );
698 CPPUNIT_ASSERT( v3.s.nFindCall == 0 );
699 CPPUNIT_ASSERT( l.find( v3.key(), find_functor() ));
700 CPPUNIT_ASSERT( v3.s.nFindCall == 1 );
703 typename OrdList::iterator it = l.begin();
704 typename OrdList::const_iterator cit = l.cbegin();
705 CPPUNIT_ASSERT( it != l.end() );
706 CPPUNIT_ASSERT( it != l.cend() );
707 CPPUNIT_ASSERT( cit != l.end() );
708 CPPUNIT_ASSERT( cit != l.cend() );
709 CPPUNIT_ASSERT( cit == it );
711 CPPUNIT_ASSERT( it->nKey == v2.nKey );
712 CPPUNIT_ASSERT( it->nVal == v2.nVal );
713 CPPUNIT_ASSERT( ++it != l.end() );
714 CPPUNIT_ASSERT( it->nKey == v1.nKey );
715 CPPUNIT_ASSERT( it->nVal == v1.nVal );
716 CPPUNIT_ASSERT( it++ != l.end() );
717 CPPUNIT_ASSERT( it->nKey == v3.nKey );
718 CPPUNIT_ASSERT( it->nVal == v3.nVal );
719 CPPUNIT_ASSERT( it++ != l.end() );
720 CPPUNIT_ASSERT( it == l.end() );
724 OrdList const & lref = l;
725 typename OrdList::const_iterator it = lref.begin();
726 CPPUNIT_ASSERT( it != l.end() );
727 CPPUNIT_ASSERT( it->nKey == v2.nKey );
728 CPPUNIT_ASSERT( it->nVal == v2.nVal );
729 CPPUNIT_ASSERT( ++it != lref.end() );
730 CPPUNIT_ASSERT( it->nKey == v1.nKey );
731 CPPUNIT_ASSERT( it->nVal == v1.nVal );
732 CPPUNIT_ASSERT( it++ != l.end() );
733 CPPUNIT_ASSERT( it->nKey == v3.nKey );
734 CPPUNIT_ASSERT( it->nVal == v3.nVal );
735 CPPUNIT_ASSERT( it++ != lref.end() );
736 CPPUNIT_ASSERT( it == l.end() );
740 // Disposer called on list destruction
741 CPPUNIT_ASSERT( v1.s.nDisposeCount == 1 );
742 CPPUNIT_ASSERT( v2.s.nDisposeCount == 1 );
743 CPPUNIT_ASSERT( v3.s.nDisposeCount == 1 );
749 void HP_base_cmpmix();
751 void HP_member_cmp();
752 void HP_member_less();
753 void HP_member_cmpmix();
757 void DHP_base_less();
758 void DHP_base_cmpmix();
760 void DHP_member_cmp();
761 void DHP_member_less();
762 void DHP_member_cmpmix();
763 void DHP_member_ic();
765 void RCU_GPI_base_cmp();
766 void RCU_GPI_base_less();
767 void RCU_GPI_base_cmpmix();
768 void RCU_GPI_base_ic();
769 void RCU_GPI_member_cmp();
770 void RCU_GPI_member_less();
771 void RCU_GPI_member_cmpmix();
772 void RCU_GPI_member_ic();
774 void RCU_GPB_base_cmp();
775 void RCU_GPB_base_less();
776 void RCU_GPB_base_cmpmix();
777 void RCU_GPB_base_ic();
778 void RCU_GPB_member_cmp();
779 void RCU_GPB_member_less();
780 void RCU_GPB_member_cmpmix();
781 void RCU_GPB_member_ic();
783 void RCU_GPT_base_cmp();
784 void RCU_GPT_base_less();
785 void RCU_GPT_base_cmpmix();
786 void RCU_GPT_base_ic();
787 void RCU_GPT_member_cmp();
788 void RCU_GPT_member_less();
789 void RCU_GPT_member_cmpmix();
790 void RCU_GPT_member_ic();
792 void RCU_SHB_base_cmp();
793 void RCU_SHB_base_less();
794 void RCU_SHB_base_cmpmix();
795 void RCU_SHB_base_ic();
796 void RCU_SHB_member_cmp();
797 void RCU_SHB_member_less();
798 void RCU_SHB_member_cmpmix();
799 void RCU_SHB_member_ic();
801 void RCU_SHT_base_cmp();
802 void RCU_SHT_base_less();
803 void RCU_SHT_base_cmpmix();
804 void RCU_SHT_base_ic();
805 void RCU_SHT_member_cmp();
806 void RCU_SHT_member_less();
807 void RCU_SHT_member_cmpmix();
808 void RCU_SHT_member_ic();
810 void nogc_base_cmp();
811 void nogc_base_less();
812 void nogc_base_cmpmix();
814 void nogc_member_cmp();
815 void nogc_member_less();
816 void nogc_member_cmpmix();
817 void nogc_member_ic();
820 CPPUNIT_TEST_SUITE(IntrusiveLazyListHeaderTest)
821 CPPUNIT_TEST(HP_base_cmp)
822 CPPUNIT_TEST(HP_base_less)
823 CPPUNIT_TEST(HP_base_cmpmix)
824 CPPUNIT_TEST(HP_base_ic)
825 CPPUNIT_TEST(HP_member_cmp)
826 CPPUNIT_TEST(HP_member_less)
827 CPPUNIT_TEST(HP_member_cmpmix)
828 CPPUNIT_TEST(HP_member_ic)
830 CPPUNIT_TEST(DHP_base_cmp)
831 CPPUNIT_TEST(DHP_base_less)
832 CPPUNIT_TEST(DHP_base_cmpmix)
833 CPPUNIT_TEST(DHP_base_ic)
834 CPPUNIT_TEST(DHP_member_cmp)
835 CPPUNIT_TEST(DHP_member_less)
836 CPPUNIT_TEST(DHP_member_cmpmix)
837 CPPUNIT_TEST(DHP_member_ic)
839 CPPUNIT_TEST(RCU_GPI_base_cmp)
840 CPPUNIT_TEST(RCU_GPI_base_less)
841 CPPUNIT_TEST(RCU_GPI_base_cmpmix)
842 CPPUNIT_TEST(RCU_GPI_base_ic)
843 CPPUNIT_TEST(RCU_GPI_member_cmp)
844 CPPUNIT_TEST(RCU_GPI_member_less)
845 CPPUNIT_TEST(RCU_GPI_member_cmpmix)
846 CPPUNIT_TEST(RCU_GPI_member_ic)
848 CPPUNIT_TEST(RCU_GPB_base_cmp)
849 CPPUNIT_TEST(RCU_GPB_base_less)
850 CPPUNIT_TEST(RCU_GPB_base_cmpmix)
851 CPPUNIT_TEST(RCU_GPB_base_ic)
852 CPPUNIT_TEST(RCU_GPB_member_cmp)
853 CPPUNIT_TEST(RCU_GPB_member_less)
854 CPPUNIT_TEST(RCU_GPB_member_cmpmix)
855 CPPUNIT_TEST(RCU_GPB_member_ic)
857 CPPUNIT_TEST(RCU_GPT_base_cmp)
858 CPPUNIT_TEST(RCU_GPT_base_less)
859 CPPUNIT_TEST(RCU_GPT_base_cmpmix)
860 CPPUNIT_TEST(RCU_GPT_base_ic)
861 CPPUNIT_TEST(RCU_GPT_member_cmp)
862 CPPUNIT_TEST(RCU_GPT_member_less)
863 CPPUNIT_TEST(RCU_GPT_member_cmpmix)
864 CPPUNIT_TEST(RCU_GPT_member_ic)
866 CPPUNIT_TEST(RCU_SHB_base_cmp)
867 CPPUNIT_TEST(RCU_SHB_base_less)
868 CPPUNIT_TEST(RCU_SHB_base_cmpmix)
869 CPPUNIT_TEST(RCU_SHB_base_ic)
870 CPPUNIT_TEST(RCU_SHB_member_cmp)
871 CPPUNIT_TEST(RCU_SHB_member_less)
872 CPPUNIT_TEST(RCU_SHB_member_cmpmix)
873 CPPUNIT_TEST(RCU_SHB_member_ic)
875 CPPUNIT_TEST(RCU_SHT_base_cmp)
876 CPPUNIT_TEST(RCU_SHT_base_less)
877 CPPUNIT_TEST(RCU_SHT_base_cmpmix)
878 CPPUNIT_TEST(RCU_SHT_base_ic)
879 CPPUNIT_TEST(RCU_SHT_member_cmp)
880 CPPUNIT_TEST(RCU_SHT_member_less)
881 CPPUNIT_TEST(RCU_SHT_member_cmpmix)
882 CPPUNIT_TEST(RCU_SHT_member_ic)
884 CPPUNIT_TEST(nogc_base_cmp)
885 CPPUNIT_TEST(nogc_base_less)
886 CPPUNIT_TEST(nogc_base_cmpmix)
887 CPPUNIT_TEST(nogc_base_ic)
888 CPPUNIT_TEST(nogc_member_cmp)
889 CPPUNIT_TEST(nogc_member_less)
890 CPPUNIT_TEST(nogc_member_cmpmix)
891 CPPUNIT_TEST(nogc_member_ic)
893 CPPUNIT_TEST_SUITE_END()
895 } // namespace ordlist
897 #endif // #ifndef CDSTEST_HDR_INTRUSIVE_LAZY_H