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:
parent
b916df3b62
commit
a4a2a9eda4
3 changed files with 167 additions and 0 deletions
|
@ -159,6 +159,19 @@ class T_RcPtr
|
||||||
// Access the object; undefined behavior if get() == nullptr.
|
// Access the object; undefined behavior if get() == nullptr.
|
||||||
Type* operator -> ( ) const;
|
Type* operator -> ( ) const;
|
||||||
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 >
|
template< typename T >
|
||||||
|
|
|
@ -295,6 +295,30 @@ inline T& T_RcPtr< T >::operator * ( ) const
|
||||||
return *target_;
|
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
|
} // namespace ebcl
|
||||||
#endif // _H_EBCL_INLINE_REFCOUNT
|
#endif // _H_EBCL_INLINE_REFCOUNT
|
||||||
|
|
|
@ -47,6 +47,12 @@ class RefCountTest : public CppUnit::TestFixture
|
||||||
CPPUNIT_TEST( testMoveAssToChildBad );
|
CPPUNIT_TEST( testMoveAssToChildBad );
|
||||||
|
|
||||||
CPPUNIT_TEST( testSwap );
|
CPPUNIT_TEST( testSwap );
|
||||||
|
|
||||||
|
CPPUNIT_TEST( testEq );
|
||||||
|
CPPUNIT_TEST( testEqChild );
|
||||||
|
|
||||||
|
CPPUNIT_TEST( testNEq );
|
||||||
|
CPPUNIT_TEST( testNEqChild );
|
||||||
CPPUNIT_TEST_SUITE_END( );
|
CPPUNIT_TEST_SUITE_END( );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -78,6 +84,12 @@ class RefCountTest : public CppUnit::TestFixture
|
||||||
void testMoveAssToChildBad( );
|
void testMoveAssToChildBad( );
|
||||||
|
|
||||||
void testSwap( );
|
void testSwap( );
|
||||||
|
|
||||||
|
void testEq( );
|
||||||
|
void testEqChild( );
|
||||||
|
|
||||||
|
void testNEq( );
|
||||||
|
void testNEqChild( );
|
||||||
};
|
};
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest< true > );
|
CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest< true > );
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest< false > );
|
CPPUNIT_TEST_SUITE_REGISTRATION( RefCountTest< false > );
|
||||||
|
@ -372,3 +384,121 @@ void RefCountTest< A >::testSwap( )
|
||||||
}
|
}
|
||||||
CPPUNIT_ASSERT_EQUAL( 1u , T_Test::cDel );
|
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 ) );
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue