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;
151 template <typename T>
153 bool operator ()(const T& v1, const T& v2 ) const
155 return v1.key() == v2.key();
158 template <typename Q>
159 bool operator ()(const T& v1, const Q& v2 ) const
161 return v1.key() == v2;
164 template <typename Q>
165 bool operator ()(const Q& v1, const T& v2 ) const
167 return v1 == v2.key();
180 template <typename T, typename Q>
181 bool operator()( T const& i1, Q const& i2) const
183 return i1.nKey < i2.nKey;
188 template <typename T, typename Q>
189 bool operator()( T const& i1, Q const& i2) const
191 return i1.nKey == i2.nKey;
195 struct faked_disposer
197 template <typename T>
198 void operator ()( T * p )
200 ++p->s.nDisposeCount;
204 struct ensure_functor
206 template <typename T>
207 void operator ()(bool bNew, T& item, T& /*val*/ )
210 ++item.s.nEnsureNewCall;
212 ++item.s.nEnsureExistsCall;
218 template <typename T, typename Q>
219 void operator ()( T& item, Q& /*val*/ )
227 template <typename T>
228 void operator()( T const& item )
234 template <class OrdList>
235 void test_int_common()
237 typedef typename OrdList::value_type value_type;
239 value_type v1( 10, 50 );
240 value_type v2( 5, 25 );
241 value_type v3( 20, 100 );
244 CPPUNIT_ASSERT( l.empty() );
246 CPPUNIT_ASSERT( l.insert( v1 )) ; // true
247 CPPUNIT_ASSERT( l.find( v1.key() ));
249 CPPUNIT_ASSERT( v1.s.nFindCall == 0 );
250 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
251 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
253 CPPUNIT_ASSERT( !l.find_with( v2.key(), less<value_type>() ));
254 CPPUNIT_ASSERT( !l.find( v3.key(), find_functor() ));
255 CPPUNIT_ASSERT( !l.empty() );
257 //CPPUNIT_ASSERT( !l.insert( v1 )) ; // assertion "is_empty" is raised
261 CPPUNIT_ASSERT( !l.insert( v )) ; // false
264 std::pair<bool, bool> ret = l.ensure( v2, ensure_functor() );
265 CPPUNIT_ASSERT( ret.first );
266 CPPUNIT_ASSERT( ret.second );
267 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
268 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 0 );
270 //CPPUNIT_ASSERT( !l.insert( v2 )) ; // assertion "is_empty"
272 CPPUNIT_ASSERT( l.find( v1.key() )) ; // true
274 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
275 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
276 CPPUNIT_ASSERT( v1.s.nFindCall == 2 );
278 CPPUNIT_ASSERT( l.find( v2.key() ));
280 CPPUNIT_ASSERT( v2.s.nFindCall == 0 );
281 CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>(), find_functor() ));
282 CPPUNIT_ASSERT( v2.s.nFindCall == 1 );
284 CPPUNIT_ASSERT( !l.find( v3.key() ));
287 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 0 );
288 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
291 ret = l.ensure( v, ensure_functor() );
293 CPPUNIT_ASSERT( ret.first );
294 CPPUNIT_ASSERT( !ret.second );
295 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 1 );
296 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
297 CPPUNIT_ASSERT( v.s.nEnsureExistsCall == 0 );
298 CPPUNIT_ASSERT( v.s.nEnsureNewCall == 0 );
301 CPPUNIT_ASSERT( !l.empty() );
303 CPPUNIT_ASSERT( l.insert( v3 )) ; // true
304 CPPUNIT_ASSERT( l.find( v3.key() ));
306 CPPUNIT_ASSERT( v3.s.nFindCall == 0 );
307 CPPUNIT_ASSERT( l.find( v3.key(), find_functor() ));
308 CPPUNIT_ASSERT( v3.s.nFindCall == 1 );
310 CPPUNIT_ASSERT( l.unlink( v2 ) );
311 CPPUNIT_ASSERT( l.find( v1.key() )) ; // true
312 CPPUNIT_ASSERT( !l.find( v2.key() )) ; // true
313 CPPUNIT_ASSERT( l.find( v3.key() )) ; // true
314 CPPUNIT_ASSERT( !l.empty() );
315 CPPUNIT_ASSERT( !l.unlink( v2 ) );
318 // v1 key is in the list but v NODE is not in the list
320 CPPUNIT_ASSERT( !l.unlink( v ) );
323 CPPUNIT_ASSERT( l.unlink( v1 ) );
324 CPPUNIT_ASSERT( !l.unlink( v1 ) );
325 CPPUNIT_ASSERT( !l.find( v1.key() ));
326 CPPUNIT_ASSERT( !l.find( v2.key() ));
327 CPPUNIT_ASSERT( l.find( v3.key() ));
328 CPPUNIT_ASSERT( !l.empty() );
329 CPPUNIT_ASSERT( !l.unlink( v1 ) );
330 CPPUNIT_ASSERT( !l.unlink( v2 ) );
332 CPPUNIT_ASSERT( l.unlink( v3 ) );
333 CPPUNIT_ASSERT( !l.find( v1.key() ));
334 CPPUNIT_ASSERT( !l.find_with( v2.key(), less<value_type>() ));
335 CPPUNIT_ASSERT( !l.find( v3.key() ));
336 CPPUNIT_ASSERT( l.empty() );
337 CPPUNIT_ASSERT( !l.unlink( v1 ) );
338 CPPUNIT_ASSERT( !l.unlink( v2 ) );
339 CPPUNIT_ASSERT( !l.unlink( v3 ) );
341 // Apply retired pointer to clean links
342 OrdList::gc::force_dispose();
345 ret = l.ensure( v3, ensure_functor() );
346 CPPUNIT_ASSERT( ret.first );
347 CPPUNIT_ASSERT( ret.second );
348 CPPUNIT_ASSERT( v3.s.nEnsureNewCall == s.nEnsureNewCall + 1);
349 CPPUNIT_ASSERT( v3.s.nEnsureExistsCall == s.nEnsureExistsCall );
350 CPPUNIT_ASSERT( !l.empty() );
353 ret = l.ensure( v2, ensure_functor() );
354 CPPUNIT_ASSERT( ret.first );
355 CPPUNIT_ASSERT( ret.second );
356 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == s.nEnsureNewCall + 1);
357 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == s.nEnsureExistsCall );
358 CPPUNIT_ASSERT( !l.empty() );
361 ret = l.ensure( v1, ensure_functor() );
362 CPPUNIT_ASSERT( ret.first );
363 CPPUNIT_ASSERT( ret.second );
364 CPPUNIT_ASSERT( v1.s.nEnsureNewCall == s.nEnsureNewCall + 1);
365 CPPUNIT_ASSERT( v1.s.nEnsureExistsCall == s.nEnsureExistsCall );
366 CPPUNIT_ASSERT( !l.empty() );
369 CPPUNIT_ASSERT( l.erase( v1.key()) );
370 //CPPUNIT_ASSERT( v1.s.nDisposeCount == 0 );
371 CPPUNIT_ASSERT( !l.empty() );
373 CPPUNIT_ASSERT( v2.s.nEraseCall == 0 );
374 CPPUNIT_ASSERT( l.erase_with( v2.key(), less<value_type>(), erase_functor()) );
375 CPPUNIT_ASSERT( v2.s.nEraseCall == 1 );
376 CPPUNIT_ASSERT( !l.erase_with( v2.key(), less<value_type>()));
377 CPPUNIT_ASSERT( v2.s.nEraseCall == 1 );
378 //CPPUNIT_ASSERT( v2.s.nDisposeCount == 0 );
379 CPPUNIT_ASSERT( !l.empty() );
381 CPPUNIT_ASSERT( !l.erase( v2 ));
382 CPPUNIT_ASSERT( !l.erase( v1 ));
383 //CPPUNIT_ASSERT( v2.s.nDisposeCount == 0 );
384 CPPUNIT_ASSERT( !l.empty() );
386 CPPUNIT_ASSERT( v3.s.nEraseCall == 0 );
387 CPPUNIT_ASSERT( l.erase( v3, erase_functor() ));
388 CPPUNIT_ASSERT( v3.s.nEraseCall == 1 );
389 //CPPUNIT_ASSERT( v3.s.nDisposeCount == 0 );
390 CPPUNIT_ASSERT( l.empty() );
392 // Apply retired pointer to clean links
393 OrdList::gc::force_dispose();
396 CPPUNIT_ASSERT( l.insert( v1 ));
397 CPPUNIT_ASSERT( l.insert( v3 ));
398 CPPUNIT_ASSERT( !l.empty() );
399 CPPUNIT_ASSERT( !l.unlink( v2 ));
400 CPPUNIT_ASSERT( l.unlink( v1 ));
401 CPPUNIT_ASSERT( !l.unlink( v1 ));
402 CPPUNIT_ASSERT( l.unlink( v3 ));
403 CPPUNIT_ASSERT( !l.unlink( v3 ));
404 CPPUNIT_ASSERT( l.empty() );
406 // Apply retired pointer
407 OrdList::gc::force_dispose();
408 CPPUNIT_ASSERT( v1.s.nDisposeCount == 3 );
409 CPPUNIT_ASSERT( v2.s.nDisposeCount == 2 );
410 CPPUNIT_ASSERT( v3.s.nDisposeCount == 3 );
412 // Destructor test (call disposer)
413 CPPUNIT_ASSERT( l.insert( v1 ));
414 CPPUNIT_ASSERT( l.insert( v3 ));
415 CPPUNIT_ASSERT( l.insert( v2 ));
419 typename OrdList::iterator it = l.begin();
420 typename OrdList::const_iterator cit = l.cbegin();
421 CPPUNIT_ASSERT( it != l.end() );
422 CPPUNIT_ASSERT( it != l.cend() );
423 CPPUNIT_ASSERT( cit != l.end() );
424 CPPUNIT_ASSERT( cit != l.cend() );
425 CPPUNIT_ASSERT( cit == it );
427 CPPUNIT_ASSERT( it->nKey == v2.nKey );
428 CPPUNIT_ASSERT( it->nVal == v2.nVal );
429 CPPUNIT_ASSERT( ++it != l.end() );
430 CPPUNIT_ASSERT( it->nKey == v1.nKey );
431 CPPUNIT_ASSERT( it->nVal == v1.nVal );
432 CPPUNIT_ASSERT( ++it != l.end() );
433 CPPUNIT_ASSERT( it->nKey == v3.nKey );
434 CPPUNIT_ASSERT( it->nVal == v3.nVal );
435 CPPUNIT_ASSERT( ++it == l.end() );
439 OrdList const & lref = l;
440 typename OrdList::const_iterator it = lref.begin();
441 CPPUNIT_ASSERT( it != l.end() );
442 CPPUNIT_ASSERT( it->nKey == v2.nKey );
443 CPPUNIT_ASSERT( it->nVal == v2.nVal );
444 CPPUNIT_ASSERT( ++it != lref.end() );
445 CPPUNIT_ASSERT( it->nKey == v1.nKey );
446 CPPUNIT_ASSERT( it->nVal == v1.nVal );
447 CPPUNIT_ASSERT( ++it != l.end() );
448 CPPUNIT_ASSERT( it->nKey == v3.nKey );
449 CPPUNIT_ASSERT( it->nVal == v3.nVal );
450 CPPUNIT_ASSERT( ++it == l.end() );
454 // Apply retired pointer
455 OrdList::gc::force_dispose();
457 CPPUNIT_ASSERT( v1.s.nDisposeCount == 4 );
458 CPPUNIT_ASSERT( v2.s.nDisposeCount == 3 );
459 CPPUNIT_ASSERT( v3.s.nDisposeCount == 4 );
462 template <class OrdList>
465 test_int_common<OrdList>();
468 typename OrdList::guarded_ptr gp;
470 static int const nLimit = 20;
471 typename OrdList::value_type arrItem[nLimit];
475 for (int i = 0; i < nLimit; ++i)
477 std::random_shuffle( a, a + nLimit );
479 for (int i = 0; i < nLimit; ++i) {
480 arrItem[i].nKey = a[i];
481 arrItem[i].nVal = a[i] * 2;
485 for ( int i = 0; i < nLimit; ++i )
486 CPPUNIT_ASSERT( l.insert( arrItem[i] ) );
488 for ( int i=0; i < nLimit; ++i ) {
489 gp = l.get( arrItem[i].nKey );
490 CPPUNIT_ASSERT( gp );
491 CPPUNIT_ASSERT( !gp.empty());
492 CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey );
493 CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal );
495 gp = l.extract( arrItem[i].nKey );
496 CPPUNIT_ASSERT( gp );
497 CPPUNIT_ASSERT( !gp.empty());
498 CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey );
499 CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal );
501 gp = l.get( arrItem[i].nKey );
502 CPPUNIT_ASSERT( !gp );
503 CPPUNIT_ASSERT( gp.empty());
504 CPPUNIT_ASSERT( !l.extract( arrItem[i].nKey ));
505 CPPUNIT_ASSERT( gp.empty());
507 CPPUNIT_ASSERT( l.empty() );
508 CPPUNIT_ASSERT( !l.get( nLimit/2 ));
509 CPPUNIT_ASSERT( !l.extract( nLimit/2 ));
511 // Apply retired pointer
512 OrdList::gc::force_dispose();
514 // extract_with/get_with
515 for ( int i = 0; i < nLimit; ++i )
516 CPPUNIT_ASSERT( l.insert( arrItem[i] ) );
518 for ( int i=0; i < nLimit; ++i ) {
519 other_item itm( arrItem[i].nKey );
520 gp = l.get_with( itm, other_less() );
521 CPPUNIT_ASSERT( gp );
522 CPPUNIT_ASSERT( !gp.empty());
523 CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey );
524 CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal );
526 gp = l.extract_with( itm, other_less() );
527 CPPUNIT_ASSERT( gp );
528 CPPUNIT_ASSERT( !gp.empty());
529 CPPUNIT_ASSERT( gp->nKey == arrItem[i].nKey );
530 CPPUNIT_ASSERT( gp->nVal == arrItem[i].nVal );
532 gp = l.get_with( itm, other_less() );
533 CPPUNIT_ASSERT( !gp );
534 CPPUNIT_ASSERT( gp.empty());
535 CPPUNIT_ASSERT( !l.extract_with( itm, other_less() ));
536 CPPUNIT_ASSERT( gp.empty());
538 CPPUNIT_ASSERT( l.empty() );
539 CPPUNIT_ASSERT( !l.get_with( other_item(nLimit/2), other_less() ));
540 CPPUNIT_ASSERT( gp.empty());
541 CPPUNIT_ASSERT( !l.extract_with( other_item(nLimit/2), other_less() ));
542 CPPUNIT_ASSERT( gp.empty());
544 // Apply retired pointer
545 OrdList::gc::force_dispose();
547 for ( int i=0; i < nLimit; i++ ) {
548 CPPUNIT_ASSERT( arrItem[i].s.nDisposeCount == 2 );
553 template <class OrdList>
556 test_int_common<OrdList>();
559 static int const nLimit = 20;
560 typename OrdList::value_type arrItem[nLimit];
562 typedef typename OrdList::rcu_lock rcu_lock;
563 typedef typename OrdList::value_type value_type;
564 typedef typename OrdList::gc rcu_type;
568 for (int i = 0; i < nLimit; ++i)
570 std::random_shuffle( a, a + nLimit );
572 for (int i = 0; i < nLimit; ++i) {
573 arrItem[i].nKey = a[i];
574 arrItem[i].nVal = a[i] * 2;
577 typename OrdList::exempt_ptr ep;
580 for ( int i = 0; i < nLimit; ++i )
581 CPPUNIT_ASSERT( l.insert( arrItem[i] ) );
583 for ( int i = 0; i < nLimit; ++i ) {
586 value_type * pGet = l.get( a[i] );
587 CPPUNIT_ASSERT( pGet != nullptr );
588 CPPUNIT_CHECK( pGet->nKey == a[i] );
589 CPPUNIT_CHECK( pGet->nVal == a[i] * 2 );
591 ep = l.extract( a[i] );
592 CPPUNIT_ASSERT( ep );
593 CPPUNIT_ASSERT( !ep.empty() );
594 CPPUNIT_CHECK( ep->nKey == a[i] );
595 CPPUNIT_CHECK( (*ep).nVal == a[i] * 2 );
600 CPPUNIT_CHECK( l.get( a[i] ) == nullptr );
601 CPPUNIT_CHECK( !l.extract( a[i] ) );
602 CPPUNIT_CHECK( ep.empty() );
605 CPPUNIT_ASSERT( l.empty() );
609 CPPUNIT_CHECK( l.get( a[0] ) == nullptr );
610 ep = l.extract( a[0] );
611 CPPUNIT_CHECK( !ep );
612 CPPUNIT_CHECK( ep.empty() );
614 // Apply retired pointer
615 OrdList::gc::force_dispose();
617 // extract_with/get_with
618 for ( int i = 0; i < nLimit; ++i ) {
619 CPPUNIT_ASSERT( l.insert( arrItem[i] ) );
622 for ( int i = 0; i < nLimit; ++i ) {
623 other_item itm( a[i] );
626 value_type * pGet = l.get_with( itm, other_less() );
627 CPPUNIT_ASSERT( pGet != nullptr );
628 CPPUNIT_CHECK( pGet->nKey == a[i] );
629 CPPUNIT_CHECK( pGet->nVal == a[i] * 2 );
631 ep = l.extract_with( itm, other_less() );
632 CPPUNIT_ASSERT( ep );
633 CPPUNIT_ASSERT( !ep.empty() );
634 CPPUNIT_CHECK( ep->nKey == a[i] );
635 CPPUNIT_CHECK( ep->nVal == a[i] * 2 );
640 CPPUNIT_CHECK( l.get_with( itm, other_less() ) == nullptr );
641 ep = l.extract_with( itm, other_less() );
642 CPPUNIT_CHECK( !ep );
643 CPPUNIT_CHECK( ep.empty() );
646 CPPUNIT_ASSERT( l.empty() );
650 CPPUNIT_CHECK( l.get_with( other_item( 0 ), other_less() ) == nullptr );
651 CPPUNIT_CHECK( !l.extract_with( other_item(0), other_less() ));
652 CPPUNIT_CHECK( ep.empty() );
654 // Apply retired pointer
655 OrdList::gc::force_dispose();
659 template <class OrdList>
662 typedef typename OrdList::value_type value_type;
665 value_type v1( 10, 50 );
666 value_type v2( 5, 25 );
667 value_type v3( 20, 100 );
670 CPPUNIT_ASSERT( l.empty() );
672 CPPUNIT_ASSERT( l.insert( v1 )) ; // true
673 CPPUNIT_ASSERT( l.find( v1.key() ) == &v1 );
675 CPPUNIT_ASSERT( v1.s.nFindCall == 0 );
676 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
677 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
679 CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>() ) == nullptr );
680 CPPUNIT_ASSERT( l.find( v3.key() ) == nullptr );
681 CPPUNIT_ASSERT( !l.empty() );
683 //CPPUNIT_ASSERT( !l.insert( v1 )) ; // assertion "is_empty" is raised
687 CPPUNIT_ASSERT( !l.insert( v )) ; // false
690 std::pair<bool, bool> ret = l.ensure( v2, ensure_functor() );
691 CPPUNIT_ASSERT( ret.first );
692 CPPUNIT_ASSERT( ret.second );
693 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
694 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 0 );
696 //CPPUNIT_ASSERT( !l.insert( v2 )) ; // assertion "is_empty"
698 CPPUNIT_ASSERT( l.find( v1.key() ) == &v1 ) ; // true
700 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
701 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
702 CPPUNIT_ASSERT( v1.s.nFindCall == 2 );
704 CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>() ) == &v2 );
706 CPPUNIT_ASSERT( v2.s.nFindCall == 0 );
707 CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>(), find_functor() ));
708 CPPUNIT_ASSERT( v2.s.nFindCall == 1 );
710 CPPUNIT_ASSERT( !l.find( v3.key() ));
714 ret = l.ensure( v, ensure_functor() );
716 CPPUNIT_ASSERT( ret.first );
717 CPPUNIT_ASSERT( !ret.second );
718 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 1 );
719 CPPUNIT_ASSERT( v.s.nEnsureExistsCall == 0 && v.s.nEnsureNewCall == 0 );
722 CPPUNIT_ASSERT( !l.empty() );
724 CPPUNIT_ASSERT( l.insert( v3 )) ; // true
725 CPPUNIT_ASSERT( l.find( v3.key() ) == &v3 );
727 CPPUNIT_ASSERT( v3.s.nFindCall == 0 );
728 CPPUNIT_ASSERT( l.find( v3.key(), find_functor() ));
729 CPPUNIT_ASSERT( v3.s.nFindCall == 1 );
732 typename OrdList::iterator it = l.begin();
733 typename OrdList::const_iterator cit = l.cbegin();
734 CPPUNIT_ASSERT( it != l.end() );
735 CPPUNIT_ASSERT( it != l.cend() );
736 CPPUNIT_ASSERT( cit != l.end() );
737 CPPUNIT_ASSERT( cit != l.cend() );
738 CPPUNIT_ASSERT( cit == it );
740 CPPUNIT_ASSERT( it->nKey == v2.nKey );
741 CPPUNIT_ASSERT( it->nVal == v2.nVal );
742 CPPUNIT_ASSERT( ++it != l.end() );
743 CPPUNIT_ASSERT( it->nKey == v1.nKey );
744 CPPUNIT_ASSERT( it->nVal == v1.nVal );
745 CPPUNIT_ASSERT( it++ != l.end() );
746 CPPUNIT_ASSERT( it->nKey == v3.nKey );
747 CPPUNIT_ASSERT( it->nVal == v3.nVal );
748 CPPUNIT_ASSERT( it++ != l.end() );
749 CPPUNIT_ASSERT( it == l.end() );
753 OrdList const & lref = l;
754 typename OrdList::const_iterator it = lref.begin();
755 CPPUNIT_ASSERT( it != l.end() );
756 CPPUNIT_ASSERT( it->nKey == v2.nKey );
757 CPPUNIT_ASSERT( it->nVal == v2.nVal );
758 CPPUNIT_ASSERT( ++it != lref.end() );
759 CPPUNIT_ASSERT( it->nKey == v1.nKey );
760 CPPUNIT_ASSERT( it->nVal == v1.nVal );
761 CPPUNIT_ASSERT( it++ != l.end() );
762 CPPUNIT_ASSERT( it->nKey == v3.nKey );
763 CPPUNIT_ASSERT( it->nVal == v3.nVal );
764 CPPUNIT_ASSERT( it++ != lref.end() );
765 CPPUNIT_ASSERT( it == l.end() );
769 // Disposer called on list destruction
770 CPPUNIT_ASSERT( v1.s.nDisposeCount == 1 );
771 CPPUNIT_ASSERT( v2.s.nDisposeCount == 1 );
772 CPPUNIT_ASSERT( v3.s.nDisposeCount == 1 );
776 template <class UnordList>
777 void test_nogc_int_unordered()
779 typedef typename UnordList::value_type value_type;
781 value_type v1( 10, 50 );
782 value_type v2( 5, 25 );
783 value_type v3( 20, 100 );
786 CPPUNIT_ASSERT( l.empty() );
788 CPPUNIT_ASSERT( l.insert( v1 )); // true
789 CPPUNIT_ASSERT( l.find( v1.key() ) == &v1 );
791 CPPUNIT_ASSERT( v1.s.nFindCall == 0 );
792 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
793 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
795 CPPUNIT_ASSERT( l.find_with( v2.key(), equal_to<value_type>() ) == nullptr );
796 CPPUNIT_ASSERT( l.find( v3.key() ) == nullptr );
797 CPPUNIT_ASSERT( !l.empty() );
799 //CPPUNIT_ASSERT( !l.insert( v1 )) ; // assertion "is_empty" is raised
803 CPPUNIT_ASSERT( !l.insert( v )) ; // false
806 std::pair<bool, bool> ret = l.ensure( v2, ensure_functor() );
807 CPPUNIT_ASSERT( ret.first );
808 CPPUNIT_ASSERT( ret.second );
809 CPPUNIT_ASSERT( v2.s.nEnsureNewCall == 1 );
810 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 0 );
812 //CPPUNIT_ASSERT( !l.insert( v2 )) ; // assertion "is_empty"
814 CPPUNIT_ASSERT( l.find( v1.key() ) == &v1 ) ; // true
816 CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
817 CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
818 CPPUNIT_ASSERT( v1.s.nFindCall == 2 );
820 CPPUNIT_ASSERT( l.find_with( v2.key(), equal_to<value_type>() ) == &v2 );
822 CPPUNIT_ASSERT( v2.s.nFindCall == 0 );
823 CPPUNIT_ASSERT( l.find_with( v2.key(), equal_to<value_type>(), find_functor() ));
824 CPPUNIT_ASSERT( v2.s.nFindCall == 1 );
826 CPPUNIT_ASSERT( !l.find( v3.key() ));
830 ret = l.ensure( v, ensure_functor() );
832 CPPUNIT_ASSERT( ret.first );
833 CPPUNIT_ASSERT( !ret.second );
834 CPPUNIT_ASSERT( v2.s.nEnsureExistsCall == 1 );
835 CPPUNIT_ASSERT( v.s.nEnsureExistsCall == 0 && v.s.nEnsureNewCall == 0 );
838 CPPUNIT_ASSERT( !l.empty() );
840 CPPUNIT_ASSERT( l.insert( v3 )) ; // true
841 CPPUNIT_ASSERT( l.find( v3.key() ) == &v3 );
843 CPPUNIT_ASSERT( v3.s.nFindCall == 0 );
844 CPPUNIT_ASSERT( l.find( v3.key(), find_functor() ));
845 CPPUNIT_ASSERT( v3.s.nFindCall == 1 );
848 typename UnordList::iterator it = l.begin();
849 typename UnordList::const_iterator cit = l.cbegin();
850 CPPUNIT_ASSERT( it != l.end() );
851 CPPUNIT_ASSERT( it != l.cend() );
852 CPPUNIT_ASSERT( cit != l.end() );
853 CPPUNIT_ASSERT( cit != l.cend() );
854 CPPUNIT_ASSERT( cit == it );
856 CPPUNIT_ASSERT( it->nKey == v1.nKey );
857 CPPUNIT_ASSERT( it->nVal == v1.nVal );
858 CPPUNIT_ASSERT( ++it != l.end() );
859 CPPUNIT_ASSERT( it->nKey == v2.nKey );
860 CPPUNIT_ASSERT( it->nVal == v2.nVal );
861 CPPUNIT_ASSERT( it++ != l.end() );
862 CPPUNIT_ASSERT( it->nKey == v3.nKey );
863 CPPUNIT_ASSERT( it->nVal == v3.nVal );
864 CPPUNIT_ASSERT( it++ != l.end() );
865 CPPUNIT_ASSERT( it == l.end() );
869 UnordList const & lref = l;
870 typename UnordList::const_iterator it = lref.begin();
871 CPPUNIT_ASSERT( it != l.end() );
872 CPPUNIT_ASSERT( it->nKey == v1.nKey );
873 CPPUNIT_ASSERT( it->nVal == v1.nVal );
874 CPPUNIT_ASSERT( ++it != lref.end() );
875 CPPUNIT_ASSERT( it->nKey == v2.nKey );
876 CPPUNIT_ASSERT( it->nVal == v2.nVal );
877 CPPUNIT_ASSERT( it++ != l.end() );
878 CPPUNIT_ASSERT( it->nKey == v3.nKey );
879 CPPUNIT_ASSERT( it->nVal == v3.nVal );
880 CPPUNIT_ASSERT( it++ != lref.end() );
881 CPPUNIT_ASSERT( it == l.end() );
885 // Disposer called on list destruction
886 CPPUNIT_ASSERT( v1.s.nDisposeCount == 1 );
887 CPPUNIT_ASSERT( v2.s.nDisposeCount == 1 );
888 CPPUNIT_ASSERT( v3.s.nDisposeCount == 1 );
895 void HP_base_cmpmix();
897 void HP_member_cmp();
898 void HP_member_less();
899 void HP_member_cmpmix();
903 void DHP_base_less();
904 void DHP_base_cmpmix();
906 void DHP_member_cmp();
907 void DHP_member_less();
908 void DHP_member_cmpmix();
909 void DHP_member_ic();
911 void RCU_GPI_base_cmp();
912 void RCU_GPI_base_less();
913 void RCU_GPI_base_cmpmix();
914 void RCU_GPI_base_ic();
915 void RCU_GPI_member_cmp();
916 void RCU_GPI_member_less();
917 void RCU_GPI_member_cmpmix();
918 void RCU_GPI_member_ic();
920 void RCU_GPB_base_cmp();
921 void RCU_GPB_base_less();
922 void RCU_GPB_base_cmpmix();
923 void RCU_GPB_base_ic();
924 void RCU_GPB_member_cmp();
925 void RCU_GPB_member_less();
926 void RCU_GPB_member_cmpmix();
927 void RCU_GPB_member_ic();
929 void RCU_GPT_base_cmp();
930 void RCU_GPT_base_less();
931 void RCU_GPT_base_cmpmix();
932 void RCU_GPT_base_ic();
933 void RCU_GPT_member_cmp();
934 void RCU_GPT_member_less();
935 void RCU_GPT_member_cmpmix();
936 void RCU_GPT_member_ic();
938 void RCU_SHB_base_cmp();
939 void RCU_SHB_base_less();
940 void RCU_SHB_base_cmpmix();
941 void RCU_SHB_base_ic();
942 void RCU_SHB_member_cmp();
943 void RCU_SHB_member_less();
944 void RCU_SHB_member_cmpmix();
945 void RCU_SHB_member_ic();
947 void RCU_SHT_base_cmp();
948 void RCU_SHT_base_less();
949 void RCU_SHT_base_cmpmix();
950 void RCU_SHT_base_ic();
951 void RCU_SHT_member_cmp();
952 void RCU_SHT_member_less();
953 void RCU_SHT_member_cmpmix();
954 void RCU_SHT_member_ic();
956 void nogc_base_cmp();
957 void nogc_base_less();
958 void nogc_base_cmpmix();
960 void nogc_member_cmp();
961 void nogc_member_less();
962 void nogc_member_cmpmix();
963 void nogc_member_ic();
965 void nogc_base_cmp_unord();
966 void nogc_base_less_unord();
967 void nogc_base_equal_to_unord();
968 void nogc_base_cmpmix_unord();
969 void nogc_base_equal_to_mix_unord();
970 void nogc_base_ic_unord();
971 void nogc_member_cmp_unord();
972 void nogc_member_less_unord();
973 void nogc_member_equal_to_unord();
974 void nogc_member_cmpmix_unord();
975 void nogc_member_equal_to_mix_unord();
976 void nogc_member_ic_unord();
978 CPPUNIT_TEST_SUITE(IntrusiveLazyListHeaderTest)
979 CPPUNIT_TEST(HP_base_cmp)
980 CPPUNIT_TEST(HP_base_less)
981 CPPUNIT_TEST(HP_base_cmpmix)
982 CPPUNIT_TEST(HP_base_ic)
983 CPPUNIT_TEST(HP_member_cmp)
984 CPPUNIT_TEST(HP_member_less)
985 CPPUNIT_TEST(HP_member_cmpmix)
986 CPPUNIT_TEST(HP_member_ic)
988 CPPUNIT_TEST(DHP_base_cmp)
989 CPPUNIT_TEST(DHP_base_less)
990 CPPUNIT_TEST(DHP_base_cmpmix)
991 CPPUNIT_TEST(DHP_base_ic)
992 CPPUNIT_TEST(DHP_member_cmp)
993 CPPUNIT_TEST(DHP_member_less)
994 CPPUNIT_TEST(DHP_member_cmpmix)
995 CPPUNIT_TEST(DHP_member_ic)
997 CPPUNIT_TEST(RCU_GPI_base_cmp)
998 CPPUNIT_TEST(RCU_GPI_base_less)
999 CPPUNIT_TEST(RCU_GPI_base_cmpmix)
1000 CPPUNIT_TEST(RCU_GPI_base_ic)
1001 CPPUNIT_TEST(RCU_GPI_member_cmp)
1002 CPPUNIT_TEST(RCU_GPI_member_less)
1003 CPPUNIT_TEST(RCU_GPI_member_cmpmix)
1004 CPPUNIT_TEST(RCU_GPI_member_ic)
1006 CPPUNIT_TEST(RCU_GPB_base_cmp)
1007 CPPUNIT_TEST(RCU_GPB_base_less)
1008 CPPUNIT_TEST(RCU_GPB_base_cmpmix)
1009 CPPUNIT_TEST(RCU_GPB_base_ic)
1010 CPPUNIT_TEST(RCU_GPB_member_cmp)
1011 CPPUNIT_TEST(RCU_GPB_member_less)
1012 CPPUNIT_TEST(RCU_GPB_member_cmpmix)
1013 CPPUNIT_TEST(RCU_GPB_member_ic)
1015 CPPUNIT_TEST(RCU_GPT_base_cmp)
1016 CPPUNIT_TEST(RCU_GPT_base_less)
1017 CPPUNIT_TEST(RCU_GPT_base_cmpmix)
1018 CPPUNIT_TEST(RCU_GPT_base_ic)
1019 CPPUNIT_TEST(RCU_GPT_member_cmp)
1020 CPPUNIT_TEST(RCU_GPT_member_less)
1021 CPPUNIT_TEST(RCU_GPT_member_cmpmix)
1022 CPPUNIT_TEST(RCU_GPT_member_ic)
1024 CPPUNIT_TEST(RCU_SHB_base_cmp)
1025 CPPUNIT_TEST(RCU_SHB_base_less)
1026 CPPUNIT_TEST(RCU_SHB_base_cmpmix)
1027 CPPUNIT_TEST(RCU_SHB_base_ic)
1028 CPPUNIT_TEST(RCU_SHB_member_cmp)
1029 CPPUNIT_TEST(RCU_SHB_member_less)
1030 CPPUNIT_TEST(RCU_SHB_member_cmpmix)
1031 CPPUNIT_TEST(RCU_SHB_member_ic)
1033 CPPUNIT_TEST(RCU_SHT_base_cmp)
1034 CPPUNIT_TEST(RCU_SHT_base_less)
1035 CPPUNIT_TEST(RCU_SHT_base_cmpmix)
1036 CPPUNIT_TEST(RCU_SHT_base_ic)
1037 CPPUNIT_TEST(RCU_SHT_member_cmp)
1038 CPPUNIT_TEST(RCU_SHT_member_less)
1039 CPPUNIT_TEST(RCU_SHT_member_cmpmix)
1040 CPPUNIT_TEST(RCU_SHT_member_ic)
1042 CPPUNIT_TEST(nogc_base_cmp)
1043 CPPUNIT_TEST(nogc_base_less)
1044 CPPUNIT_TEST(nogc_base_cmpmix)
1045 CPPUNIT_TEST(nogc_base_ic)
1046 CPPUNIT_TEST(nogc_member_cmp)
1047 CPPUNIT_TEST(nogc_member_less)
1048 CPPUNIT_TEST(nogc_member_cmpmix)
1049 CPPUNIT_TEST(nogc_member_ic)
1051 CPPUNIT_TEST(nogc_base_cmp_unord)
1052 CPPUNIT_TEST(nogc_base_less_unord)
1053 CPPUNIT_TEST(nogc_base_equal_to_unord)
1054 CPPUNIT_TEST(nogc_base_cmpmix_unord)
1055 CPPUNIT_TEST(nogc_base_equal_to_mix_unord)
1056 CPPUNIT_TEST(nogc_base_ic_unord)
1057 CPPUNIT_TEST(nogc_member_cmp_unord)
1058 CPPUNIT_TEST(nogc_member_less_unord)
1059 CPPUNIT_TEST(nogc_member_equal_to_unord)
1060 CPPUNIT_TEST(nogc_member_cmpmix_unord)
1061 CPPUNIT_TEST(nogc_member_equal_to_mix_unord)
1062 CPPUNIT_TEST(nogc_member_ic_unord)
1064 CPPUNIT_TEST_SUITE_END()
1066 } // namespace ordlist
1068 #endif // #ifndef CDSTEST_HDR_INTRUSIVE_LAZY_H