Reference-counting helpers - Equality operators

* Added == and != operators; they can only be used if the referenced types are
from the same hierarchy
 * Tests for the above
This commit is contained in:
Emmanuel BENOîT 2019-01-02 17:52:56 +01:00
parent b916df3b62
commit a4a2a9eda4
3 changed files with 167 additions and 0 deletions

View file

@ -159,6 +159,19 @@ class T_RcPtr
// Access the object; undefined behavior if get() == nullptr.
Type* operator -> ( ) const;
Type& operator * ( ) const;
// ---------------------------------------------------------------------
// Comparison operators
template<
typename Q ,
T_EnableForHierarchy< Type , Q > = true
> bool operator== ( T_RcPtr< Q > const& p ) const noexcept;
template<
typename Q ,
T_EnableForHierarchy< Type , Q > = true
> bool operator!= ( T_RcPtr< Q > const& p ) const noexcept;
};
template< typename T >

View file

@ -295,6 +295,30 @@ inline T& T_RcPtr< T >::operator * ( ) const
return *target_;
}
/*----------------------------------------------------------------------------*/
template< typename T >
template<
typename Q ,
T_EnableForHierarchy< T , Q >
> inline bool T_RcPtr< T >::operator== (
T_RcPtr< Q > const& p ) const noexcept
{
return (char const*) this == (char const*) &p
|| (char const*) p.target_ == (char const*) target_;
}
template< typename T >
template<
typename Q ,
T_EnableForHierarchy< T , Q >
> inline bool T_RcPtr< T >::operator!= (
T_RcPtr< Q > const& p ) const noexcept
{
return (char const*) this != (char const*) &p
&& (char const*) p.target_ != (char const*) target_;
}
} // namespace ebcl
#endif // _H_EBCL_INLINE_REFCOUNT

View file

@ -47,6 +47,12 @@ class RefCountTest : public CppUnit::TestFixture
CPPUNIT_TEST( testMoveAssToChildBad );
CPPUNIT_TEST( testSwap );
CPPUNIT_TEST( testEq );
CPPUNIT_TEST( testEqChild );
CPPUNIT_TEST( testNEq );
CPPUNIT_TEST( testNEqChild );
CPPUNIT_TEST_SUITE_END( );
public:
@ -78,6 +84,12 @@ class RefCountTest : public CppUnit::TestFixture
void testMoveAssToChildBad( );
void testSwap( );
void testEq( );
void testEqChild( );
void testNEq( );
void testNEqChild( );
};
CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest< true > );
CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest< false > );
@ -372,3 +384,121 @@ void RefCountTest< A >::testSwap( )
}
CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel );
}
/*----------------------------------------------------------------------------*/
template< bool A >
void RefCountTest< A >::testEq( )
{
P_Test p1{ P_Test::New( ) },
p2{ p1 } ,
p3{ P_Test::New( ) },
p4;
CPPUNIT_ASSERT( ( p1 == p1 ) );
CPPUNIT_ASSERT( ( p1 == p2 ) );
CPPUNIT_ASSERT( !( p1 == p3 ) );
CPPUNIT_ASSERT( !( p1 == p4 ) );
CPPUNIT_ASSERT( ( p2 == p1 ) );
CPPUNIT_ASSERT( ( p2 == p2 ) );
CPPUNIT_ASSERT( !( p2 == p3 ) );
CPPUNIT_ASSERT( !( p2 == p4 ) );
CPPUNIT_ASSERT( !( p3 == p1 ) );
CPPUNIT_ASSERT( !( p3 == p2 ) );
CPPUNIT_ASSERT( ( p3 == p3 ) );
CPPUNIT_ASSERT( !( p3 == p4 ) );
CPPUNIT_ASSERT( !( p4 == p1 ) );
CPPUNIT_ASSERT( !( p4 == p2 ) );
CPPUNIT_ASSERT( !( p4 == p3 ) );
CPPUNIT_ASSERT( ( p4 == p4 ) );
}
template< bool A >
void RefCountTest< A >::testEqChild( )
{
P_Child p1{ P_Child::New( ) } ,
p2{ P_Child::New( ) };
P_Test p3{ p1 } , p4{ p2 };
CPPUNIT_ASSERT( ( p1 == p1 ) );
CPPUNIT_ASSERT( !( p1 == p2 ) );
CPPUNIT_ASSERT( ( p1 == p3 ) );
CPPUNIT_ASSERT( !( p1 == p4 ) );
CPPUNIT_ASSERT( !( p2 == p1 ) );
CPPUNIT_ASSERT( ( p2 == p2 ) );
CPPUNIT_ASSERT( !( p2 == p3 ) );
CPPUNIT_ASSERT( ( p2 == p4 ) );
CPPUNIT_ASSERT( ( p3 == p1 ) );
CPPUNIT_ASSERT( !( p3 == p2 ) );
CPPUNIT_ASSERT( ( p3 == p3 ) );
CPPUNIT_ASSERT( !( p3 == p4 ) );
CPPUNIT_ASSERT( !( p4 == p1 ) );
CPPUNIT_ASSERT( ( p4 == p2 ) );
CPPUNIT_ASSERT( !( p4 == p3 ) );
CPPUNIT_ASSERT( ( p4 == p4 ) );
}
/*----------------------------------------------------------------------------*/
template< bool A >
void RefCountTest< A >::testNEq( )
{
P_Test p1{ P_Test::New( ) },
p2{ p1 } ,
p3{ P_Test::New( ) },
p4;
CPPUNIT_ASSERT( !( p1 != p1 ) );
CPPUNIT_ASSERT( !( p1 != p2 ) );
CPPUNIT_ASSERT( ( p1 != p3 ) );
CPPUNIT_ASSERT( ( p1 != p4 ) );
CPPUNIT_ASSERT( !( p2 != p1 ) );
CPPUNIT_ASSERT( !( p2 != p2 ) );
CPPUNIT_ASSERT( ( p2 != p3 ) );
CPPUNIT_ASSERT( ( p2 != p4 ) );
CPPUNIT_ASSERT( ( p3 != p1 ) );
CPPUNIT_ASSERT( ( p3 != p2 ) );
CPPUNIT_ASSERT( !( p3 != p3 ) );
CPPUNIT_ASSERT( ( p3 != p4 ) );
CPPUNIT_ASSERT( ( p4 != p1 ) );
CPPUNIT_ASSERT( ( p4 != p2 ) );
CPPUNIT_ASSERT( ( p4 != p3 ) );
CPPUNIT_ASSERT( !( p4 != p4 ) );
}
template< bool A >
void RefCountTest< A >::testNEqChild( )
{
P_Child p1{ P_Child::New( ) } ,
p2{ P_Child::New( ) };
P_Test p3{ p1 } , p4{ p2 };
CPPUNIT_ASSERT( !( p1 != p1 ) );
CPPUNIT_ASSERT( ( p1 != p2 ) );
CPPUNIT_ASSERT( !( p1 != p3 ) );
CPPUNIT_ASSERT( ( p1 != p4 ) );
CPPUNIT_ASSERT( ( p2 != p1 ) );
CPPUNIT_ASSERT( !( p2 != p2 ) );
CPPUNIT_ASSERT( ( p2 != p3 ) );
CPPUNIT_ASSERT( !( p2 != p4 ) );
CPPUNIT_ASSERT( !( p3 != p1 ) );
CPPUNIT_ASSERT( ( p3 != p2 ) );
CPPUNIT_ASSERT( !( p3 != p3 ) );
CPPUNIT_ASSERT( ( p3 != p4 ) );
CPPUNIT_ASSERT( ( p4 != p1 ) );
CPPUNIT_ASSERT( !( p4 != p2 ) );
CPPUNIT_ASSERT( ( p4 != p3 ) );
CPPUNIT_ASSERT( !( p4 != p4 ) );
}