Fixed bugs 1452805 and 1451835. Added Merge ability for RefLink policy.
Added more tests for SmartPtr. git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@610 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
aab36b5ebb
commit
47730a3073
3 changed files with 648 additions and 87 deletions
|
@ -39,7 +39,10 @@
|
|||
#include <functional>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include <stdint.h>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
namespace Loki
|
||||
{
|
||||
|
@ -94,8 +97,10 @@ namespace Loki
|
|||
// Destroys the data stored
|
||||
// (Destruction might be taken over by the OwnershipPolicy)
|
||||
void Destroy()
|
||||
{ delete pointee_; }
|
||||
|
||||
{
|
||||
delete pointee_;
|
||||
}
|
||||
|
||||
// Default value to initialize the pointer
|
||||
static StoredType Default()
|
||||
{ return 0; }
|
||||
|
@ -387,9 +392,16 @@ namespace Loki
|
|||
|
||||
void Swap(RefLinkedBase& rhs);
|
||||
|
||||
bool Merge( RefLinkedBase & rhs );
|
||||
|
||||
enum { destructiveCopy = false };
|
||||
|
||||
private:
|
||||
static unsigned int CountPrevCycle( const RefLinkedBase * pThis );
|
||||
static unsigned int CountNextCycle( const RefLinkedBase * pThis );
|
||||
bool HasPrevNode( const RefLinkedBase * p ) const;
|
||||
bool HasNextNode( const RefLinkedBase * p ) const;
|
||||
|
||||
mutable const RefLinkedBase* prev_;
|
||||
mutable const RefLinkedBase* next_;
|
||||
};
|
||||
|
@ -412,6 +424,12 @@ namespace Loki
|
|||
|
||||
bool Release(const P&)
|
||||
{ return Private::RefLinkedBase::Release(); }
|
||||
|
||||
template < class P1 >
|
||||
bool Merge( RefLinked< P1 > & rhs )
|
||||
{
|
||||
return Private::RefLinkedBase::Merge( rhs );
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -984,6 +1002,24 @@ namespace Loki
|
|||
friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
|
||||
{ SmartPtr(p).Swap(sp); }
|
||||
|
||||
template
|
||||
<
|
||||
typename T1,
|
||||
template <class> class OP1,
|
||||
class CP1,
|
||||
template <class> class KP1,
|
||||
template <class> class SP1,
|
||||
template <class> class CNP1
|
||||
>
|
||||
bool Merge( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
|
||||
{
|
||||
if ( GetImpl( *this ) != GetImpl( rhs ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return OP::Merge( rhs );
|
||||
}
|
||||
|
||||
PointerType operator->()
|
||||
{
|
||||
KP::OnDereference(GetImplRef(*this));
|
||||
|
@ -1010,7 +1046,9 @@ namespace Loki
|
|||
|
||||
bool operator!() const // Enables "if (!sp) ..."
|
||||
{ return GetImpl(*this) == 0; }
|
||||
|
||||
|
||||
static inline T * GetPointer( const SmartPtr & sp )
|
||||
{ return GetImpl( sp ); }
|
||||
|
||||
// Ambiguity buster
|
||||
template
|
||||
|
@ -1051,6 +1089,51 @@ namespace Loki
|
|||
bool operator<(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
|
||||
{ return GetImpl(*this) < GetImpl(rhs); }
|
||||
|
||||
// Ambiguity buster
|
||||
template
|
||||
<
|
||||
typename T1,
|
||||
template <class> class OP1,
|
||||
class CP1,
|
||||
template <class> class KP1,
|
||||
template <class> class SP1,
|
||||
template <class> class CNP1
|
||||
>
|
||||
inline bool operator > ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
|
||||
{
|
||||
return ( GetImpl( rhs ) < GetImpl( *this ) );
|
||||
}
|
||||
|
||||
// Ambiguity buster
|
||||
template
|
||||
<
|
||||
typename T1,
|
||||
template <class> class OP1,
|
||||
class CP1,
|
||||
template <class> class KP1,
|
||||
template <class> class SP1,
|
||||
template <class> class CNP1
|
||||
>
|
||||
inline bool operator <= ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
|
||||
{
|
||||
return !( GetImpl( rhs ) < GetImpl( *this ) );
|
||||
}
|
||||
|
||||
// Ambiguity buster
|
||||
template
|
||||
<
|
||||
typename T1,
|
||||
template <class> class OP1,
|
||||
class CP1,
|
||||
template <class> class KP1,
|
||||
template <class> class SP1,
|
||||
template <class> class CNP1
|
||||
>
|
||||
inline bool operator >= ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
|
||||
{
|
||||
return !( GetImpl( *this ) < GetImpl( rhs ) );
|
||||
}
|
||||
|
||||
private:
|
||||
// Helper for enabling 'if (sp)'
|
||||
struct Tester
|
||||
|
@ -1108,7 +1191,7 @@ namespace Loki
|
|||
inline bool operator==(const SmartPtr<T, OP, CP, KP, SP, CNP1 >& lhs,
|
||||
U* rhs)
|
||||
{ return GetImpl(lhs) == rhs; }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// operator== for lhs = raw pointer, rhs = SmartPtr
|
||||
/// \ingroup SmartPointerGroup
|
||||
|
@ -1167,7 +1250,7 @@ namespace Loki
|
|||
{ return rhs != lhs; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// operator< for lhs = SmartPtr, rhs = raw pointer -- NOT DEFINED
|
||||
/// operator< for lhs = SmartPtr, rhs = raw pointer
|
||||
/// \ingroup SmartPointerGroup
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1182,10 +1265,13 @@ namespace Loki
|
|||
typename U
|
||||
>
|
||||
inline bool operator<(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
|
||||
U* rhs);
|
||||
|
||||
U* rhs)
|
||||
{
|
||||
return ( GetImpl( lhs ) < rhs );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// operator< for lhs = raw pointer, rhs = SmartPtr -- NOT DEFINED
|
||||
/// operator< for lhs = raw pointer, rhs = SmartPtr
|
||||
/// \ingroup SmartPointerGroup
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1200,10 +1286,13 @@ namespace Loki
|
|||
typename U
|
||||
>
|
||||
inline bool operator<(U* lhs,
|
||||
const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs);
|
||||
|
||||
const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
|
||||
{
|
||||
return ( GetImpl( rhs ) < lhs );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// operator> for lhs = SmartPtr, rhs = raw pointer -- NOT DEFINED
|
||||
// operator> for lhs = SmartPtr, rhs = raw pointer
|
||||
/// \ingroup SmartPointerGroup
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1363,6 +1452,10 @@ namespace std
|
|||
#endif // SMARTPTR_INC_
|
||||
|
||||
// $Log$
|
||||
// Revision 1.26 2006/03/17 22:52:55 rich_sposato
|
||||
// Fixed bugs 1452805 and 1451835. Added Merge ability for RefLink policy.
|
||||
// Added more tests for SmartPtr.
|
||||
//
|
||||
// Revision 1.25 2006/03/17 20:22:14 syntheticpp
|
||||
// patch undefined uintptr_t, thx to Regis Desgroppes
|
||||
//
|
||||
|
|
191
src/SmartPtr.cpp
191
src/SmartPtr.cpp
|
@ -20,6 +20,11 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
//#define DO_EXTRA_LOKI_TESTS
|
||||
#ifdef DO_EXTRA_LOKI_TESTS
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -37,12 +42,25 @@ RefLinkedBase::RefLinkedBase(const RefLinkedBase& rhs)
|
|||
next_ = rhs.next_;
|
||||
prev_->next_ = this;
|
||||
next_->prev_ = this;
|
||||
|
||||
#ifdef DO_EXTRA_LOKI_TESTS
|
||||
assert( prev_->HasPrevNode( this ) );
|
||||
assert( next_->HasNextNode( this ) );
|
||||
assert( CountPrevCycle( this ) == CountNextCycle( this ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool RefLinkedBase::Release()
|
||||
{
|
||||
|
||||
#ifdef DO_EXTRA_LOKI_TESTS
|
||||
assert( prev_->HasPrevNode( this ) );
|
||||
assert( next_->HasNextNode( this ) );
|
||||
assert( CountPrevCycle( this ) == CountNextCycle( this ) );
|
||||
#endif
|
||||
|
||||
if ( NULL == next_ )
|
||||
{
|
||||
assert( NULL == prev_ );
|
||||
|
@ -58,10 +76,24 @@ bool RefLinkedBase::Release()
|
|||
next_ = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DO_EXTRA_LOKI_TESTS
|
||||
assert( this != prev_ );
|
||||
assert( NULL != prev_ );
|
||||
assert( prev_->HasPrevNode( this ) );
|
||||
assert( next_->HasNextNode( this ) );
|
||||
#endif
|
||||
|
||||
prev_->next_ = next_;
|
||||
next_->prev_ = prev_;
|
||||
|
||||
#ifdef DO_EXTRA_LOKI_TESTS
|
||||
next_ = this;
|
||||
prev_ = this;
|
||||
assert( 1 == CountNextCycle( this ) );
|
||||
assert( 1 == CountPrevCycle( this ) );
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -69,6 +101,13 @@ bool RefLinkedBase::Release()
|
|||
|
||||
void RefLinkedBase::Swap(RefLinkedBase& rhs)
|
||||
{
|
||||
|
||||
#ifdef DO_EXTRA_LOKI_TESTS
|
||||
assert( prev_->HasPrevNode( this ) );
|
||||
assert( next_->HasNextNode( this ) );
|
||||
assert( CountPrevCycle( this ) == CountNextCycle( this ) );
|
||||
#endif
|
||||
|
||||
if (next_ == this)
|
||||
{
|
||||
assert(prev_ == this);
|
||||
|
@ -115,7 +154,155 @@ void RefLinkedBase::Swap(RefLinkedBase& rhs)
|
|||
std::swap(next_->prev_, rhs.next_->prev_);
|
||||
}
|
||||
|
||||
#ifdef DO_EXTRA_LOKI_TESTS
|
||||
assert( next_ == this ? prev_ == this : prev_ != this);
|
||||
assert( prev_ == this ? next_ == this : next_ != this);
|
||||
assert( prev_->HasPrevNode( this ) );
|
||||
assert( next_->HasNextNode( this ) );
|
||||
assert( CountPrevCycle( this ) == CountNextCycle( this ) );
|
||||
assert( rhs.prev_->HasPrevNode( &rhs ) );
|
||||
assert( rhs.next_->HasNextNode( &rhs ) );
|
||||
assert( CountPrevCycle( &rhs ) == CountNextCycle( &rhs ) );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
unsigned int RefLinkedBase::CountPrevCycle( const RefLinkedBase * pThis )
|
||||
{
|
||||
if ( NULL == pThis )
|
||||
return 0;
|
||||
const RefLinkedBase * p = pThis->prev_;
|
||||
if ( NULL == p )
|
||||
return 0;
|
||||
if ( pThis == p )
|
||||
return 1;
|
||||
|
||||
unsigned int count = 1;
|
||||
do
|
||||
{
|
||||
p = p->prev_;
|
||||
++count;
|
||||
} while ( p != pThis );
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
unsigned int RefLinkedBase::CountNextCycle( const RefLinkedBase * pThis )
|
||||
{
|
||||
if ( NULL == pThis )
|
||||
return 0;
|
||||
const RefLinkedBase * p = pThis->next_;
|
||||
if ( NULL == p )
|
||||
return 0;
|
||||
if ( pThis == p )
|
||||
return 1;
|
||||
|
||||
unsigned int count = 1;
|
||||
while ( p != pThis )
|
||||
{
|
||||
p = p->next_;
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool RefLinkedBase::HasPrevNode( const RefLinkedBase * p ) const
|
||||
{
|
||||
if ( this == p )
|
||||
return true;
|
||||
const RefLinkedBase * prev = prev_;
|
||||
if ( NULL == prev )
|
||||
return false;
|
||||
while ( prev != this )
|
||||
{
|
||||
if ( p == prev )
|
||||
return true;
|
||||
prev = prev->prev_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool RefLinkedBase::HasNextNode( const RefLinkedBase * p ) const
|
||||
{
|
||||
if ( this == p )
|
||||
return true;
|
||||
const RefLinkedBase * next = next_;
|
||||
if ( NULL == next )
|
||||
return false;
|
||||
while ( next != this )
|
||||
{
|
||||
if ( p == next )
|
||||
return true;
|
||||
next = next->next_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool RefLinkedBase::Merge( RefLinkedBase & rhs )
|
||||
{
|
||||
|
||||
if ( NULL == next_ )
|
||||
{
|
||||
assert( NULL == prev_ );
|
||||
return false;
|
||||
}
|
||||
RefLinkedBase * prhs = &rhs;
|
||||
if ( prhs == this )
|
||||
return true;
|
||||
if ( NULL == prhs->next_ )
|
||||
{
|
||||
assert( NULL == prhs->prev_ );
|
||||
return true;
|
||||
}
|
||||
|
||||
assert( CountPrevCycle( this ) == CountNextCycle( this ) );
|
||||
assert( CountPrevCycle( prhs ) == CountNextCycle( prhs ) );
|
||||
// If rhs node is already in this cycle, then no need to merge.
|
||||
if ( HasPrevNode( &rhs ) )
|
||||
{
|
||||
assert( HasNextNode( &rhs ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( prhs == prhs->next_ )
|
||||
{
|
||||
/// rhs is in a cycle with 1 node.
|
||||
assert( prhs->prev_ == prhs );
|
||||
prhs->prev_ = prev_;
|
||||
prhs->next_ = this;
|
||||
prev_->next_ = prhs;
|
||||
prev_ = prhs;
|
||||
}
|
||||
else if ( this == next_ )
|
||||
{
|
||||
/// this is in a cycle with 1 node.
|
||||
assert( prev_ == this );
|
||||
prev_ = prhs->prev_;
|
||||
next_ = prhs;
|
||||
prhs->prev_->next_ = this;
|
||||
prhs->prev_ = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
next_->prev_ = prhs->prev_;
|
||||
prhs->prev_->next_ = prev_;
|
||||
next_ = prhs;
|
||||
prhs->prev_ = this;
|
||||
}
|
||||
|
||||
assert( CountPrevCycle( this ) == CountNextCycle( this ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -127,6 +314,10 @@ void RefLinkedBase::Swap(RefLinkedBase& rhs)
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
// $Log$
|
||||
// Revision 1.4 2006/03/17 22:52:56 rich_sposato
|
||||
// Fixed bugs 1452805 and 1451835. Added Merge ability for RefLink policy.
|
||||
// Added more tests for SmartPtr.
|
||||
//
|
||||
// Revision 1.3 2006/03/01 02:08:10 rich_sposato
|
||||
// Fixed bug 1440694 by adding check if rhs is previous neighbor.
|
||||
//
|
||||
|
|
|
@ -18,91 +18,20 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "Base.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using namespace std;
|
||||
using namespace Loki;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class BaseClass
|
||||
{
|
||||
public:
|
||||
BaseClass( void )
|
||||
{
|
||||
s_constructions++;
|
||||
}
|
||||
|
||||
virtual ~BaseClass( void )
|
||||
{
|
||||
s_destructions++;
|
||||
}
|
||||
|
||||
// These 2 functions are so we can pretend we have a COM object.
|
||||
void AddRef( void ) {}
|
||||
void Release( void ) {}
|
||||
|
||||
// This function is used only for the DeepCopy policy.
|
||||
virtual BaseClass * Clone( void ) const
|
||||
{
|
||||
return new BaseClass();
|
||||
}
|
||||
|
||||
static bool AllDestroyed( void )
|
||||
{
|
||||
return ( s_constructions == s_destructions );
|
||||
}
|
||||
|
||||
static bool ExtraConstructions( void )
|
||||
{
|
||||
return ( s_constructions > s_destructions );
|
||||
}
|
||||
|
||||
static bool ExtraDestructions( void )
|
||||
{
|
||||
return ( s_constructions < s_destructions );
|
||||
}
|
||||
|
||||
private:
|
||||
/// Not implemented.
|
||||
BaseClass( const BaseClass & );
|
||||
/// Not implemented.
|
||||
BaseClass & operator = ( const BaseClass & );
|
||||
|
||||
static unsigned int s_constructions;
|
||||
static unsigned int s_destructions;
|
||||
};
|
||||
extern void DoStrongRefCountTests( void );
|
||||
extern void DoStrongRefLinkTests( void );
|
||||
|
||||
unsigned int BaseClass::s_constructions = 0;
|
||||
unsigned int BaseClass::s_destructions = 0;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class PublicSubClass : public BaseClass
|
||||
{
|
||||
public:
|
||||
// This function is used only for the DeepCopy policy.
|
||||
virtual BaseClass * Clone( void ) const
|
||||
{
|
||||
return new BaseClass();
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class PrivateSubClass : private BaseClass
|
||||
{
|
||||
public:
|
||||
// This function is used only for the DeepCopy policy.
|
||||
virtual BaseClass * Clone( void ) const
|
||||
{
|
||||
return new BaseClass();
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// @note Used for testing most policies.
|
||||
|
@ -370,7 +299,9 @@ void DoRefCountSwapTests( void )
|
|||
|
||||
void DoRefLinkSwapTests( void )
|
||||
{
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p1( new BaseClass );
|
||||
|
||||
BaseClass * pBaseClass = new BaseClass;
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p1( pBaseClass );
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p2( new BaseClass );
|
||||
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p3( p1 );
|
||||
|
@ -431,6 +362,8 @@ void DoRefLinkSwapTests( void )
|
|||
assert( p5 == p5 );
|
||||
|
||||
p1.Swap( p2 ); // p2 <---> p3 and p1 <---> p4 and p5 and p6
|
||||
assert( p1 != pBaseClass );
|
||||
assert( p2 == pBaseClass );
|
||||
assert( p1 == p4 );
|
||||
assert( p1 != p2 );
|
||||
assert( p1 != p3 );
|
||||
|
@ -631,6 +564,340 @@ void DoRefLinkSwapTests( void )
|
|||
assert( p4 == p4 );
|
||||
assert( p5 == p5 );
|
||||
assert( p6 == p6 );
|
||||
|
||||
bool merged = false;
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p7( pBaseClass );
|
||||
assert( p7 == p7 );
|
||||
assert( p6 == p7 );
|
||||
assert( p1 != p7 );
|
||||
merged = p7.Merge( p6 );
|
||||
// p7 <---> p6 <---> p3 <---> p5 <---> p2 and p4 <---> p1
|
||||
assert( merged );
|
||||
assert( p6 == p7 );
|
||||
assert( p1 != p7 );
|
||||
assert( p6 == p5 );
|
||||
assert( p6 == p2 );
|
||||
assert( p6 == p3 );
|
||||
assert( p5 == p3 );
|
||||
assert( p2 == p3 );
|
||||
assert( p1 == p4 );
|
||||
assert( p2 != p4 );
|
||||
assert( p1 != p5 );
|
||||
assert( p2 != p1 );
|
||||
assert( p3 != p1 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p3 == p3 );
|
||||
assert( p4 == p4 );
|
||||
assert( p5 == p5 );
|
||||
assert( p6 == p6 );
|
||||
assert( p7 == p7 );
|
||||
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p8( pBaseClass );
|
||||
assert( p6 == p8 );
|
||||
assert( p1 != p8 );
|
||||
merged = p6.Merge( p8 );
|
||||
// p7 <---> p6 <---> p8 <---> p3 <---> p5 <---> p2 and p4 <---> p1
|
||||
assert( merged );
|
||||
assert( p6 == p8 );
|
||||
assert( p6 == p7 );
|
||||
assert( p1 != p7 );
|
||||
assert( p6 == p5 );
|
||||
assert( p6 == p2 );
|
||||
assert( p6 == p3 );
|
||||
assert( p5 == p3 );
|
||||
assert( p2 == p3 );
|
||||
assert( p1 == p4 );
|
||||
assert( p2 != p4 );
|
||||
assert( p1 != p5 );
|
||||
assert( p2 != p1 );
|
||||
assert( p3 != p1 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p3 == p3 );
|
||||
assert( p4 == p4 );
|
||||
assert( p5 == p5 );
|
||||
assert( p6 == p6 );
|
||||
assert( p7 == p7 );
|
||||
assert( p8 == p8 );
|
||||
|
||||
merged = p6.Merge( p6 );
|
||||
// p7 <---> p6 <---> p8 <---> p3 <---> p5 <---> p2 and p4 <---> p1
|
||||
assert( merged );
|
||||
assert( p6 == p8 );
|
||||
assert( p6 == p7 );
|
||||
assert( p1 != p7 );
|
||||
assert( p6 == p5 );
|
||||
assert( p6 == p2 );
|
||||
assert( p6 == p3 );
|
||||
assert( p5 == p3 );
|
||||
assert( p2 == p3 );
|
||||
assert( p1 == p4 );
|
||||
assert( p2 != p4 );
|
||||
assert( p1 != p5 );
|
||||
assert( p2 != p1 );
|
||||
assert( p3 != p1 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p3 == p3 );
|
||||
assert( p4 == p4 );
|
||||
assert( p5 == p5 );
|
||||
assert( p6 == p6 );
|
||||
assert( p7 == p7 );
|
||||
assert( p8 == p8 );
|
||||
|
||||
merged = p6.Merge( p3 );
|
||||
// p7 <---> p6 <---> p8 <---> p3 <---> p5 <---> p2 and p4 <---> p1
|
||||
assert( merged );
|
||||
assert( p6 == p8 );
|
||||
assert( p6 == p7 );
|
||||
assert( p1 != p7 );
|
||||
assert( p6 == p5 );
|
||||
assert( p6 == p2 );
|
||||
assert( p6 == p3 );
|
||||
assert( p5 == p3 );
|
||||
assert( p2 == p3 );
|
||||
assert( p1 == p4 );
|
||||
assert( p2 != p4 );
|
||||
assert( p1 != p5 );
|
||||
assert( p2 != p1 );
|
||||
assert( p3 != p1 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p3 == p3 );
|
||||
assert( p4 == p4 );
|
||||
assert( p5 == p5 );
|
||||
assert( p6 == p6 );
|
||||
assert( p7 == p7 );
|
||||
assert( p8 == p8 );
|
||||
|
||||
merged = p5.Merge( p1 );
|
||||
// p7 <---> p6 <---> p8 <---> p3 <---> p5 <---> p2 and p4 <---> p1
|
||||
assert( !merged );
|
||||
assert( p6 == p8 );
|
||||
assert( p6 == p7 );
|
||||
assert( p1 != p7 );
|
||||
assert( p6 == p5 );
|
||||
assert( p6 == p2 );
|
||||
assert( p6 == p3 );
|
||||
assert( p5 == p3 );
|
||||
assert( p2 == p3 );
|
||||
assert( p1 == p4 );
|
||||
assert( p2 != p4 );
|
||||
assert( p1 != p5 );
|
||||
assert( p2 != p1 );
|
||||
assert( p3 != p1 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p3 == p3 );
|
||||
assert( p4 == p4 );
|
||||
assert( p5 == p5 );
|
||||
assert( p6 == p6 );
|
||||
assert( p7 == p7 );
|
||||
assert( p8 == p8 );
|
||||
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p9( pBaseClass );
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr pA( p9 );
|
||||
assert( p9 == pA );
|
||||
assert( p9 == p8 );
|
||||
assert( p1 != p8 );
|
||||
merged = p9.Merge( p1 );
|
||||
// p7 <---> p6 <---> p8 <---> p3 <---> p5 <---> p2
|
||||
// and p4 <---> p1 and p9 <---> pA
|
||||
assert( !merged );
|
||||
assert( p6 == p8 );
|
||||
assert( p6 == p7 );
|
||||
assert( p1 != p7 );
|
||||
assert( p6 == p5 );
|
||||
assert( p6 == p2 );
|
||||
assert( p6 == p3 );
|
||||
assert( p5 == p3 );
|
||||
assert( p2 == p3 );
|
||||
assert( p1 == p4 );
|
||||
assert( p2 != p4 );
|
||||
assert( p1 != p5 );
|
||||
assert( p2 != p1 );
|
||||
assert( p3 != p1 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p3 == p3 );
|
||||
assert( p4 == p4 );
|
||||
assert( p5 == p5 );
|
||||
assert( p6 == p6 );
|
||||
assert( p7 == p7 );
|
||||
assert( p8 == p8 );
|
||||
assert( p9 == p9 );
|
||||
assert( pA == pA );
|
||||
|
||||
merged = p9.Merge( p2 );
|
||||
// p7 <---> p6 <---> p8 <---> p3 <---> p5 <---> p2 <---> p9 <---> pA
|
||||
// and p4 <---> p1
|
||||
assert( merged );
|
||||
assert( p6 == p8 );
|
||||
assert( p6 == p7 );
|
||||
assert( p1 != p7 );
|
||||
assert( p6 == p5 );
|
||||
assert( p6 == p2 );
|
||||
assert( p6 == p3 );
|
||||
assert( p5 == p3 );
|
||||
assert( p2 == p3 );
|
||||
assert( p1 == p4 );
|
||||
assert( p2 != p4 );
|
||||
assert( p1 != p5 );
|
||||
assert( p2 != p1 );
|
||||
assert( p3 != p1 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p3 == p3 );
|
||||
assert( p4 == p4 );
|
||||
assert( p5 == p5 );
|
||||
assert( p6 == p6 );
|
||||
assert( p7 == p7 );
|
||||
assert( p8 == p8 );
|
||||
assert( p9 == p9 );
|
||||
assert( pA == pA );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoRefLinkTests( void )
|
||||
{
|
||||
|
||||
const unsigned int ctorCount = BaseClass::GetCtorCount();
|
||||
const unsigned int dtorCount = BaseClass::GetDtorCount();
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr w0;
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr w1;
|
||||
}
|
||||
assert( ctorCount == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr w3( new BaseClass );
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr w4( new BaseClass );
|
||||
assert( w3 != w4 );
|
||||
assert( w3 );
|
||||
assert( w4 );
|
||||
w3 = w4;
|
||||
assert( w3 == w4 );
|
||||
assert( w3 );
|
||||
assert( w4 );
|
||||
assert( dtorCount + 1 == BaseClass::GetDtorCount() );
|
||||
}
|
||||
assert( ctorCount + 2 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 2 == BaseClass::GetDtorCount() );
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoRefCountNullPointerTests( void )
|
||||
{
|
||||
BaseClass * pNull = NULL;
|
||||
const unsigned int ctorCount = BaseClass::GetCtorCount();
|
||||
const unsigned int dtorCount = BaseClass::GetDtorCount();
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p0;
|
||||
NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p1;
|
||||
NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p2( p0 );
|
||||
|
||||
assert( !p0 );
|
||||
assert( !p1 );
|
||||
assert( !p2 );
|
||||
assert( p1 == pNull );
|
||||
assert( p0 == pNull );
|
||||
assert( pNull == p0 );
|
||||
assert( pNull == p1 );
|
||||
assert( pNull == p2 );
|
||||
assert( p0 == p0 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p1 == p0 );
|
||||
assert( p0 == p1 );
|
||||
assert( p2 == p0 );
|
||||
assert( p0 == p2 );
|
||||
assert( p1 <= p0 );
|
||||
assert( p1 >= p0 );
|
||||
assert( p0 <= p1 );
|
||||
assert( p0 >= p1 );
|
||||
assert( p2 <= p0 );
|
||||
assert( p2 >= p0 );
|
||||
assert( p0 <= p2 );
|
||||
assert( p0 >= p2 );
|
||||
assert( !( p1 < p0 ) );
|
||||
assert( !( p1 > p0 ) );
|
||||
assert( !( p0 < p1 ) );
|
||||
assert( !( p0 > p1 ) );
|
||||
assert( !( p2 < p0 ) );
|
||||
assert( !( p2 > p0 ) );
|
||||
assert( !( p0 < p2 ) );
|
||||
assert( !( p0 > p2 ) );
|
||||
assert( !( p0 < pNull ) );
|
||||
assert( !( p0 > pNull ) );
|
||||
assert( !( pNull < p0 ) );
|
||||
assert( !( pNull > p0 ) );
|
||||
}
|
||||
assert( ctorCount == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount == BaseClass::GetDtorCount() );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoRefLinkNullPointerTests( void )
|
||||
{
|
||||
BaseClass * pNull = NULL;
|
||||
const unsigned int ctorCount = BaseClass::GetCtorCount();
|
||||
const unsigned int dtorCount = BaseClass::GetDtorCount();
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p0;
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p1;
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p2( p0 );
|
||||
|
||||
assert( !p0 );
|
||||
assert( !p1 );
|
||||
assert( !p2 );
|
||||
assert( p1 == pNull );
|
||||
assert( p0 == pNull );
|
||||
assert( pNull == p0 );
|
||||
assert( pNull == p1 );
|
||||
assert( pNull == p2 );
|
||||
assert( p0 == p0 );
|
||||
assert( p1 == p1 );
|
||||
assert( p2 == p2 );
|
||||
assert( p1 == p0 );
|
||||
assert( p0 == p1 );
|
||||
assert( p2 == p0 );
|
||||
assert( p0 == p2 );
|
||||
assert( p1 <= p0 );
|
||||
assert( p1 >= p0 );
|
||||
assert( p0 <= p1 );
|
||||
assert( p0 >= p1 );
|
||||
assert( p2 <= p0 );
|
||||
assert( p2 >= p0 );
|
||||
assert( p0 <= p2 );
|
||||
assert( p0 >= p2 );
|
||||
assert( !( p1 < p0 ) );
|
||||
assert( !( p1 > p0 ) );
|
||||
assert( !( p0 < p1 ) );
|
||||
assert( !( p0 > p1 ) );
|
||||
assert( !( p2 < p0 ) );
|
||||
assert( !( p2 > p0 ) );
|
||||
assert( !( p0 < p2 ) );
|
||||
assert( !( p0 > p2 ) );
|
||||
assert( !( p0 < pNull ) );
|
||||
assert( !( p0 > pNull ) );
|
||||
assert( !( pNull < p0 ) );
|
||||
assert( !( pNull > p0 ) );
|
||||
}
|
||||
assert( ctorCount == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount == BaseClass::GetDtorCount() );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -638,6 +905,11 @@ void DoRefLinkSwapTests( void )
|
|||
int main( unsigned int , const char * [] )
|
||||
{
|
||||
|
||||
DoRefLinkTests();
|
||||
|
||||
DoRefCountNullPointerTests();
|
||||
DoRefLinkNullPointerTests();
|
||||
|
||||
DoRefCountSwapTests();
|
||||
DoRefLinkSwapTests();
|
||||
DoConstConversionTests();
|
||||
|
@ -651,12 +923,17 @@ int main( unsigned int , const char * [] )
|
|||
// Check that no destructor called too often.
|
||||
assert( !BaseClass::ExtraDestructions() );
|
||||
|
||||
cout << "All SmartPtr tests passed!" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// $Log$
|
||||
// Revision 1.3 2006/03/17 22:52:56 rich_sposato
|
||||
// Fixed bugs 1452805 and 1451835. Added Merge ability for RefLink policy.
|
||||
// Added more tests for SmartPtr.
|
||||
//
|
||||
// Revision 1.2 2006/03/01 02:08:11 rich_sposato
|
||||
// Fixed bug 1440694 by adding check if rhs is previous neighbor.
|
||||
//
|
||||
|
|
Loading…
Add table
Reference in a new issue