Added tests for new single-owner policy classes for StrongPtr.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1081 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
a381009fee
commit
27f38492bd
1 changed files with 601 additions and 12 deletions
|
@ -23,12 +23,21 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if !defined( NULL )
|
||||||
|
#define nullptr 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined( nullptr )
|
||||||
|
#define nullptr NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Loki;
|
using namespace Loki;
|
||||||
|
|
||||||
|
@ -140,6 +149,7 @@ typedef Loki::StrongPtr< Moon, true, TwoRefCounts, DisallowConversion,
|
||||||
AssertCheck, AllowReset, DeleteSingle, DontPropagateConst >
|
AssertCheck, AllowReset, DeleteSingle, DontPropagateConst >
|
||||||
Moon_StrongPtr;
|
Moon_StrongPtr;
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class Earth
|
class Earth
|
||||||
|
@ -329,6 +339,8 @@ void DoWeakLeakTest( void )
|
||||||
const unsigned int ctorCount = Counted::GetCtorCount();
|
const unsigned int ctorCount = Counted::GetCtorCount();
|
||||||
const unsigned int dtorCount = Counted::GetDtorCount();
|
const unsigned int dtorCount = Counted::GetDtorCount();
|
||||||
assert( Counted::AllDestroyed() );
|
assert( Counted::AllDestroyed() );
|
||||||
|
(void)ctorCount;
|
||||||
|
(void)dtorCount;
|
||||||
|
|
||||||
{
|
{
|
||||||
Counted_WeakPtr pWeakInt;
|
Counted_WeakPtr pWeakInt;
|
||||||
|
@ -1028,6 +1040,586 @@ void DoWeakCycleTests( void )
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Ball
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
inline static unsigned int GetCtorCount( void )
|
||||||
|
{
|
||||||
|
return s_CtorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static unsigned int GetDtorCount( void )
|
||||||
|
{
|
||||||
|
return s_DtorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static bool AllDestroyed( void )
|
||||||
|
{
|
||||||
|
return ( s_CtorCount == s_DtorCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Ball( void )
|
||||||
|
{
|
||||||
|
s_CtorCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ~Ball( void )
|
||||||
|
{
|
||||||
|
s_DtorCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static unsigned int s_CtorCount;
|
||||||
|
static unsigned int s_DtorCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int Ball::s_CtorCount = 0;
|
||||||
|
unsigned int Ball::s_DtorCount = 0;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// These typedefs are for testing StrongPtr ownership policies that enforce a single owner.
|
||||||
|
typedef ::Loki::StrongPtr< Ball, false, ::Loki::SingleOwnerRefCount,
|
||||||
|
::Loki::DisallowConversion, ::Loki::AssertCheck, ::Loki::OnlyStrongMayReset >
|
||||||
|
NonOwner_Counted_BallPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Ball, true, ::Loki::SingleOwnerRefCount,
|
||||||
|
::Loki::DisallowConversion, ::Loki::AssertCheck, ::Loki::OnlyStrongMayReset >
|
||||||
|
Owner_Counted_BallPtr;
|
||||||
|
|
||||||
|
typedef ::Loki::StrongPtr< Ball, false, ::Loki::Lockable1OwnerRefCount,
|
||||||
|
::Loki::DisallowConversion, ::Loki::AssertCheck, ::Loki::OnlyStrongMayReset >
|
||||||
|
Lockable_NonOwner_Counted_BallPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Ball, true, ::Loki::Lockable1OwnerRefCount,
|
||||||
|
::Loki::DisallowConversion, ::Loki::AssertCheck, ::Loki::OnlyStrongMayReset >
|
||||||
|
Lockable_Owner_Counted_BallPtr;
|
||||||
|
|
||||||
|
typedef ::Loki::StrongPtr< Ball, false, ::Loki::SingleOwnerRefLinks,
|
||||||
|
::Loki::DisallowConversion, ::Loki::AssertCheck, ::Loki::OnlyStrongMayReset >
|
||||||
|
NonOwner_Linked_BallPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Ball, true, ::Loki::SingleOwnerRefLinks,
|
||||||
|
::Loki::DisallowConversion, ::Loki::AssertCheck, ::Loki::OnlyStrongMayReset >
|
||||||
|
Owner_Linked_BallPtr;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template < class OwnerPtr, class NonOwnerPtr >
|
||||||
|
class TheOwner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
TheOwner( void ) : m_myBall(), m_otherBall() {}
|
||||||
|
~TheOwner( void ) {}
|
||||||
|
|
||||||
|
void ClearBall( void )
|
||||||
|
{
|
||||||
|
Ball * pBall = NULL;
|
||||||
|
ResetAll( m_myBall, pBall );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OwnBall( const NonOwnerPtr & ball )
|
||||||
|
{
|
||||||
|
if ( !ball )
|
||||||
|
return false;
|
||||||
|
m_myBall = ball;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OwnBall( const OwnerPtr & ball )
|
||||||
|
{
|
||||||
|
if ( !ball )
|
||||||
|
return false;
|
||||||
|
m_myBall = ball;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OwnBall( Ball * ball )
|
||||||
|
{
|
||||||
|
if ( nullptr == ball )
|
||||||
|
return false;
|
||||||
|
m_myBall = ball;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DoesOwnBall( void ) const
|
||||||
|
{
|
||||||
|
const bool hasBall = m_myBall;
|
||||||
|
return hasBall;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UseBall( const OwnerPtr & ball )
|
||||||
|
{
|
||||||
|
m_otherBall = ball;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DoesUseBall( void ) const
|
||||||
|
{
|
||||||
|
const bool hasBall = m_otherBall;
|
||||||
|
return hasBall;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OwnerPtr & ShareMyBall( void ) const
|
||||||
|
{
|
||||||
|
return m_myBall;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NonOwnerPtr & ShareOtherBall( void )
|
||||||
|
{
|
||||||
|
return m_otherBall;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
OwnerPtr m_myBall;
|
||||||
|
NonOwnerPtr m_otherBall;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef TheOwner< Owner_Counted_BallPtr, NonOwner_Counted_BallPtr > Toddler;
|
||||||
|
|
||||||
|
typedef TheOwner< Owner_Linked_BallPtr, NonOwner_Linked_BallPtr > Kitten;
|
||||||
|
|
||||||
|
typedef TheOwner< Lockable_Owner_Counted_BallPtr, Lockable_NonOwner_Counted_BallPtr > Teenager;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template < class OwnerPtr, class NonOwnerPtr, class Owner >
|
||||||
|
void DoSingleOwnerTest( OwnerPtr & op1,
|
||||||
|
const NonOwnerPtr & pBall1,
|
||||||
|
const NonOwnerPtr & pBall2,
|
||||||
|
const NonOwnerPtr & pBall3,
|
||||||
|
Owner & owner1,
|
||||||
|
Owner & owner2,
|
||||||
|
Owner & owner3 )
|
||||||
|
{
|
||||||
|
|
||||||
|
assert( !pBall1.IsStrong() );
|
||||||
|
assert( !pBall2.IsStrong() );
|
||||||
|
assert( !pBall3.IsStrong() );
|
||||||
|
assert( pBall1 != nullptr );
|
||||||
|
assert( pBall2 != nullptr );
|
||||||
|
assert( pBall3 != nullptr );
|
||||||
|
|
||||||
|
assert( !owner1.DoesOwnBall() );
|
||||||
|
assert( !owner2.DoesOwnBall() );
|
||||||
|
assert( !owner3.DoesOwnBall() );
|
||||||
|
assert( !owner1.DoesUseBall() );
|
||||||
|
assert( !owner2.DoesUseBall() );
|
||||||
|
assert( !owner3.DoesUseBall() );
|
||||||
|
|
||||||
|
owner1.OwnBall( pBall1 );
|
||||||
|
owner2.OwnBall( pBall2 );
|
||||||
|
owner3.OwnBall( pBall3 );
|
||||||
|
assert( owner1.DoesOwnBall() );
|
||||||
|
assert( owner2.DoesOwnBall() );
|
||||||
|
assert( owner3.DoesOwnBall() );
|
||||||
|
assert( !owner1.DoesUseBall() );
|
||||||
|
assert( !owner2.DoesUseBall() );
|
||||||
|
assert( !owner3.DoesUseBall() );
|
||||||
|
|
||||||
|
assert( owner1.ShareMyBall() == pBall1 );
|
||||||
|
assert( owner2.ShareMyBall() == pBall2 );
|
||||||
|
assert( owner3.ShareMyBall() == pBall3 );
|
||||||
|
assert( owner1.ShareMyBall().IsStrong() );
|
||||||
|
assert( owner2.ShareMyBall().IsStrong() );
|
||||||
|
assert( owner3.ShareMyBall().IsStrong() );
|
||||||
|
|
||||||
|
owner1.UseBall( owner2.ShareMyBall() );
|
||||||
|
owner2.UseBall( owner3.ShareMyBall() );
|
||||||
|
owner3.UseBall( owner1.ShareMyBall() );
|
||||||
|
assert( owner1.DoesUseBall() );
|
||||||
|
assert( owner2.DoesUseBall() );
|
||||||
|
assert( owner3.DoesUseBall() );
|
||||||
|
|
||||||
|
assert( !owner1.ShareOtherBall().IsStrong() );
|
||||||
|
assert( !owner2.ShareOtherBall().IsStrong() );
|
||||||
|
assert( !owner3.ShareOtherBall().IsStrong() );
|
||||||
|
|
||||||
|
assert( owner1.ShareOtherBall() == pBall2 );
|
||||||
|
assert( owner2.ShareOtherBall() == pBall3 );
|
||||||
|
assert( owner3.ShareOtherBall() == pBall1 );
|
||||||
|
assert( owner1.ShareMyBall() == pBall1 );
|
||||||
|
assert( owner2.ShareMyBall() == pBall2 );
|
||||||
|
assert( owner3.ShareMyBall() == pBall3 );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert( owner2.ShareMyBall() == pBall2 );
|
||||||
|
// Can owner1 own a ball that is owned by somebody else?
|
||||||
|
owner1.OwnBall( pBall2 );
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
catch ( const ::std::logic_error & ex )
|
||||||
|
{
|
||||||
|
assert( true );
|
||||||
|
assert( ::strcmp( ex.what(), ::Loki::StrongPtr_Single_Owner_Exception_Message ) == 0 );
|
||||||
|
(void)ex;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert( owner3.ShareMyBall() == pBall3 );
|
||||||
|
// Can owner2 own a ball that is owned by somebody else?
|
||||||
|
owner2.OwnBall( pBall3 );
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
catch ( const ::std::logic_error & ex )
|
||||||
|
{
|
||||||
|
assert( true );
|
||||||
|
assert( ::strcmp( ex.what(), ::Loki::StrongPtr_Single_Owner_Exception_Message ) == 0 );
|
||||||
|
(void)ex;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert( owner1.ShareMyBall() == pBall1 );
|
||||||
|
// Can owner3 own a ball that is owned by somebody else?
|
||||||
|
owner3.OwnBall( pBall1 );
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
catch ( const ::std::logic_error & ex )
|
||||||
|
{
|
||||||
|
assert( true );
|
||||||
|
assert( ::strcmp( ex.what(), ::Loki::StrongPtr_Single_Owner_Exception_Message ) == 0 );
|
||||||
|
(void)ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These tests occur after exceptions were thrown. Since these tests pass,
|
||||||
|
// that means the pointers are still in a valid state. Also, the pointers
|
||||||
|
// are untouched by the temporary StrongPtr's that were made inside the
|
||||||
|
// assignment operators, so therefore the pointers have strong exception
|
||||||
|
// safety.
|
||||||
|
owner1.ClearBall();
|
||||||
|
owner2.ClearBall();
|
||||||
|
owner3.ClearBall();
|
||||||
|
assert( !owner1.DoesOwnBall() );
|
||||||
|
assert( !owner2.DoesOwnBall() );
|
||||||
|
assert( !owner3.DoesOwnBall() );
|
||||||
|
assert( nullptr == pBall1 );
|
||||||
|
assert( nullptr == pBall2 );
|
||||||
|
assert( nullptr == pBall3 );
|
||||||
|
assert( owner1.ShareMyBall() == pBall1 );
|
||||||
|
assert( owner2.ShareMyBall() == pBall2 );
|
||||||
|
assert( owner3.ShareMyBall() == pBall3 );
|
||||||
|
assert( owner1.ShareMyBall() == nullptr );
|
||||||
|
assert( owner2.ShareMyBall() == nullptr );
|
||||||
|
assert( owner3.ShareMyBall() == nullptr );
|
||||||
|
|
||||||
|
{
|
||||||
|
Ball * baseball = new Ball;
|
||||||
|
Ball * football = new Ball;
|
||||||
|
Ball * softball = new Ball;
|
||||||
|
|
||||||
|
NonOwnerPtr p1( baseball );
|
||||||
|
NonOwnerPtr p2( football );
|
||||||
|
NonOwnerPtr p3( softball );
|
||||||
|
assert( nullptr != p1 );
|
||||||
|
assert( nullptr != p2 );
|
||||||
|
assert( nullptr != p3 );
|
||||||
|
|
||||||
|
assert( !p1.IsStrong() );
|
||||||
|
assert( !p2.IsStrong() );
|
||||||
|
assert( !p3.IsStrong() );
|
||||||
|
|
||||||
|
{
|
||||||
|
Owner o1;
|
||||||
|
Owner o2;
|
||||||
|
Owner o3;
|
||||||
|
|
||||||
|
assert( !o1.DoesOwnBall() );
|
||||||
|
assert( !o2.DoesOwnBall() );
|
||||||
|
assert( !o3.DoesOwnBall() );
|
||||||
|
assert( !o1.DoesUseBall() );
|
||||||
|
assert( !o2.DoesUseBall() );
|
||||||
|
assert( !o3.DoesUseBall() );
|
||||||
|
|
||||||
|
o1.OwnBall( p1 );
|
||||||
|
o2.OwnBall( p2 );
|
||||||
|
o3.OwnBall( p3 );
|
||||||
|
|
||||||
|
assert( o1.DoesOwnBall() );
|
||||||
|
assert( o2.DoesOwnBall() );
|
||||||
|
assert( o3.DoesOwnBall() );
|
||||||
|
assert( !o1.DoesUseBall() );
|
||||||
|
assert( !o2.DoesUseBall() );
|
||||||
|
assert( !o3.DoesUseBall() );
|
||||||
|
|
||||||
|
assert( o1.ShareMyBall() == p1 );
|
||||||
|
assert( o2.ShareMyBall() == p2 );
|
||||||
|
assert( o3.ShareMyBall() == p3 );
|
||||||
|
|
||||||
|
o1.ClearBall();
|
||||||
|
o2.ClearBall();
|
||||||
|
o3.ClearBall();
|
||||||
|
assert( !o1.DoesOwnBall() );
|
||||||
|
assert( !o2.DoesOwnBall() );
|
||||||
|
assert( !o3.DoesOwnBall() );
|
||||||
|
assert( o1.ShareMyBall() == nullptr );
|
||||||
|
assert( o2.ShareMyBall() == nullptr );
|
||||||
|
assert( o3.ShareMyBall() == nullptr );
|
||||||
|
assert( nullptr == p1 );
|
||||||
|
assert( nullptr == p2 );
|
||||||
|
assert( nullptr == p3 );
|
||||||
|
assert( o1.ShareMyBall() == p1 );
|
||||||
|
assert( o2.ShareMyBall() == p2 );
|
||||||
|
assert( o3.ShareMyBall() == p3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
assert( nullptr == p1 );
|
||||||
|
assert( nullptr == p2 );
|
||||||
|
assert( nullptr == p3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
OwnerPtr op_1;
|
||||||
|
OwnerPtr op_2;
|
||||||
|
(void)op_1;
|
||||||
|
(void)op_2;
|
||||||
|
op_1 = op_2;
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
|
||||||
|
// Test ResetAll with owner pointer.
|
||||||
|
{
|
||||||
|
Ball * ball = new Ball;
|
||||||
|
Ball * noBall = nullptr;
|
||||||
|
OwnerPtr op_1( ball );
|
||||||
|
NonOwnerPtr np1( op_1 );
|
||||||
|
NonOwnerPtr np2( np1 );
|
||||||
|
assert( ball == op_1 );
|
||||||
|
assert( ball == np1 );
|
||||||
|
assert( ball == np2 );
|
||||||
|
|
||||||
|
ResetAll( op_1, noBall );
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
assert( nullptr == op_1 );
|
||||||
|
assert( nullptr == np1 );
|
||||||
|
assert( nullptr == np2 );
|
||||||
|
assert( nullptr == noBall );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test ReleaseAll with owner pointer.
|
||||||
|
{
|
||||||
|
Ball * ball = new Ball;
|
||||||
|
Ball * noBall = nullptr;
|
||||||
|
OwnerPtr op_1( ball );
|
||||||
|
NonOwnerPtr np1( op_1 );
|
||||||
|
NonOwnerPtr np2( np1 );
|
||||||
|
assert( ball == op_1 );
|
||||||
|
assert( ball == np1 );
|
||||||
|
assert( ball == np2 );
|
||||||
|
|
||||||
|
ReleaseAll( op_1, noBall );
|
||||||
|
assert( !Ball::AllDestroyed() );
|
||||||
|
assert( nullptr != noBall );
|
||||||
|
assert( noBall == ball );
|
||||||
|
assert( nullptr == op_1 );
|
||||||
|
assert( nullptr == np1 );
|
||||||
|
assert( nullptr == np2 );
|
||||||
|
delete noBall;
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test ResetAll with nonowner pointer.
|
||||||
|
{
|
||||||
|
Ball * ball = new Ball;
|
||||||
|
Ball * noBall = nullptr;
|
||||||
|
OwnerPtr op_1( ball );
|
||||||
|
NonOwnerPtr np1( op_1 );
|
||||||
|
NonOwnerPtr np2( np1 );
|
||||||
|
assert( ball == op_1 );
|
||||||
|
assert( ball == np1 );
|
||||||
|
assert( ball == np2 );
|
||||||
|
|
||||||
|
ResetAll( np1, noBall );
|
||||||
|
// ResetAll fails for non-owner pointers.
|
||||||
|
assert( !Ball::AllDestroyed() );
|
||||||
|
assert( nullptr != op_1 );
|
||||||
|
assert( nullptr != np1 );
|
||||||
|
assert( nullptr != np2 );
|
||||||
|
assert( nullptr == noBall );
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
|
||||||
|
// Test ReleaseAll with nonowner pointer.
|
||||||
|
{
|
||||||
|
Ball * ball = new Ball;
|
||||||
|
Ball * noBall = nullptr;
|
||||||
|
OwnerPtr op_1( ball );
|
||||||
|
NonOwnerPtr np1( op_1 );
|
||||||
|
NonOwnerPtr np2( np1 );
|
||||||
|
assert( ball == op_1 );
|
||||||
|
assert( ball == np1 );
|
||||||
|
assert( ball == np2 );
|
||||||
|
|
||||||
|
ReleaseAll( np1, noBall );
|
||||||
|
// ReleaseAll fails for non-owner pointers.
|
||||||
|
assert( !Ball::AllDestroyed() );
|
||||||
|
assert( nullptr != op_1 );
|
||||||
|
assert( nullptr != np1 );
|
||||||
|
assert( nullptr != np2 );
|
||||||
|
assert( nullptr == noBall );
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
|
||||||
|
// Test assignment operator.
|
||||||
|
{
|
||||||
|
OwnerPtr op2;
|
||||||
|
Ball * ball1 = new Ball;
|
||||||
|
Ball * ball2 = new Ball;
|
||||||
|
op1 = ball1;
|
||||||
|
op2 = ball2;
|
||||||
|
assert( ball1 == op1 );
|
||||||
|
assert( ball2 == op2 );
|
||||||
|
op1 = nullptr;
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
|
||||||
|
// Test the Swap function for strong co-pointers.
|
||||||
|
{
|
||||||
|
NonOwnerPtr np1;
|
||||||
|
NonOwnerPtr np2;
|
||||||
|
Ball * ball1 = new Ball;
|
||||||
|
Ball * ball2 = new Ball;
|
||||||
|
np1 = ball1;
|
||||||
|
np2 = ball2;
|
||||||
|
assert( ball1 == np1 );
|
||||||
|
assert( ball2 == np2 );
|
||||||
|
assert( nullptr != np1 );
|
||||||
|
assert( nullptr != np2 );
|
||||||
|
|
||||||
|
op1 = np1;
|
||||||
|
OwnerPtr op2( np2 );
|
||||||
|
assert( np1 == op1 );
|
||||||
|
assert( np2 == op2 );
|
||||||
|
assert( np2 != op1 );
|
||||||
|
assert( np1 != op2 );
|
||||||
|
|
||||||
|
op1.Swap( op2 );
|
||||||
|
|
||||||
|
assert( ball1 != op1 ); // Owners do not point to original objects.
|
||||||
|
assert( ball2 != op2 );
|
||||||
|
assert( ball2 == op1 ); // Owners now point to different objects.
|
||||||
|
assert( ball1 == op2 );
|
||||||
|
assert( ball1 != np2 ); // Non-owners still point to original objects.
|
||||||
|
assert( ball2 != np1 );
|
||||||
|
assert( ball2 == np2 ); // Non-owners do not point to different objects.
|
||||||
|
assert( ball1 == np1 );
|
||||||
|
assert( np1 != op1 );
|
||||||
|
assert( np2 != op2 );
|
||||||
|
assert( np2 == op1 );
|
||||||
|
assert( np1 == op2 );
|
||||||
|
assert( nullptr != op1 );
|
||||||
|
assert( nullptr != op2 );
|
||||||
|
assert( nullptr != np1 );
|
||||||
|
assert( nullptr != np2 );
|
||||||
|
op1 = nullptr;
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
|
||||||
|
// Test the Swap function for weak co-pointers.
|
||||||
|
{
|
||||||
|
NonOwnerPtr np1;
|
||||||
|
NonOwnerPtr np2;
|
||||||
|
Ball * ball1 = new Ball;
|
||||||
|
Ball * ball2 = new Ball;
|
||||||
|
np1 = ball1;
|
||||||
|
np2 = ball2;
|
||||||
|
assert( ball1 == np1 );
|
||||||
|
assert( ball2 == np2 );
|
||||||
|
assert( nullptr != np1 );
|
||||||
|
assert( nullptr != np2 );
|
||||||
|
|
||||||
|
op1 = np1;
|
||||||
|
OwnerPtr op2( np2 );
|
||||||
|
assert( np1 == op1 );
|
||||||
|
assert( np2 == op2 );
|
||||||
|
assert( np2 != op1 );
|
||||||
|
assert( np1 != op2 );
|
||||||
|
|
||||||
|
np1.Swap( np2 );
|
||||||
|
|
||||||
|
assert( ball1 == op1 ); // Owners still point to their original objects.
|
||||||
|
assert( ball2 == op2 );
|
||||||
|
assert( ball2 != op1 ); // Owners do not point to different objects.
|
||||||
|
assert( ball1 != op2 );
|
||||||
|
assert( ball1 == np2 ); // Non-owners now point to different objects.
|
||||||
|
assert( ball2 == np1 );
|
||||||
|
assert( ball2 != np2 ); // Non-owners do not point to their original objects.
|
||||||
|
assert( ball1 != np1 );
|
||||||
|
assert( np1 != op1 );
|
||||||
|
assert( np2 != op2 );
|
||||||
|
assert( np2 == op1 );
|
||||||
|
assert( np1 == op2 );
|
||||||
|
assert( nullptr != op1 );
|
||||||
|
assert( nullptr != op2 );
|
||||||
|
assert( nullptr != np1 );
|
||||||
|
assert( nullptr != np2 );
|
||||||
|
op1 = nullptr;
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
|
||||||
|
// A Swap of a weak pointer with a strong pointer will cause a compiler error.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DoSingleOwnerTests( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
// These tests exercise the lockable single-owner StrongPtr policies.
|
||||||
|
{
|
||||||
|
Ball * baseball = new Ball;
|
||||||
|
Ball * football = new Ball;
|
||||||
|
Ball * softball = new Ball;
|
||||||
|
Lockable_Owner_Counted_BallPtr op1;
|
||||||
|
Lockable_NonOwner_Counted_BallPtr pBaseball( baseball );
|
||||||
|
Lockable_NonOwner_Counted_BallPtr pFootball( football );
|
||||||
|
Lockable_NonOwner_Counted_BallPtr pSoftball( softball );
|
||||||
|
Teenager teen1;
|
||||||
|
Teenager teen2;
|
||||||
|
Teenager teen3;
|
||||||
|
DoSingleOwnerTest( op1, pBaseball, pFootball, pSoftball,
|
||||||
|
teen1, teen2, teen3 );
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
|
||||||
|
// These tests exercise the reference-counted single-owner StrongPtr policies.
|
||||||
|
{
|
||||||
|
Ball * soccerBall = new Ball;
|
||||||
|
Ball * bouncyBall = new Ball;
|
||||||
|
Ball * basketBall = new Ball;
|
||||||
|
|
||||||
|
NonOwner_Counted_BallPtr pSoccerBall( soccerBall );
|
||||||
|
NonOwner_Counted_BallPtr pBouncyBall( bouncyBall );
|
||||||
|
NonOwner_Counted_BallPtr pBasketBall( basketBall );
|
||||||
|
Toddler child1;
|
||||||
|
Toddler child2;
|
||||||
|
Toddler child3;
|
||||||
|
Owner_Counted_BallPtr op1;
|
||||||
|
DoSingleOwnerTest( op1, pSoccerBall, pBouncyBall, pBasketBall,
|
||||||
|
child1, child2, child3 );
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
|
||||||
|
// These tests exercise the linked-cycle single-owner StrongPtr policies.
|
||||||
|
{
|
||||||
|
Ball * yarnBall = new Ball;
|
||||||
|
Ball * twineBall = new Ball;
|
||||||
|
Ball * stringBall = new Ball;
|
||||||
|
|
||||||
|
NonOwner_Linked_BallPtr pYarnBall( yarnBall );
|
||||||
|
NonOwner_Linked_BallPtr pTwineBall( twineBall );
|
||||||
|
NonOwner_Linked_BallPtr pStringBall( stringBall );
|
||||||
|
Kitten cat1;
|
||||||
|
Kitten cat2;
|
||||||
|
Kitten cat3;
|
||||||
|
Owner_Linked_BallPtr op1;
|
||||||
|
DoSingleOwnerTest( op1, pYarnBall, pTwineBall, pStringBall,
|
||||||
|
cat1, cat2, cat3 );
|
||||||
|
}
|
||||||
|
assert( Ball::AllDestroyed() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void DoStrongForwardReferenceTest( void )
|
void DoStrongForwardReferenceTest( void )
|
||||||
{
|
{
|
||||||
/** @note These lines should cause the compiler to make a warning message
|
/** @note These lines should cause the compiler to make a warning message
|
||||||
|
@ -1497,6 +2089,3 @@ void foo()
|
||||||
// this will not compile:
|
// this will not compile:
|
||||||
//int i = f1.i;
|
//int i = f1.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue